3、PSI计算公式详解:数学推导、分箱方法与计算步骤

群体稳定性指标(Population Stability Index,PSI)是衡量模型评分分布随时间或样本变化是否发生偏移的核心量化工具。在催收触达场景中,PSI 用于监控模型对同一客群在不同时间窗口(如月度、季度)的评分分布是否保持稳定。本节从数学公式、分箱策略到计算步骤进行完整拆解。

3.1 PSI 数学公式推导

PSI 基于信息论中的 相对熵(KL 散度) 思想,衡量两个概率分布之间的差异。其标准计算公式为:

PSI = Σ (Aᵢ - Eᵢ) × ln(Aᵢ / Eᵢ)

其中:

  • Aᵢ:实际分布(Actual)在第 i 个分箱中的样本占比(如当前月份催收触达评分分布)。
  • Eᵢ:期望分布(Expected)在第 i 个分箱中的样本占比(如模型开发时的基准分布或上个月分布)。
  • ln(Aᵢ / Eᵢ):自然对数比率,衡量该分箱的偏移程度。
  • Σ:对所有分箱求和,得到整体偏移量。
数学本质: PSI 可视为对称化后的 KL 散度。当 Aᵢ 与 Eᵢ 完全一致时,每个分箱的贡献为 0,PSI = 0;差异越大,PSI 值越高。

在实际计算中,为避免 ln(0) 或除以 0 的情况,通常对占比进行微小平滑处理(如加 0.0001)或合并空箱。

3.2 分箱方法详解

分箱是 PSI 计算的前置步骤,直接影响稳定性评估的敏感度与鲁棒性。常用的三种分箱方法对比如下:

分箱方法 原理 优点 缺点 催收场景适用性
等距分箱 将评分范围等分为 k 个宽度相同的区间 实现简单,区间边界固定,便于跨期对比 样本分布不均时,部分箱可能样本过少或为空 适用于评分范围已知且分布较均匀的成熟模型
等频分箱 使每个分箱包含大致相同数量的样本 避免空箱,每个箱统计意义稳定 区间边界随分布变化而移动,跨期对比不直观 适用于样本量波动大、需保证每箱统计稳健的场景
分位数分箱 基于指定分位数(如十分位、二十分位)切分 边界具有统计意义,对极端值不敏感 分位数选择需经验,边界可能不整齐 推荐用于催收评分卡监控,兼顾稳定性和可解释性
行业实践建议: 催收触达 PSI 监控通常采用 等频分箱(10 箱) 或 分位数分箱(十分位)。等距分箱在评分范围两端容易出现空箱,导致 PSI 计算不稳定,不推荐单独使用。

3.3 计算步骤拆解

以下以 等频分箱(10 箱) 为例,完整拆解 PSI 计算流程:

  1. 确定基准分布(期望分布 E):取模型开发样本或上个月催收触达评分,计算每个样本的评分值。
  2. 确定分箱边界:基于基准分布,按等频原则确定 10 个分箱的边界(即十分位点)。
  3. 统计实际分布(A):将当前月份催收触达评分按上述边界分箱,统计每个箱中的样本数,计算占比 Aᵢ。
  4. 计算每个分箱的贡献值:对每个箱 i,计算 (Aᵢ - Eᵢ) × ln(Aᵢ / Eᵢ)。
  5. 求和得到 PSI:将所有分箱的贡献值相加,得到最终 PSI 值。
  6. 结果解读:根据行业阈值判断稳定性等级(详见后续章节)。
常见陷阱: 若实际分布中某个分箱样本数为 0(Aᵢ = 0),则 ln(0) 无定义。此时应将该箱与相邻箱合并,或对占比做极小值平滑(如 Aᵢ = max(Aᵢ, 0.0001)),避免计算异常。

3.4 PSI 计算流程 SVG 图

下图展示了从基准分布到 PSI 输出的完整计算链路:

PSI 计算流程 PSI 计算流程(等频分箱示例) 基准分布 E 等频分箱边界 实际分布 A 分箱统计占比 计算每箱贡献值 PSI = Σ (Aᵢ - Eᵢ) × ln(Aᵢ / Eᵢ) 稳定性判定 分箱数通常取 10,兼顾粒度与稳定性

3.5 计算示例表

以下为一个简化的 5 箱 PSI 计算示例(实际监控中通常使用 10 箱):

分箱编号 评分区间 期望占比 Eᵢ 实际占比 Aᵢ Aᵢ - Eᵢ ln(Aᵢ / Eᵢ) 单箱贡献
1 [0, 200) 0.20 0.25 0.05 0.2231 0.0112
2 [200, 400) 0.20 0.22 0.02 0.0953 0.0019
3 [400, 600) 0.20 0.18 -0.02 -0.1054 0.0021
4 [600, 800) 0.20 0.17 -0.03 -0.1625 0.0049
5 [800, 1000] 0.20 0.18 -0.02 -0.1054 0.0021
PSI 合计 0.0222
示例解读: 该 PSI = 0.0222,远低于 0.1 的常见预警阈值,表明当前实际分布与基准分布高度一致,模型稳定性良好。若 PSI 超过 0.25,则需启动模型复核与催收策略调整。

3.6 分箱策略对比 SVG 图

下图直观对比三种分箱方法在相同评分分布下的切分效果:

三种分箱方法对比 三种分箱方法切分效果对比(评分范围 0-1000) 等距分箱 0-250 250-500 500-750 750-1000 等频分箱 0-180 180-420 420-650 650-1000 分位数分箱 10 个等样本量区间(十分位) 等距:区间等宽;等频:样本等量

3.7 计算代码示例(Python)

以下为 PSI 计算的 Python 实现,采用等频分箱策略:

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 值
        bin_edges: array, 分箱边界
    """
    # 基于基准分布确定等频分箱边界
    percentiles = np.linspace(0, 100, bins + 1)
    bin_edges = np.percentile(expected, percentiles)
    
    # 处理边界重复(极端情况)
    bin_edges = np.unique(bin_edges)
    
    # 统计期望分布占比
    expected_counts, _ = np.histogram(expected, bins=bin_edges)
    expected_pct = expected_counts / len(expected)
    
    # 统计实际分布占比
    actual_counts, _ = np.histogram(actual, bins=bin_edges)
    actual_pct = actual_counts / len(actual)
    
    # 平滑处理,避免 ln(0)
    epsilon = 1e-6
    expected_pct = np.clip(expected_pct, epsilon, 1 - epsilon)
    actual_pct = np.clip(actual_pct, epsilon, 1 - epsilon)
    
    # 计算 PSI
    psi = np.sum((actual_pct - expected_pct) * np.log(actual_pct / expected_pct))
    
    return psi, bin_edges

# 示例用法
expected_scores = np.random.normal(500, 150, 10000)
actual_scores = np.random.normal(520, 160, 10000)
psi_value, edges = calculate_psi(expected_scores, actual_scores)
print(f"PSI = {psi_value:.4f}")
代码要点:
  • 使用 np.percentile 基于基准分布计算等频分箱边界,确保每箱样本量大致相等。
  • np.clip 对占比进行平滑,避免因空箱导致 ln(0) 错误。
  • 返回的 bin_edges 可用于后续监控批次的分箱对齐,保证边界一致。

3.8 关键注意事项

  • 分箱数选择: 通常取 10 箱(十分位),样本量较大时可取 20 箱提高敏感度;样本量小于 1000 时建议减少至 5 箱。
  • 边界对齐: 所有监控批次必须使用与基准分布相同的分箱边界,否则 PSI 不可比。
  • 空箱处理: 优先合并相邻箱,其次使用极小值平滑,避免直接丢弃。
  • PSI 阈值: 行业通用标准:PSI < 0.1 表示稳定;0.1 ≤ PSI < 0.25 需关注;PSI ≥ 0.25 表示显著偏移,需立即干预。