PSI 数学原理与公式推导

群体稳定性指标(Population Stability Index, PSI)是衡量两个分布之间差异程度的统计量,在评分卡监控中用于量化模型评分分布随时间或样本集的变化幅度。理解 PSI 的数学本质,是正确设定阈值、解读漂移信号的前提。

2.1 PSI 的数学定义

PSI 的计算基于将连续评分划分为 k 个等宽或等频区间(通常为 10–20 个分箱),然后比较每个区间内实际分布(当前评分)与期望分布(建模时评分)的占比差异。其标准公式为:

PSI = Σ (Actual_i - Expected_i) × ln(Actual_i / Expected_i)

其中:

  • Expected_i:建模样本(基准集)在第 i 个分箱中的样本占比;
  • Actual_i:当前监控样本(实际集)在第 i 个分箱中的样本占比;
  • ln(Actual_i / Expected_i):实际占比与期望占比的自然对数比;
  • 求和:对所有非空分箱的贡献值求和。
关键约定:当 Expected_i = 0 时,该分箱不参与计算;当 Actual_i = 0 时,该项贡献视为 0(因为 0 × ln(0) 在极限下趋近于 0)。实际工程中建议使用平滑处理(如加极小值 ε)避免除零。

2.2 基于信息论的解读:相对熵视角

PSI 在数学上等价于 Kullback-Leibler 散度(KL 散度) 的对称化形式。KL 散度衡量用一个分布 P 近似另一个分布 Q 时的信息损失:

KL(P || Q) = Σ P_i × ln(P_i / Q_i)

PSI 实际上是 KL(Actual || Expected) + KL(Expected || Actual) 的对称版本,即:

PSI = Σ (Actual_i - Expected_i) × ln(Actual_i / Expected_i)
    = Σ Actual_i × ln(Actual_i / Expected_i) + Σ Expected_i × ln(Expected_i / Actual_i)
    = KL(Actual || Expected) + KL(Expected || Actual)

这种对称性使得 PSI 对两个分布的角色不敏感——无论将哪个分布视为基准,计算结果一致。这与 KL 散度的非对称性形成对比,也是 PSI 在工业监控中更受欢迎的原因之一。

指标 对称性 取值范围 与 PSI 关系
KL 散度 非对称 [0, +∞) PSI = KL(Actual||Expected) + KL(Expected||Actual)
JS 散度 对称 [0, ln2] JS = 0.5 × KL(P||M) + 0.5 × KL(Q||M),M=(P+Q)/2
PSI 对称 [0, +∞) 直接用于评分卡漂移监控

2.3 分布差异的直观解释:对数比求和

PSI 的核心计算单元是 (Actual_i - Expected_i) × ln(Actual_i / Expected_i)。这个乘积可以拆解为两个因子的作用:

  • 差异方向因子 (Actual_i - Expected_i):表示当前分布相对于基准分布是“偏多”还是“偏少”。正号表示该分箱中实际样本占比上升,负号表示下降。
  • 差异幅度因子 ln(Actual_i / Expected_i):表示偏离的比例。当 Actual_i = Expected_i 时,该因子为 0;偏离越大,绝对值越大。

两个因子相乘后,每个分箱的贡献始终为非负值(因为当 Actual_i > Expected_i 时,两项均为正;当 Actual_i < Expected_i 时,两项均为负,乘积仍为正)。因此 PSI 是一个非负指标,值越大表示分布差异越大。

工程直觉:PSI < 0.1 表示分布稳定,0.1–0.25 表示轻度漂移需关注,> 0.25 表示显著漂移需立即排查。这些阈值来源于经验积累,与分箱数量(通常 10 箱)强相关。
PSI 计算流程与信息论映射 PSI 计算流程与信息论映射 基准分布 (Expected) 实际分布 (Actual) 分箱 (Binning) ln(Actual_i / Expected_i) Σ (A_i - E_i) × ln(A_i/E_i) PSI 指标 信息论映射 • KL(Actual || Expected) = Σ Actual_i × ln(Actual_i / Expected_i) • KL(Expected || Actual) = Σ Expected_i × ln(Expected_i / Actual_i) • PSI = KL(Actual || Expected) + KL(Expected || Actual) → 对称化相对熵

