2. PSI 与模型监控:模型监控体系全景、PSI 在模型监控中的位置、PSI 与 KS/IV 等其他指标的关系
2.1 模型监控体系全景
一个完整的模型监控体系,通常覆盖从数据输入到业务决策的全链路。PSI 只是其中一环,但却是最敏感的“哨兵”。下图展示了风控模型监控的四大核心模块及其关系:
核心认知:PSI 不是孤立指标。它处于“数据质量 → 特征分布 → 模型性能 → 业务决策”链条的第二环。当 PSI 告警时,往往意味着模型赖以生存的底层数据分布已经发生改变,后续的 KS、AUC 下降只是时间问题。
2.2 PSI 在模型监控中的位置
PSI(Population Stability Index,群体稳定性指标)是衡量模型评分或特征分布在时间维度上稳定性的核心指标。在监控体系中,PSI 承担着“早期预警”的角色:
- 前置性:PSI 漂移通常早于 KS/AUC 恶化 1-3 个监控周期,是模型失效的先行指标。
- 归因性:PSI 可以分解到每个特征,帮助定位是哪个变量发生了分布偏移。
- 可量化:PSI 提供统一的数值阈值(通常 0.1/0.25),便于自动化告警。
| 监控层级 | 典型指标 | PSI 关联性 | 告警优先级 |
|---|---|---|---|
| 数据质量 | 缺失率、异常值比例 | 数据质量问题会直接导致 PSI 升高 | 高 |
| 特征分布 | PSI | 核心指标 | 高 |
| 模型性能 | KS、AUC、Gini | PSI 持续升高后 KS 通常下降 | 中 |
| 业务决策 | 通过率、坏账率 | PSI 漂移最终影响业务结果 | 中 |
实践要点:在搭建监控看板时,建议将 PSI 放在最显眼的位置,并设置“黄灯(0.1 ≤ PSI < 0.25)”和“红灯(PSI ≥ 0.25)”两级告警。当 PSI 亮黄灯时,应启动特征归因分析;亮红灯时,需立即评估模型是否需要重训或下架。
2.3 PSI 与 KS、IV 等其他指标的关系
PSI、KS、IV 是风控建模中最常用的三个统计指标,它们既有联系又有区别。理解它们之间的关系,是进行有效监控的前提。
2.3.1 指标定义与计算逻辑对比
| 指标 | 全称 | 衡量对象 | 计算逻辑 | 典型阈值 |
|---|---|---|---|---|
| PSI | Population Stability Index | 同一变量/评分在时间上的分布差异 | ∑(实际占比 - 预期占比) × ln(实际占比 / 预期占比) | <0.1 稳定;0.1-0.25 需关注;>0.25 严重漂移 |
| KS | Kolmogorov-Smirnov | 模型区分好坏样本的能力 | max(累计好样本占比 - 累计坏样本占比) | >0.3 可接受;>0.4 优秀 |
| IV | Information Value | 特征对好坏样本的区分能力 | ∑(好占比 - 坏占比) × ln(好占比 / 坏占比) | <0.02 无预测力;0.02-0.1 弱;0.1-0.3 中等;>0.3 强 |
2.3.2 三者的逻辑关系
PSI、KS、IV 在风控生命周期中扮演不同角色,但存在内在联动:
2.3.3 实际应用中的组合分析
在监控实践中,不能孤立地看 PSI,需要结合 KS 和 IV 做综合判断:
组合分析矩阵:
| PSI 状态 | KS 状态 | IV 变化 | 诊断结论 | 建议动作 |
|---|---|---|---|---|
| 正常 | 正常 | 稳定 | 模型健康 | 常规监控 |
| 升高 | 正常 | 稳定 | 分布偏移早期,区分力未受损 | 启动特征归因,加强监控频率 |
| 升高 | 下降 | 下降 | 模型已失效 | 立即重训或版本回退 |
| 正常 | 下降 | 下降 | 标签偏移或样本选择偏差 | 检查 Y 定义和样本采集逻辑 |
| 升高 | 升高 | 升高 | 分布偏移但模型适应了新模式 | 需验证是否过拟合新分布 |
常见误区:不要因为 KS 还维持在较高水平就忽视 PSI 告警。PSI 是先行指标,当 KS 开始下降时,往往已经错过了最佳干预窗口。建议将 PSI 作为“第一道防线”,KS 作为“第二道防线”。
2.3.4 代码示例:PSI 与 KS 的联合计算
以下 Python 代码展示了如何同时计算 PSI 和 KS,并输出诊断建议:
import numpy as np
import pandas as pd
from scipy.stats import ks_2samp
def psi_ks_monitor(score_actual, score_expected, y_actual, y_expected=None, bins=10):
"""
联合计算 PSI 和 KS,输出诊断结果
Parameters:
-----------
score_actual : array, 当前评分
score_expected : array, 基准评分
y_actual : array, 当前样本标签 (0/1)
y_expected : array, 基准样本标签 (可选)
bins : int, 分箱数
Returns:
--------
dict : 包含 psi, ks, 诊断结论
"""
# 1. 计算 PSI
min_val = min(score_actual.min(), score_expected.min())
max_val = max(score_actual.max(), score_expected.max())
bin_edges = np.linspace(min_val, max_val, bins + 1)
actual_counts, _ = np.histogram(score_actual, bins=bin_edges)
expected_counts, _ = np.histogram(score_expected, bins=bin_edges)
actual_pct = actual_counts / len(score_actual)
expected_pct = expected_counts / len(score_expected)
# 避免除零
expected_pct = np.where(expected_pct == 0, 0.0001, expected_pct)
actual_pct = np.where(actual_pct == 0, 0.0001, actual_pct)
psi = np.sum((actual_pct - expected_pct) * np.log(actual_pct / expected_pct))
# 2. 计算 KS
if y_expected is not None:
# 使用基准样本的标签分布
ks_stat, p_value = ks_2samp(score_actual[y_actual == 1],
score_expected[y_expected == 1])
else:
# 仅使用当前样本
ks_stat, p_value = ks_2samp(score_actual[y_actual == 1],
score_actual[y_actual == 0])
# 3. 诊断逻辑
psi_flag = '正常' if psi < 0.1 else ('需关注' if psi < 0.25 else '严重漂移')
ks_flag = '正常' if ks_stat > 0.3 else ('需关注' if ks_stat > 0.2 else '失效')
if psi < 0.1 and ks_stat > 0.3:
diagnosis = '模型健康,常规监控'
elif psi >= 0.1 and ks_stat > 0.3:
diagnosis = '分布偏移早期,加强监控并启动特征归因'
elif psi >= 0.1 and ks_stat <= 0.3:
diagnosis = '模型已失效,建议立即重训'
else:
diagnosis = '需进一步分析标签和样本'
return {
'PSI': round(psi, 4),
'PSI_Flag': psi_flag,
'KS': round(ks_stat, 4),
'KS_Flag': ks_flag,
'Diagnosis': diagnosis
}
# 使用示例
# result = psi_ks_monitor(score_actual, score_expected, y_actual)
# print(result)
最佳实践:建议将 PSI、KS、IV 三个指标放在同一个监控看板上,并设置联动告警规则。例如:当 PSI > 0.15 且 KS 连续 2 个周期下降超过 5% 时,自动触发模型重训工单。