4. PSI(群体稳定性指标)原理

群体稳定性指标(Population Stability Index, PSI)是风控模型监控中最核心的量化工具,用于衡量模型评分在时间维度或不同客群之间的分布偏移程度。PSI 值越大,说明模型打分的分布变化越剧烈,模型失效或客群漂移的风险越高。

4.1 PSI 的定义与业务含义

PSI 通过比较两个概率分布(或分数分布)的差异来量化稳定性:

  • 基准分布(Expected):模型开发时的训练集评分分布,或模型上线初期的稳定分布。
  • 实际分布(Actual):当前监控周期内的模型评分分布。

当两个分布高度一致时,PSI 趋近于 0;当分布发生显著偏移时,PSI 会快速增大。在风控场景中,PSI 常用于监控:

  • 模型评分卡分数的月度/周度漂移
  • 入模特征(如收入、负债率)的分布变化
  • 不同渠道或产品线之间的客群差异
核心认知: PSI 不是衡量模型预测能力的指标,而是衡量模型适用环境是否发生变化的指标。即使模型 AUC 保持不变,PSI 过高也意味着模型需要重新校准或迭代。

4.2 PSI 计算公式

PSI 的计算基于信息论中的 KL 散度(Kullback-Leibler divergence)对称化形式。其标准公式为:

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

其中:
- i = 第 i 个分箱(共 n 个箱)
- Actual_i  = 第 i 箱中实际样本占比
- Expected_i = 第 i 箱中基准样本占比
- ln = 自然对数

公式的直观含义:

  • (Actual_i - Expected_i):衡量两个分布在该箱上的占比差异,差异越大贡献越大。
  • ln(Actual_i / Expected_i):衡量该箱的偏移方向与幅度,对数变换使偏移量对称化。
  • 对所有箱的乘积求和,得到全局的分布偏移总量。
计算示例: 假设模型分数分为 3 个箱,基准占比分别为 [0.5, 0.3, 0.2],实际占比为 [0.4, 0.4, 0.2]。
箱1: (0.4-0.5)×ln(0.4/0.5) = (-0.1)×(-0.2231) = 0.0223
箱2: (0.4-0.3)×ln(0.4/0.3) = 0.1×0.2877 = 0.0288
箱3: (0.2-0.2)×ln(0.2/0.2) = 0×0 = 0
PSI = 0.0223 + 0.0288 + 0 = 0.0511

4.3 分箱方法

PSI 的计算依赖对连续分数进行离散化分箱。分箱方式直接影响 PSI 值的稳定性和可解释性。常用的分箱方法有三种:

分箱方法 操作方式 优点 缺点
等距分箱 将分数范围等分为固定宽度的区间(如每 50 分一箱) 实现简单,箱边界固定,便于跨周期对比 样本分布不均时可能出现空箱或极稀疏箱
等频分箱 按基准分布的百分位数切分,使每箱样本数大致相等 避免空箱,每箱统计量稳定 箱边界随基准分布变化,跨周期对比时边界不固定
自定义分箱 根据业务经验或模型分数阈值手动设定箱边界 贴合业务逻辑(如拒绝/通过阈值) 主观性强,需要业务专家参与
实践建议: 风控模型监控中推荐使用等频分箱(通常 10 箱),因为模型分数分布通常呈偏态,等距分箱容易导致两端箱样本过少,使 PSI 计算不稳定。等频分箱能保证每箱都有足够的统计支撑。

4.4 阈值设定

PSI 的阈值决定了何时触发模型监控预警。行业通用阈值标准如下:

PSI 范围 稳定性等级 建议行动
PSI < 0.1 稳定 无需干预,模型运行正常
0.1 ≤ PSI < 0.25 轻度漂移 发出预警,排查特征分布变化,准备模型评估
PSI ≥ 0.25 严重漂移 立即停用或降级模型,启动模型重训或校准流程

阈值设定需结合业务场景调整:

  • 信贷审批模型:通常采用 0.1/0.25 标准,因为审批决策对分数漂移敏感。
  • 反欺诈模型:可适当放宽至 0.15/0.3,因为欺诈模式变化快,过于严格的阈值会导致频繁误报。
  • 行为评分卡:建议采用 0.1/0.2,因为行为分数变化通常较缓慢,轻度漂移也需关注。

4.5 PSI 计算流程与架构

下图展示了 PSI 从数据输入到预警输出的完整计算流程:

PSI 计算与监控流程架构 模型评分数据输入 等频分箱(10箱) 计算每箱 Actual_i / Expected_i PSI = Σ(Actual-Expected)×ln(Actual/Expected) PSI ≥ 0.25 ? 严重漂移预警 输出 PSI 监控报告

