AmirhosseinHonardoust/Underwriting-Decision-Safety-Lab

GitHub: AmirhosseinHonardoust/Underwriting-Decision-Safety-Lab

一个用于贷款审批的决策安全实验室,通过校准概率和优化阈值来制定可辩护的自动化决策策略。

Stars: 13 | Forks: 0

# 承保决策安全实验室 **校准 + 拒绝 + 决策安全的策略界面,用于贷款审批。** 将模型分数转换为**可辩护的行动**:*自动批准 / 自动拒绝 / 转交人工审核*。 Python Streamlit scikit-learn pandas License Status
## 为何存在此代码库 大多数机器学习项目止步于**“AUC 是这些”**。但承保业务不行。 在贷款领域,只有当预测能转化为带有以下特点的*决策策略*时,它才是有用的: - **校准的概率**(一个“0.90 批准”在类似条件下应意味着约 90% 的批准正确率) - **拒绝选项**(为不确定案例提供*审核*路径) - **覆盖率权衡**(在保证质量的前提下,可以安全地自动决策多少案例) - **决策安全的用户界面**(让用户看到置信度以及触发该结果的原因) 本实验室实现了一个完整的端到端工作流: 1. 训练一个基线贷款审批模型 2. 校准预测概率 3. 构建**覆盖率前沿**(阈值 ↔ 自动决策率 ↔ 质量) 4. 推荐一个**可辩护的阈值策略** 5. 提供一个用于**分诊**和**报告**的交互式 Streamlit 应用程序 ## 您将获得 ### 流程输出 - `outputs/metrics_overall.json` | 测试集上的模型指标(准确率、F1、ROC-AUC、ECE、Brier 分数等) - `outputs/abstention_policy.json` | 推荐的阈值 + 预期覆盖率 + 预期“自动”质量 - `outputs/test_predictions.csv` | 逐行的概率 + 标签(供分诊 UI 使用) - `outputs/coverage_curve.csv` | 阈值扫描结果(覆盖率 vs 性能) ### 图表 放置在 `reports/figures/` 目录中: - 混淆矩阵(基线阈值) - 覆盖率 vs 性能(拒绝权衡) - 概率直方图(分离度 + 置信度) - 可靠性图(校准) ### Streamlit 仪表板 包含以下标签页: - **报告卡** - **覆盖率曲线** - **分诊 UI** - **数据质量** - **备注** ## 数据集 本实验室使用 Kaggle 的 **贷款审批数据集** (`loanapproval.csv`)。 关键列(如“数据质量”标签页所示): - `applicant_id`(唯一标识符) - `age`(数值型) - `gender`(分类型) - `marital_status`(分类型) - `annual_income`(数值型) - `loan_amount`(数值型) - `credit_score`(数值型) - `num_dependents`(数值型) - `existing_loans_count`(数值型) - `employment_status`(分类型) - `loan_approved`(目标变量,0/1) ### 快速合理性检查(“数据质量”屏幕所示内容) - **行数:** 1000 - **列数:** 11 - **缺失值:** 在此数据集快照中,所有列均为 0 - **目标平衡:** 批准案例占多数(这是经过整理的演示数据集的典型情况) ## 项目结构 ``` underwriting-decision-safety-lab/ ├─ app/ │ └─ app.py # Streamlit dashboard ├─ data/ │ └─ raw/ │ └─ loanapproval.csv ├─ outputs/ # generated JSON/CSV artifacts ├─ reports/ │ └─ figures/ # generated PNG charts └─ src/ ├─ pipeline.py # main pipeline entrypoint ├─ clean.py # cleaning + schema normalization ├─ train.py # model training ├─ calibrate.py # sigmoid/isotonic calibration ├─ abstention.py # threshold sweep + policy recommendation ├─ metrics.py # ECE/Brier/etc └─ plots.py # figure generation ``` ## 如何运行 ### 1) 创建环境 ``` python -m venv .venv # Windows: .venv\Scripts\activate # macOS/Linux: source .venv/bin/activate pip install -r requirements.txt ``` ### 2) 运行流程(生成输出 + 图表) ``` python -m src.pipeline --input data/raw/loanapproval.csv ``` 您应该会看到类似这样的信息: * 完成! * 输出: `outputs/` * 图表: `reports/figures/` ### 3) 启动 Streamlit 应用 ``` streamlit run app/app.py ``` ## 仪表板导览(界面 + “如何解读”) 以下是您分享的仪表板界面。每个部分解释: * 该界面回答什么问题 * 如何解读结果 * 接下来您可以采取什么行动 # 1) 报告卡标签页 **目标:** 回答“模型是否*足够好*以考虑自动决策?以及安全的默认策略是什么?” ### 您将看到 * 顶级测试指标:**准确率、F1、ROC-AUC、ECE、Brier 分数** * 一个**推荐的拒绝策略**(阈值和预期覆盖率) * 一个 2×2 的图表网格: * 混淆矩阵 * 可靠性图 * 覆盖率 vs 性能 * 概率直方图 Screenshot 2026-02-20 at 13-25-28 Underwriting Decision Safety Lab ## 指标解释(附承保含义) ### 准确率 “整体上,我们预测正确的频率是多少?” **为何它不足:** 一个模型可能很准确,但其置信度可能危险地不准确。 ### F1 分数 平衡精确率和召回率(当存在类别不平衡时尤其有用)。 **承保解读:** 帮助您避免“批准一切”或“拒绝一切”的行为。 ### ROC-AUC 排序质量:“被批准的案例是否通常比被拒绝的案例得分更高?” **承保解读:** 高 AUC 有帮助,但它不能保证阈值决策的良好表现。 ### ECE(期望校准误差) 衡量置信度在不同概率区间内与实际情况的偏差程度。 * 如果模型对某个案例给出约 0.8 的批准概率,那么在类似条件下,大约 80 个这样的案例中应该有约 80 个被实际批准。 * 高 ECE 意味着在未校准的情况下,概率是不可信的。 ### Brier 分数 概率预测的均方误差。 * 越低越好。 * 对自信的错误预测惩罚很重。 # 2) 混淆矩阵图 confusion_matrix ### 它回答什么问题 “在基线阈值(通常是 0.5)下,我们正在犯哪类错误?” ### 如何解读 * 行 = 真实标签 * 列 = 预测标签 * 对角线 = 正确预测 * 非对角线 = 错误: * **错误批准**(预测批准但实际拒绝),风险/信用损失 * **错误拒绝**(预测拒绝但实际批准),机会成本/客户摩擦 ### 为何它只是起点 承保通常*不是*在单一的固定阈值下运行。 本代码库的目的在于从“0.5 分类器”转向**策略**: * 保守的自动批准 * 保守的自动拒绝 * 其他所有案例 → 转交审核 # 3) 可靠性图(校准) reliability_diagram ### 它回答什么问题 “我们能否信任预测概率作为真正的概率?” ### 如何解读 * X 轴:预测概率(分箱) * Y 轴:观察到的准确率 / 经验频率 * 对角线 = 完美校准 * 点在对角线上方:置信不足(现实 > 置信度) * 点在对角线下方:过度自信(置信度 > 现实) ### 为何校准在此至关重要 拒绝规则依赖于置信度阈值,例如: * 仅当置信度 ≥ 0.85 时才自动决策 如果概率未校准,“0.85”就没有意义。 ### 良好校准的表现 * 点在中高概率区域接近对角线 * 在您将要部署的决策阈值附近尤其重要 # 4) 概率直方图(分离度 + 置信度) probability_histograms ### 它回答什么问题 “模型能否将批准案例与拒绝案例区分开?不确定性集中在何处?” ### 如何解读 * 两个重叠的直方图: * 批准 (y=1) * 拒绝 (y=0) * 如果分布分离良好,模型可以自信地自动决策更多案例。 * 如果在中间区域大量重叠,您将需要更多的拒绝/审核。 ### 您可从中获得的承保洞察 * 在 **1.0** 附近对批准案例有大量聚集,表明存在强大的“安全批准”区域。 * 分散的拒绝分布表明拒绝案例更难识别或一致性较低。 * 重叠区域是您的审核队列候选区。 # 5) 覆盖率 vs 性能(拒绝权衡) coverage_vs_performance ### 它回答什么问题 “如果我们拒绝更多案例,能获得多少质量提升?” ### 定义 * **覆盖率:** 系统自动决策的案例比例 * **自动决策性能:** 仅在自动决策案例上衡量的准确率/F1 * 随着阈值增加: * 覆盖率通常会下降 * 自动决策质量通常会提高 ### 如何使用(实际工作流程) 1. 确定目标覆盖率(例如,70% 自动决策) 2. 选择实现该覆盖率的置信度阈值 3. 验证自动决策质量是否可接受 4. 审核队列大小变为 (1 - 覆盖率) ### 常见陷阱 如果在所有困难的案例上都选择拒绝,很容易获得高自动决策准确率。 因此,您必须始终**同时报告覆盖率和质量**。 # 6) 覆盖率曲线标签页 **目标:** 使覆盖率前沿交互化且易于检查。 Screenshot 2026-02-20 at 13-25-42 Underwriting Decision Safety Lab ### 您通常寻找什么 * 曲线中的“拐点”:一个小幅降低覆盖率就能带来质量大幅提升的区域 * 稳定性:避免微小变化导致大幅波动的阈值 * 一个可辩护的操作点: * “在阈值 0.85 下,我们自动决策约 70% 的案例,自动决策准确率约为 0.98” # 7) 分诊 UI 标签页(决策安全演示) **目标:** 展示*承保员或分析师将如何体验该模型*。 Screenshot 2026-02-20 at 13-25-58 Underwriting Decision Safety Lab ### 它的功能 * 您输入申请人特征(年龄、收入、贷款金额、信用评分等) * 应用输出: * `p(批准)` * 置信度度量(通常是最大概率或概率差值) * 决策:**自动决策** 或 **转交审核** * 类别概率条形图 ### 决策安全规则(核心概念) 该 UI 不会因为 p=0.71 就说“批准”,而是显示: * 当置信度 ≥ 阈值时**自动决策** * 否则**转交审核** 这使得系统可辩护: * 您可以解释您选择了什么置信度阈值 * 您可以估算工作量(审核量) * 您可以监控漂移(覆盖率随时间变化) ### 为何这优于原始预测 没有策略的原始概率会导致误用: * 不同团队解读不同 * 阈值被临时选定 * 您会丧失“为何做出此决策?”的可追溯性 # 8) 数据质量标签页(快速检查) **目标:** 在信任指标之前发现问题。 Screenshot 2026-02-20 at 13-26-15 Underwriting Decision Safety Lab ### 此标签页应包含的内容(及原因) 即使在干净的演示数据集中,现实世界的承保系统也可能因以下原因出错: #### 缺失值漂移 * 新渠道的收入数据缺失 * 合作伙伴集成的就业状态缺失 #### 合理性违规 * 信用评分超出预期范围 * 负的贷款金额 * 不可能的年龄 #### 类别漂移 * 新的 `employment_status` 值 * 婚姻状况编码发生变化 ### 为何这对决策安全很重要 像“置信度高于 0.85 则自动决策”这样的策略,假设您的特征分布与训练时相似。 数据质量检查是策略应用前的“信任关口”。 # 9) 备注标签页(解读 + 生产指导) Screenshot 2026-02-20 at 13-26-21 Underwriting Decision Safety Lab ### 重要信息 * **准确率 ≠ 可信** * **ECE 是校准误差** * **覆盖率是一个产品指标**(审核队列不是免费的) ### “生产级”在此处的含义 一个真正的系统应增加: * 公平性分片审计(按性别/年龄/就业状态划分的校准 + 错误率) * 监控:分数漂移、批准率漂移、覆盖率漂移 * 成本感知策略:错误批准 vs 错误拒绝 vs 审核成本 * 当校准退化时触发重新训练 ## 推荐的拒绝策略(含义) 应用显示了一个推荐策略(例如来自您的报告卡界面): * **阈值(置信度):** 0.85 * **预期覆盖率:** 0.70 * **自动决策准确率:** 0.977 * **自动决策 F1:** 0.986 解读: * 系统自动决策约 70% 的申请人。 * 剩余的约 30% 转交人工审核。 * 自动决策的案例置信度高,因此质量高。 * 这**不是“作弊”**,而是一个有意识的设计决策,将机器学习转化为安全的工作流。 ## 如何扩展此实验室 ### 1) 双边策略(批准 + 拒绝 + 审核) 目前,许多原型使用单一置信度阈值。承保通常受益于: * 若 p(批准) ≥ T_approve,则自动批准 * 若 p(批准) ≤ T_reject,则自动拒绝 * 否则转交审核 这可以在控制风险的同时减少审核工作量。 ### 2) 成本感知优化 将“最大化准确率”替换为: * 成本(错误批准) >> 成本(错误拒绝) * 成本(审核) 作为工作量项 然后选择最小化预期成本的阈值。 ### 3) 公平性感知报告 添加分片仪表板: * 按性别划分的 ECE * 按年龄组划分的错误率 * 按就业状态划分的批准率 * 按子群体划分的覆盖率 ### 4) 监控手册 每周跟踪: * 分数分布漂移 * 覆盖率漂移 * 批准率漂移 * 校准漂移(ECE 变化) ## 故障排除 ### “我的 Streamlit 警告提到 `use_container_width`” 较新的 Streamlit 版本倾向于: * 使用 `width="stretch"` 代替 `use_container_width=True` 如果您看到弃用警告,请相应地更新您的 `st.plotly_chart(...)` 和 `st.image(...)` 调用。 ### “图表看起来太小 / 布局奇怪” 请确保: * 设置了 `st.set_page_config(layout="wide")` * 使用一致的容器/列 * 对 Streamlit 中的图表/图像使用 `width="stretch"` ## 致谢 * 数据集: https://www.kaggle.com/datasets/amineipad/loan-approval-dataset * 工具: pandas, scikit-learn, Streamlit, matplotlib/plotly
标签:Apex, Kubernetes, pandas, Python, scikit-learn, Streamlit, 决策安全, 决策支持系统, 分诊UI, 弃权策略, 报告卡, 数据质量检查, 无后门, 机器学习, 概率校准, 模型评估, 自动化决策, 覆盖前沿, 访问控制, 贷款审批, 逆向工具, 金融建模, 金融风控, 阈值优化, 风险审核