2.4 分箱策略对 PSI 的影响

PSI 对分箱方式敏感,不同分箱策略可能导致同一组数据计算出不同的 PSI 值。实践中需统一分箱规则,确保基准集与监控集使用相同的分箱边界。

分箱方式 方法描述 适用场景 注意事项
等宽分箱 按评分值等间距划分 评分范围固定、分布均匀时 极端值可能导致空箱
等频分箱 按样本量等比例划分 分布偏态、长尾数据 分箱边界随样本变化
自定义分箱 按业务含义(如信用等级阈值) 业务规则驱动、监管要求 需定期验证边界合理性
常见陷阱:监控集样本量远小于基准集时,等频分箱可能导致部分分箱样本数为 0,使 PSI 计算不稳定。建议监控集样本量不低于基准集的 10%,且每个分箱至少包含 30 个样本。
不同分箱策略下的 PSI 对比 不同分箱策略下的 PSI 对比示意 等宽分箱 分箱边界:[0,20),[20,40),... 基准占比:[0.10,0.15,0.20,...] 实际占比:[0.08,0.12,0.22,...] PSI = 0.08 等频分箱 分箱边界:[0,35),[35,55),... 基准占比:[0.10,0.10,0.10,...] 实际占比:[0.09,0.11,0.10,...] PSI = 0.04 自定义分箱 分箱边界:按信用等级 基准占比:[0.05,0.20,0.50,...] 实际占比:[0.07,0.18,0.48,...] PSI = 0.12 分箱策略选择建议 • 同一模型、同一监控周期内,必须使用与基准集完全相同的分箱边界。 • 等频分箱对分布偏移更敏感,适合早期预警;等宽分箱更稳定,适合长期监控。 • 自定义分箱需结合业务含义,避免分箱边界与评分阈值脱节。

2.5 公式推导的完整步骤

为便于编程实现,下面给出 PSI 计算的完整推导步骤,附带 Python 伪代码:

  1. 确定分箱边界:基于基准集评分,使用等宽或等频策略生成 k 个分箱的边界数组 bins。
  2. 计算基准占比:统计基准集在每个分箱的样本数 count_exp,除以总样本数得到 Expected_i。
  3. 计算实际占比:使用相同 bins 对监控集评分分箱,统计 count_act,得到 Actual_i。
  4. 逐箱计算贡献:对每个分箱 i,计算 (Actual_i - Expected_i) * log(Actual_i / Expected_i)。
  5. 求和:将所有分箱的贡献值相加,得到 PSI。
import numpy as np

def calculate_psi(expected_scores, actual_scores, bins=10):
    # 1. 基于基准集确定分箱边界(等频)
    percentiles = np.linspace(0, 100, bins + 1)
    bin_edges = np.percentile(expected_scores, percentiles)
    bin_edges[0] = -np.inf
    bin_edges[-1] = np.inf
    
    # 2. 基准占比
    exp_counts, _ = np.histogram(expected_scores, bins=bin_edges)
    exp_ratio = exp_counts / len(expected_scores)
    
    # 3. 实际占比
    act_counts, _ = np.histogram(actual_scores, bins=bin_edges)
    act_ratio = act_counts / len(actual_scores)
    
    # 4. 逐箱计算(平滑处理避免除零)
    psi = 0.0
    for i in range(bins):
        e = exp_ratio[i] + 1e-10  # 平滑
        a = act_ratio[i] + 1e-10
        psi += (a - e) * np.log(a / e)
    
    return psi
实现要点:
• 使用 np.percentile 生成等频分箱边界,确保基准集每个分箱样本数大致相等。
• 平滑值 1e-10 远小于实际占比(通常 > 0.01),不会显著影响结果,但能避免 log(0) 错误。
• 监控集样本量过小时(如 < 1000),建议增加分箱数量或使用 Bootstrap 重采样稳定 PSI 估计。