资讯动态

信贷风控模型评估三件套:GINI、AUC与CAP曲线详解

发布时间:2026/10/15 12:54:57 来源:尧图企业网站定制
做信贷风控模型的朋友应该都有印象一份模型评估报告里GINI系数、累计准确率曲线Cumulative Accuracy Profile简称CAP和AUC这三个指标经常一起出现。新人第一次看到往往会问一句这不都是衡量模型好坏的吗为什么算完一个还要再算两个更常见的情况是大家知道Gini越大越好、AUC越接近1越好却说不清CAP曲线到底怎么读也不知道Gini2×AUC-1这个换算公式是哪儿冒出来的。这篇文章我不打算再给你贴一遍教科书定义而是把实际项目里用这三件套的完整逻辑讲清楚先看三个指标的来源和本质再拆解它们之间的数学换算然后落到CAP曲线在信贷场景里的落地解读最后分享我在计算和验证过程中反复踩过的坑。适合正在做评分卡、违约预测这类二分类模型的同学也适合刚入门、想彻底搞明白指标含义的读者。1. 三个指标的本质溯源从洛伦兹曲线到模型排序能力1.1 CAP曲线其实就是风控圈的洛伦兹曲线CAP曲线这个名词听起来很学院派但它的构造思路特别朴素。把一批样本按模型预测的违约概率从高到低排序然后横轴放“累积样本占比”纵轴放“累积坏样本占比”画出来的这条曲线就是CAP。举个具体的场景假设你有1000个客户模型给每个客户打了一个风险分。把这1000个客户按分数从低到高排分数越低风险越高按违约概率从高到低排前10%的客户理论上应该抓到越来越多的真实坏客户。如果模型完全随机前10%抓到的坏客户就是10%画出来是一条45度的对角线。如果模型完美前10%就把所有坏客户全抓完了画出来是一条先垂直上升再水平的折线。真实模型介于两者之间曲线越贴近“完美线”说明模型的排序能力越强。这和经济学里衡量收入分配公平程度的洛伦兹曲线长得一模一样。洛伦兹曲线把人口按收入从低到高排序横轴是累积人口占比纵轴是累积收入占比曲线越弯曲说明收入分配越不均衡。CAP曲线把客户按风险从高到低排序曲线越弯曲说明风险越集中在高分段。Gini系数原本就是衡量洛伦兹曲线弯曲程度的被引入风控领域后衡量的是模型把“好”和“坏”区分开的能力。1.2 Gini系数从收入分配领域借来的模型评价工具Gini系数在经济学里的定义是洛伦兹曲线与绝对平均线之间的面积除以绝对平均线以下的面积。搬到风控里绝对平均线就是“随机线”——模型没区分能力时坏客户均匀分布绝对不平均线就是“完美线”——所有坏客户集中在最高风险的那一小撮人里。所以模型Gini的计算公式可以写成Gini (模型曲线与随机线之间的面积) / (完美线与随机线之间的面积)这个比值越接近1说明模型越接近完美排序。一个完全随机的模型Gini是0一个完美模型Gini是1。实际业务中评分卡模型的Gini通常在0.3到0.6之间超过0.7的就要小心是不是发生了数据泄漏或者过拟合。1.3 AUC与ROC绕不开的另一个坐标系AUC来自ROC曲线坐标系和CAP不一样。ROC曲线的横轴是假正率FPR纵轴是真正率TPR也就是在“拿好客户当坏客户”的代价和“抓到坏客户”的收益之间找平衡。表面上看ROC和CAP画法完全不同一个用坏客户累计占比一个用好坏客户比率。但二者在数学上是强相关的因为都基于同一套排序结果。AUC的直观含义更简洁随机抽一个坏客户和一个好客户模型给出的风险分能把坏客户排在好客户前面的概率。这个“概率”的解释让AUC在实际工作中用得比CAP更广因为它不需要画图也能理解。2. Gini与AUC的数学转换为什么说它们是同一个东西2.1 核心换算公式的推导逻辑先说结论在双方都用连续分数、没有大量并列分组的情况下Gini 2×AUC - 1。这个公式在风控面试里几乎是必考题但大部分人只背了结论不知道它怎么来的。回到定义。AUC是“坏客户得分高于好客户”的概率。如果模型完全随机这个概率是0.5。如果模型完美这个概率是1。所以AUC-0.5度量的是模型相对于随机的提升幅度。再看Gini。CAP曲线里模型曲线与随机线之间的面积等于每个坏客户“被排在前面的好客户数量”相对随机情况的偏离。通过配对排序concordance的方式可以证明模型曲线与随机线之间的面积正好等于AUC-0.5。而完美线与随机线之间的面积正好等于0.5。两者相除Gini (AUC - 0.5) / 0.5 2×AUC - 1举个例子AUC0.8的模型Gini0.6AUC0.7Gini0.4。AUC和Gini只是同一个排序能力的不同刻度不存在“AUC好用还是Gini好用”的区别。只不过日常汇报时信贷圈习惯说Gini论文和通用机器学习圈习惯说AUC。2.2 对数几率模型里的对应关系在逻辑回归打分卡里这个换算关系还有一个更直观的验证方式。模型输出的分数本质上是违约对数几率log odds的线性变换。如果坏客户和好客户的分数分布都近似正态且方差接近那么AUC和两个分布均值之间的距离直接相关。具体说设好坏两个群体的分数均值差为d共同标准差为σ那么AUC Φ(d / (√2 × σ))其中Φ是标准正态分布的累积分布函数。这个公式的价值在于当你想在建模前预估一个特征组合能达到什么区分度时可以先看好坏样本的分数分布差异反过来推算AUC和Gini不用等到模型训练完。2.3 分组样本对换算公式的影响上面说的Gini 2×AUC - 1成立的前提是样本没有大量并列分数或者画CAP时用的是逐样本的原始分数。实际业务中大家经常把分数分箱比如按每5分一档进行分箱然后用分组数据画CAP曲线。这时候直接用面积法算出来的Gini和用逐样本配对算出来的AUC换算得到的Gini会有细微偏差。分箱越粗偏差越大。我在一个实际项目里试过用逐样本计算AUC0.783Gini0.566按10分一档分箱后再算面积Gini变成了0.554。差的这0.012看似不大但在模型监控里如果只看一位小数可能直接导致是否触发预警的判断都变了。所以规范做法是先明确口径要么全部用逐样本配对法要么全部用统一的分箱标准不要今天用这个口径明天用那个口径。3. CAP曲线在信贷模型中的落地解读3.1 AR值、随机线与完美线怎么读CAP曲线在落地时经常搭配一个数值指标叫ARAccuracy Ratio准确率。AR的定义和Gini几乎一样都是模型曲线与随机线之间的面积占完美线与随机线之间面积的比例。在很多报告里AR和Gini就是同一个数只是名字不同。实际读图时我一般会关注三个位置前10%样本的坏客户捕获率如果模型把风险分最高的10%客户捞出来能抓到多少比例的坏客户。这个值直接关系到催收资源分配和早期预警策略。50%处的累积捕获率反映模型在中间段的区分能力。很多评分卡模型头尾表现好中段曲线贴近随机线说明中段客户的风险排序能力弱。完美线与实际曲线的开口大小开口越大AR越高。举个例子某模型前10%样本捕获了42%的坏客户前50%捕获了82%整条曲线的AR0.58。对比另一个模型前10%只捕获28%前50%捕获75%AR0.44。单看AUC可能都过0.75但头部的捕获能力差异直接决定了应用于“高违约风险客户识别”场景时的效果差距。3.2 累计准确率曲线在策略中的应用CAP曲线不只是模型验收用的评估图它还是一个很好的策略制定工具。假设你要设计一条人工审核策略线上自动通过的额度是固定的超出额度的申请需要人工介入。你希望用模型把最高风险的那部分客户挑出来送人工审核这时CAP曲线能告诉你如果只审前10%的申请能覆盖多少坏客户如果扩大到前20%边际收益是增加多少。这种边际收益分析比单纯看一个AUC数值实用得多。数据同时支持单调性假设——好的模型在CAP头部斜率最大然后逐渐变缓如果曲线中段突然出现陡峭上升往往说明特征中存在某个分段异常需要排查。3.3 CAP曲线不要和收益曲线混为一谈这是我在实际项目里见过最多人踩的坑。CAP曲线衡量的只是“模型能不能把坏客户排到前面”它完全不回答“把前10%客户拒掉能省多少钱”。原因很简单被你的规则拒掉的客户里有一部分即使放进来也不会违约这部分就是误杀的成本而被你抓住的坏客户其违约损失还要扣除催收回款。CAP曲线看的是捕获率和收益曲线看的是“拒绝阈值下的期望损失”两者建模对象都不同。很多新人以为CAP越高策略收益越高忽略了误杀成本最后调出来的规则把好客户拒了一批坏账却降得有限。正确做法是用CAP曲线选出几个候选阈值再单独跑收益测算每个阈值下的坏账损失、收入损失、审批通过率、客户投诉率综合之后才能定策略。4. 实操中的指标计算与细节坑4.1 手算Gini与AUC的完整步骤理论讲再多不如实际算一遍。我平时在项目里先跑Python但为了校验结果也会用Excel手算一次小样本。手算Gini的步骤把所有样本按模型分从低到高排序违约概率高的排前面。计算累积好样本占比和累积坏样本占比。横轴放累积好样本占比或者累积总样本占比纵轴放累积坏样本占比画出CAP曲线。用梯形法计算曲线与随机线之间的面积再除以完美线与随机线的面积。如果直接用配对法算AUC更简单把所有坏客户和好客户两两配对统计“坏客户分数高于好客户”的配对比例这个比例就是AUC。然后Gini2×AUC-1。代码实现也不复杂import numpy as np from sklearn.metrics import roc_auc_score def gini_from_auc(y_true, y_score): auc roc_auc_score(y_true, y_score) gini 2 * auc - 1 return auc, gini def gini_from_cap(y_true, y_score): # 按分数降序排序 order np.argsort(-y_score) y_true_sorted y_true[order] # 累积坏样本占比 cum_bad np.cumsum(y_true_sorted) / np.sum(y_true_sorted) # 累积总样本占比 cum_pop np.arange(1, len(y_true_sorted) 1) / len(y_true_sorted) # 随机线面积近似0.5完美线面积近似 0.5 * (1 - bad_rate) # 更稳健的做法用梯形法算曲线下面积AUC_CAP auc_cap np.trapz(cum_bad, cum_pop) # AR (auc_cap - 0.5) / (0.5 * (1 - bad_rate) 0.5 * bad_rate * 0 - 0.5) # 简化AR (auc_cap - 0.5) / (0.5 - 0.5 * bad_rate 0.5 * bad_rate * 0) # 这里直接取常用简化形式 bad_rate np.mean(y_true) ar (auc_cap - 0.5) / (0.5 * (1 - bad_rate)) return auc_cap, ar需要注意的是np.trapz算出来的是曲线下面积减去随机线围成的区域分母用完美线的面积时如果坏样本占比不是50%完美线的高度不是1而是1/bad_rate对应的截断形状所以分母要带入实际坏样本占比。很多工具包内部实现已经处理了这一点但你自己手搓的时候很容易忽略算出来的AR偏大。4.2 小样本与低违约率场景的稳定性问题风控建模经常遇到违约率特别低的情况比如某个新产品线违约率只有1%坏样本只有几百个。这种数据下算出来的AUC和Gini置信区间会非常宽。用一个例子说明样本量5000坏样本200好样本4800。即使真实AUC是0.7595%置信区间也可能宽到0.70到0.80。如果两个候选模型AUC分别是0.74和0.76从统计上看差异可能完全不显著但报告里看起来就像第二个模型更好。我在项目里遇到这种情况会加做分层抽样和自助法bootstrap来估计指标波动范围而不仅仅看点估计。样本坏客户数AUC 95%置信区间宽度约50±0.09200±0.051000±0.025000±0.01这张表是经验值具体宽度取决于好坏分数分布的重叠程度但方向是一致的坏样本太少指标就像在流沙上盖楼看着稳实际一碰就晃。4.3 样本外验证OOT和跨期稳定性模型训练集上的Gini再高也不能代表未来表现。常规做法是留出时间外样本Out of TimeOOT用建模期之后的数据做验证。OOT的Gini通常比训练集低0.03到0.08如果低得太多说明模型存在时间衰减问题。另一个容易踩的坑是只报告整体Gini不报告分段Gini。同一个模型在不同客群上的Gini可能差很多。比如按地区分A地区的Gini0.62B地区只有0.41。整体Gini0.55看起来合格但B地区的排序能力已经明显劣化。把CAP曲线按客群拆开画能很快定位到模型失效的局部区域这个动作在模型监控里比单纯看整体趋势重要得多。5. 三个指标同时出现时该怎么协同使用5.1 模型监控报表里如何组合阅读日常监控报表里不要只看Gini一个数。我习惯组合看三个维度AUC/Gini的绝对值代表当前排序能力。与上一期、上上期的环比变化代表衰退速度。与OOT基准值的差异代表实际表现是否偏离验收时的预期。如果Gini连续三个月下滑但幅度都在0.01以内可能只是正常波动如果某一期突然掉0.05以上就要马上排查是客群结构变了还是某个特征的数据源断了还是评分区间分布发生了偏移。这时候光看Gini不够要切到分数分布图和PSI群体稳定性指数去定位。5.2 指标冲突时优先信谁实际项目里会遇到一种有意思的矛盾AUC/Gini很高但模型的概率校准很差。比如模型排名能力不错可预测出来的违约概率整体偏高导致审批通过率被压得很低。这种情况下Gini依然漂亮但业务根本没法用。Gini和AUC衡量的是排序不衡量概率准确性。如果你的场景只用排序比如挑选催收名单高Gini就够用如果你的场景需要设定审批阈值、计算预期损失就必须同时看校准曲线和Brier分数而不能只看Gini。这个区分是很多实际项目里最容易忽略的把“区分能力”当成了“预测准确度”。5.3 我踩过的几个坑和最后的习惯踩坑经验值得单独写几条。第一不要在同一份报告里混用不同软件包的口径不同库对Gini和AR的定义细节有差异换工具导致指标跳变的情况我碰过不止一次。第二不要对过采样后的样本直接算Gini。如果你用下采样或者SMOTE处理过不平衡样本直接算出来的AUC会偏高换算成Gini会给人虚假的信心正确做法是调整权重或者用原始分布还原后再算。第三不要指望Gini能告诉你阈值选在哪里它是排序指标阈值决策要靠收益分析和业务约束。现在我的习惯是每个模型验收时固定用三段式汇报——训练集Gini、OOT Gini、以及按客群拆分的CAP曲线对比图。先看绝对值再看相对变化最后看图找局部异常。这个方法帮我在不止一个项目里提前发现了客群偏移避免了模型上线三个月后表现崩掉的尴尬。如果你手头正好有模型报告建议把报告翻出来用Gini和AUC的换算关系快速校验一遍数字能不能对上。这一招能帮你发现不少从前没注意到的口径问题也算是这篇分享给你留下的一个小工具。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