两种漂移,两种监控各自瞎一半。 只有输入漂移时,PSI 从 0.000 冲到 0.565(早该报警),AUC 却从 0.886 涨到 0.916。 只有概念漂移时,PSI 一直停在 0.005 以下(一声不响), AUC 从 0.901 掉到 0.504——模型彻底失效。 一个吵得没用,一个静得要命。
上一节保证上线前字段是对的。这一节管上线之后:模型不会坏在某一天,它是一点一点偏的。 而「偏」有两种,监控手段也正好两套——一套盯输入,一套盯效果。
一、两种漂移,长得完全不一样
输入漂移:客户群体变了,特征的分布跟着变,但「什么样的特征对应什么样的风险」这条关系没变。 典型例子是全行业收入普遍上涨——收入这一列的均值上移了,但「收入高的人更不容易违约」依然成立。 概念漂移:特征分布一点没变,但「特征与结果的关系」变了。 典型例子是政策调整、疫情、利率环境翻转——同样的收入、同样的负债比, 现在对应完全不同的违约概率。 这两者的监控手段天然不同: 输入漂移看 PSI(两期分布的距离),概念漂移只能看真实效果(AUC、KS)。 而真实效果需要标签——标签是要等的。 这就是这一节所有麻烦的根源。 Demo 造每月 3000 条、四个特征的数据,前 6 个月正常, 第 7 个月开始注入两种漂移之一:甲只平移特征,乙只翻转系数符号。
二、一张表吵、一张表静
场景甲:只有输入漂移(特征整体平移,关系不变)
| 月份 | PSI | 当月 AUC |
|---|---|---|
| 1 | 0.000 | 0.886 |
| 4 | 0.004 | 0.895 |
| 7 | 0.615 | 0.895 |
| 9 | 0.565 | 0.908 |
| 12 | 0.618 | 0.916 |
| PSI 从 0.000 冲到 0.615,按经验界(大于 0.25 报警)早该拉红灯了。 | ||
| 但 AUC 一路从 0.886 涨到 0.916——模型的排序能力一点没坏。 | ||
| 为什么会涨?因为特征整体平移之后,模型给分整体偏了一档,但「谁排在谁前面」没变。 | ||
| 而 AUC 只看排序,不看绝对位置,所以它不动。 | ||
| 这就是「输入漂移但关系没变」的典型长相:监控吵,模型没事。 | ||
| 如果只看 PSI,团队会白忙一场; | ||
| 如果只看 AUC,会漏掉「分数整体偏移」这个事实——而那个偏移会影响卡点通过率。 | ||
| 场景乙:只有概念漂移(分布不变,系数符号翻转) |
| 月份 | PSI | 当月 AUC |
|---|---|---|
| 1 | 0.003 | 0.901 |
| 4 | 0.005 | 0.897 |
| 7 | 0.003 | 0.494 |
| 9 | 0.005 | 0.512 |
| 12 | 0.002 | 0.504 |
| PSI 一直在 0.005 以下——按经验界属于「非常稳定」。 | ||
| 而 AUC 从 0.901 掉到 0.494,等于抛硬币。 | ||
| 这就是这一节最重要的一句话: | ||
| PSI 这种只看输入分布的监控,只能发现一半的问题。 | ||
| 另一半必须靠标签回填后算真实指标。 |
三、标签要等,这是最要命的地方
AUC 需要知道「这个人最后违没违约」。 而一笔贷款的违约,要在放款后三个月甚至更久才能确认。 所以你在第 10 个月看到的 AUC,其实只反映到第 7 个月的表现。 场景乙那种断崖,等你看清楚时,已经放出去三个月的坏账了。 这个延迟不是技术问题,是业务本身的物理限制。 所以工程上只能「用代理指标抢时间」—— ① 早期表现(首期逾期率)。 放款后 30 天就能拿到,和最终违约高度相关。 但它只反映最初一段,样本有选择偏差——早期没逾期的人后来也可能违约。 ② 分数分布本身的形状。 模型输出的均值、方差、高分人群占比——这三样漂了就是信号,而且完全不需要标签。 场景甲的分数整体平移,就是靠这一条抓到的。 ③ 人工抽检。 每月抽几百条已放款样本提前核实。成本高但最准,通常只在大额产品上用。
四、落地:两条腿走路
输入监控负责「快」——当天就能发现。 效果监控负责「准」——但它永远慢半拍。 缺了任何一条,你都会在某个方向上全瞎。 一个实用的做法是给两种漂移配不同的动作: 输入漂移报警 → 先去查「是不是客群变了」,如果关系没变,只需要重新校准分数(recalibration), 不用重训。 效果监控报警 → 必须重训或换模型,因为关系已经变了。 把这两类动作混在一起,团队就会在「客群变化」上反复重训,却对真正的概念漂移视而不见。 最后一句:模型监控不是「盯着一个数字」,是「知道每个数字在替你回答什么问题」。 PSI 回答「输入还像不像」,AUC 回答「判断还准不准」——两个问题都得有人答。
五、动手 Demo:漂移监控:输入漂移 PSI 冲到 0.565,AUC 反而涨了 0.02
造 12 个月、每月 3000 条、四个特征的模拟风控数据,第 1 月做 PSI 基准。 场景甲在第 7 月把特征整体平移 0.8(关系不变),场景乙在第 7 月把系数符号翻转(分布不变)。 逐月算 PSI 与当月 AUC,看两套监控各自抓到什么、漏掉什么。
def psi(base, cur, bins=10):
edges = np.quantile(base, np.linspace(0, 1, bins + 1))
edges[0], edges[-1] = -np.inf, np.inf
pb = np.histogram(base, edges)[0] / len(base)
pc = np.histogram(cur, edges)[0] / len(cur)
pb, pc = np.clip(pb, 1e-6, None), np.clip(pc, 1e-6, None)
return float(((pc - pb) * np.log(pc / pb)).sum())
# 场景甲:整体平移;场景乙:系数符号翻转
if scene == u"甲":
X[m:] = X[m:] + 0.8
else:
w = -w
实跑输出:
--------------------------------------------------------------------
漂移监控:输入漂移 PSI 冲到 0.565,AUC 反而涨了 0.02
--------------------------------------------------------------------
样本 每月 3000 条,四个特征
基准 第 1 月的特征分布(做 PSI)
变化起点 第 7 个月,两种场景各改一处
PSI 经验界 小于 0.1 稳定,0.1~0.25 关注,大于 0.25 报警
场景甲:只有**输入漂移**(特征整体平移 0.8,关系不变)
月份 PSI 当月 AUC
----------------------
1 0.000 0.886
4 0.004 0.895
7 0.615 0.895
9 0.565 0.908
12 0.618 0.916
场景乙:只有**概念漂移**(分布不变,系数符号翻转)
月份 PSI 当月 AUC
----------------------
1 0.003 0.901
4 0.005 0.897
7 0.003 0.494
9 0.005 0.512
12 0.002 0.504
**两张表拼起来才是这一节要说的:PSI 和 AUC 抓的根本不是同一件事。**
场景甲里,**PSI 从 0.000 冲到 0.565,按经验界早就该报警了;但 AUC 从 0.886 只走到 0.908。**
**模型排序能力几乎没坏——因为特征变了,但「特征与违约的关系」没变。**
场景乙正相反:**PSI 一直在 0.005 附近(因为分布真的没变),可 AUC 从 0.901 掉到 0.512。**
**模型彻底失效了,而输入监控一声没响。**
**所以 PSI 这种「只看输入分布」的监控,只能发现一半的问题。**
**另一半必须靠「标签回填后算真实指标」。**
但标签回填有延迟,这是它最麻烦的地方。
**假设一笔贷款的违约要在放款后 3 个月才能确认:**
**你在第 10 个月看到的 AUC,其实只反映到第 7 个月。**
**场景乙那种断崖,等你看清楚时已经放出去三个月的坏账。**
工程师的折中办法是**用代理指标抢时间**:
**① 早期表现(首期逾期率)。** 它在放款后 30 天就能拿到,和最终违约高度相关。
但只有这一段时间的样本,**有选择偏差。**
**② 分数分布本身的形状**——**模型输出的均值、方差、高分人群占比,漂移了就是信号,不需要标签。**
**③ 人工抽检。** 每月抽几百条已放款样本提前核实,**成本高但最准,通常只在大额产品上用。**
要说明:数据是我**按线性关系造的**,两种漂移也是我显式注入的。
**真实漂移往往是两者混合,而且发生得更慢、更难定起点。**
**但「PSI 抓输入、AUC 抓关系」这个分工,在任何风控体系里都成立。**
这两张表要一起看,单看任何一张都会得出错误结论。 只盯 PSI 的人,在第 7 个月会为场景甲拉警报, 然后在场景乙里睡过去——因为它的 PSI 一直是 0.003。 只盯 AUC 的人,会在场景甲里以为「一切正常」,却漏掉了分数整体偏移——通过率会莫名其妙地变化。 场景甲里 AUC 还涨了一点(0.886 到 0.916),这个「涨」很容易被当成好消息。 它不是好消息,它只是「平移不改变排序」的数学后果。 所以监控指标必须成对出现:一个管输入,一个管效果。 你没法用其中一个去替代另一个,因为它们量的根本不是一件事。 要说明:数据是我按线性关系造的,两种漂移也是显式注入的。 真实漂移往往是两者混合,而且发生得更慢、更难定起点。 但「PSI 抓输入、AUC 抓关系」这个分工,在任何风控体系里都成立。
30 秒实验
- 把场景甲的平移量从 0.8 加大到 2.0,看 AUC 会不会开始掉。 会——平移太大之后,特征被推出训练时的取值范围,模型的线性外推开始失真。 这时候「关系没变」的前提也破了。
- 把 PSI 的分箱从 10 改成 20 再跑。PSI 的绝对值会变(分箱越细越敏感), 所以 PSI 的阈值只能在固定分箱数下比较——跨版本比 PSI 是没有意义的。
- 把场景乙的系数翻转换成「只翻转一个特征的符号」再跑。 AUC 只掉一部分(比如从 0.90 掉到 0.75), 而不是掉到 0.50——部分概念漂移比完全漂移更难发现,也更常见。
常见误区
- 「PSI 报警就是模型坏了」。场景甲里 PSI 报得很凶,AUC 反而涨了。
- 「AUC 没掉就是没问题」。场景甲里分数整体平移,通过率会悄悄变化。
- 「有了效果监控就不需要 PSI」。效果监控要等标签,等你看清时坏账已经放出去三个月。
自测三问(点开对答案)
1. 为什么特征整体平移之后,AUC 可能不降反升? —— AUC 只看排序,平移不改变任何样本的相对顺序;小幅平移还可能让原本重叠的分数分得更开。 2. 概念漂移为什么 PSI 抓不到? —— PSI 只比较特征分布,而概念漂移的定义就是「分布不变、关系变了」; 分布既然没变,PSI 自然没有信号。 3. 为什么说「输入漂移报警 → 重新校准」和「效果报警 → 重训」是两种动作? —— 输入漂移时关系还在,只需把分数映射拉回原来的通过率区间; 关系变了则任何校准都无效,必须重新学习映射本身。模型不坏、指标不漂,还有第三个问题:「你能不能解释它为什么拒了这个人」。 这个问题不是技术洁癖,是监管要求。
- ☐ (本节完,下一节 12.1.3 可解释性突破)