4.6 PSI 与 KL 散度的关系

PSI 本质上是 KL 散度的对称化变体。理解这一关系有助于深入把握 PSI 的数学性质:

指标 公式 对称性 取值范围
KL 散度 D(P||Q) Σ P_i × ln(P_i / Q_i) 非对称 [0, +∞)
KL 散度 D(Q||P) Σ Q_i × ln(Q_i / P_i) 非对称 [0, +∞)
PSI Σ (P_i - Q_i) × ln(P_i / Q_i) 对称 [0, +∞)

PSI 的对称性使其在风控监控中更具实用性:无论将基准分布与实际分布互换,PSI 值保持不变,避免了因角色定义不同而产生的歧义。

数学性质: PSI 可以分解为两个 KL 散度的加权和:PSI = D(P||Q) + D(Q||P)。这种对称化处理使得 PSI 同时捕捉了“基准向实际偏移”和“实际向基准偏移”两个方向的信息,比单一 KL 散度更全面地反映分布差异。

4.7 PSI 计算代码示例

以下 Python 代码实现了 PSI 的完整计算流程,包含等频分箱与阈值判断:

import numpy as np
import pandas as pd

def calculate_psi(expected, actual, bins=10):
    """
    计算群体稳定性指标 (PSI)
    
    参数:
        expected: array-like, 基准分布分数
        actual: array-like, 实际分布分数
        bins: int, 分箱数量(默认10箱等频分箱)
    
    返回:
        psi: float, PSI值
        details: DataFrame, 每箱的详细计算过程
    """
    # 基于基准分布确定分箱边界(等频分箱)
    percentiles = np.linspace(0, 100, bins + 1)
    bin_edges = np.percentile(expected, percentiles)
    bin_edges[0] = -np.inf
    bin_edges[-1] = np.inf
    
    # 计算每箱样本占比
    expected_counts, _ = np.histogram(expected, bins=bin_edges)
    actual_counts, _ = np.histogram(actual, bins=bin_edges)
    
    expected_pct = expected_counts / len(expected)
    actual_pct = actual_counts / len(actual)
    
    # 处理空箱:将0替换为极小值避免除零
    expected_pct = np.where(expected_pct == 0, 1e-6, expected_pct)
    actual_pct = np.where(actual_pct == 0, 1e-6, actual_pct)
    
    # 计算每箱PSI贡献
    psi_components = (actual_pct - expected_pct) * np.log(actual_pct / expected_pct)
    psi = np.sum(psi_components)
    
    # 构建详细结果
    details = pd.DataFrame({
        '箱号': range(1, bins + 1),
        '下限': bin_edges[:-1],
        '上限': bin_edges[1:],
        '基准占比': expected_pct,
        '实际占比': actual_pct,
        'PSI贡献': psi_components
    })
    
    return psi, details

# 示例使用
np.random.seed(42)
expected_scores = np.random.normal(600, 100, 10000)
actual_scores = np.random.normal(620, 110, 10000)

psi_value, psi_details = calculate_psi(expected_scores, actual_scores)
print(f"PSI = {psi_value:.4f}")

if psi_value < 0.1:
    print("状态:稳定,无需干预")
elif psi_value < 0.25:
    print("状态:轻度漂移,建议排查")
else:
    print("状态:严重漂移,立即行动")
代码要点:
① 使用 np.percentile 基于基准分布计算等频分箱边界,保证每箱样本量均衡。
② 将 -np.inf 和 np.inf 作为首尾边界,确保所有分数都能落入箱内。
③ 空箱处理时使用 1e-6 替代 0,避免对数计算出现负无穷。

4.8 PSI 的局限性

PSI 虽然广泛应用,但在实际监控中需要注意以下局限:

  • 对分箱数量敏感:箱数越多,PSI 值通常越大,不同箱数下的 PSI 不可直接比较。
  • 无法定位漂移来源:PSI 只能告知分布发生了偏移,但不能指出是哪些特征或哪些分数段导致的偏移。
  • 忽略样本量差异:PSI 只关注占比变化,不反映样本量的增减,大样本下的微小偏移可能被放大。
  • 对极端值敏感:当某箱占比极小时,对数变换会放大该箱的贡献,导致 PSI 异常波动。
实践提醒: PSI 应作为监控预警的第一道防线,而非唯一依据。当 PSI 触发阈值时,需要结合特征级别的分布分析(如特征 PSI、特征重要性变化)和模型性能指标(如 AUC、KS)进行综合判断,才能准确诊断模型失效的根本原因。