PSI 数学原理与计算公式
群体稳定性指标(Population Stability Index, PSI)是风控规则引擎中衡量模型或评分分布随时间变化的核心量化工具。本章从数学推导、分箱方法到实际计算步骤,完整拆解 PSI 的计算逻辑。
2.1 PSI 的数学推导
PSI 基于信息论中的 KL 散度(Kullback-Leibler divergence) 对称化改造而来。KL 散度衡量两个概率分布 P 和 Q 之间的非对称差异:
KL(P || Q) = Σ p_i * ln(p_i / q_i)
由于 KL 散度不满足对称性(KL(P||Q) ≠ KL(Q||P)),PSI 采用对称化形式:
PSI = Σ (p_i - q_i) * ln(p_i / q_i)
其中:
- p_i:当前评分分布在第 i 个分箱中的样本占比
- q_i:基准评分分布在第 i 个分箱中的样本占比
- ln(p_i / q_i):自然对数下的分布差异权重
当 p_i 与 q_i 完全一致时,PSI = 0;差异越大,PSI 值越高。
工程要点:实际计算中,当 q_i = 0 时 ln(p_i / q_i) 无定义。建议对空箱做平滑处理(如加极小值 1e-6),或强制将空箱与相邻箱合并。
2.2 分箱方法
分箱是 PSI 计算的前置步骤,直接影响指标敏感度。常用分箱方法对比如下:
| 分箱方法 | 原理 | 适用场景 | 注意事项 |
|---|---|---|---|
| 等距分箱 | 按评分区间等宽划分(如每 50 分一箱) | 评分分布均匀、业务含义明确 | 极端值可能导致空箱 |
| 等频分箱 | 按样本量等比例划分(每箱约 10% 样本) | 分布偏态严重、长尾数据 | 基准与当前分箱边界需保持一致 |
| 业务分箱 | 按风控策略阈值划分(如 0-300、300-600、600-900) | 规则引擎直接使用评分卡分段 | 需定期验证业务分段合理性 |
| 聚类分箱 | 基于 K-Means 或决策树自动寻找最优切点 | 数据驱动、无先验分段 | 计算成本高,可解释性弱 |
常见陷阱:分箱数量过少(如 <5)会掩盖局部漂移;分箱过多(如 >20)会导致噪声放大。推荐风控场景使用 10-15 箱,兼顾敏感度与稳定性。
2.3 实际计算步骤与示例
以下通过一个完整示例演示 PSI 的手工计算过程。假设某风控评分卡输出 0-1000 分,基准分布与当前分布如下:
步骤 1:确定分箱边界(等距分箱,每 200 分一箱)
| 分箱 | 区间 | 基准样本数 | 当前样本数 |
|---|---|---|---|
| 1 | [0, 200) | 500 | 400 |
| 2 | [200, 400) | 1200 | 1000 |
| 3 | [400, 600) | 1800 | 2000 |
| 4 | [600, 800) | 1000 | 1200 |
| 5 | [800, 1000] | 500 | 400 |
| 合计 | 5000 | 5000 |
步骤 2:计算各箱占比
q1 = 500/5000 = 0.1000 p1 = 400/5000 = 0.0800
q2 = 1200/5000 = 0.2400 p2 = 1000/5000 = 0.2000
q3 = 1800/5000 = 0.3600 p3 = 2000/5000 = 0.4000
q4 = 1000/5000 = 0.2000 p4 = 1200/5000 = 0.2400
q5 = 500/5000 = 0.1000 p5 = 400/5000 = 0.0800
步骤 3:逐箱计算 PSI 分量
箱1: (0.0800 - 0.1000) * ln(0.0800/0.1000) = (-0.0200) * (-0.2231) = 0.00446
箱2: (0.2000 - 0.2400) * ln(0.2000/0.2400) = (-0.0400) * (-0.1823) = 0.00729
箱3: (0.4000 - 0.3600) * ln(0.4000/0.3600) = (0.0400) * (0.1054) = 0.00422
箱4: (0.2400 - 0.2000) * ln(0.2400/0.2000) = (0.0400) * (0.1823) = 0.00729
箱5: (0.0800 - 0.1000) * ln(0.0800/0.1000) = (-0.0200) * (-0.2231) = 0.00446
步骤 4:求和得到 PSI
PSI = 0.00446 + 0.00729 + 0.00422 + 0.00729 + 0.00446 = 0.02772
最终 PSI ≈ 0.028。根据行业经验阈值:
- PSI < 0.10:分布稳定,无需告警
- 0.10 ≤ PSI < 0.25:轻度漂移,需关注
- PSI ≥ 0.25:显著漂移,触发告警
本例 PSI = 0.028,属于稳定范围。
自动化计算提示:生产环境中建议使用 Python 的
scipy.stats.entropy 或自定义向量化函数,避免逐箱循环。以下为参考实现:
import numpy as np
def calculate_psi(expected, actual, bins=10):
# 等频分箱
percentiles = np.percentile(expected, np.linspace(0, 100, bins + 1))
expected_bins = np.histogram(expected, bins=percentiles)[0]
actual_bins = np.histogram(actual, bins=percentiles)[0]
# 占比 + 平滑
q = expected_bins / expected_bins.sum() + 1e-6
p = actual_bins / actual_bins.sum() + 1e-6
# PSI 计算
psi = np.sum((p - q) * np.log(p / q))
return psi
2.4 PSI 计算流程可视化
下图完整展示了从原始评分到 PSI 输出的计算链路:
2.5 PSI 与 KL 散度的关系
下表总结了 PSI 与 KL 散度的核心差异,帮助理解 PSI 的设计优势:
| 指标 | 公式 | 对称性 | 取值范围 | 风控适用性 |
|---|---|---|---|---|
| KL 散度 | Σ p_i * ln(p_i / q_i) | 非对称 | [0, +∞) | 不直接使用,方向敏感 |
| PSI | Σ (p_i - q_i) * ln(p_i / q_i) | 对称 | [0, +∞) | 直接衡量分布偏移幅度 |
| JS 散度 | 0.5 * KL(P||M) + 0.5 * KL(Q||M) | 对称且有界 | [0, ln2] | 有界性便于阈值设定 |
工程建议:PSI 的对称性使其在监控场景中优于 KL 散度——无论基准分布在前还是当前分布在前,计算结果一致。JS 散度虽有界,但风控行业已广泛接受 PSI 的阈值体系,迁移成本较高。
2.6 分箱边界对齐的工程陷阱
实际生产中,基准分布与当前分布的分箱边界必须严格一致。下图展示了边界不对齐导致的 PSI 失真:
生产事故案例:某支付平台因模型升级后未同步分箱边界,导致 PSI 从 0.03 跳变至 0.35,触发误告警。排查发现基准分布使用等距 10 箱,当前分布使用等频 10 箱,边界完全不同。修复后 PSI 回落至 0.04。