4、PSI计算步骤详解:数据分箱、计算占比、计算WOE与差异、累加得到PSI值
PSI(Population Stability Index,群体稳定性指标)的计算过程严格遵循四个核心步骤:数据分箱 → 计算占比 → 计算WOE与差异 → 累加得到PSI值。每一步都直接影响最终监控结果的准确性,尤其在催收触达场景中,分箱方式的选择对模型敏感度至关重要。
核心原则:PSI衡量的是“实际分布”相对于“预期分布”的偏移程度。在催收触达中,通常将模型开发时的样本分布作为预期(Expected),将当前监控周期的触达结果分布作为实际(Actual)。
4.1 步骤一:数据分箱(Binning)
分箱是将连续变量或离散变量划分为若干个区间(箱)的过程。分箱质量直接决定PSI能否有效捕捉分布偏移。催收触达场景中,常用的分箱方式有三种:
| 分箱方式 | 方法描述 | 催收触达适用场景 | 注意事项 |
|---|---|---|---|
| 等距分箱 | 按变量值域等间隔划分 | 评分卡分数、逾期天数 | 容易导致某些箱样本过少 |
| 等频分箱 | 按样本数量均分,每箱样本量相近 | 催收评分、客户分层 | 边界值可能割裂同质群体 |
| 最优分箱 | 基于决策树或卡方检验自动划分 | 高风险客群识别 | 计算复杂,需保证业务可解释性 |
实战建议:催收触达PSI监控推荐使用等频分箱,通常分为10箱。若某箱样本占比低于5%,需合并相邻箱,避免统计波动导致PSI虚高。
分箱完成后,需确保预期样本(Expected)和实际样本(Actual)使用完全相同的分箱边界。例如,若预期数据将评分区间[300, 800]分为10个等频箱,实际数据必须沿用这9个边界点,不能重新分箱。
4.2 步骤二:计算各箱占比(Proportion)
分箱完成后,分别计算每个箱在预期样本和实际样本中的占比。公式如下:
预期占比(%i_Expected)= 第i箱预期样本数 / 预期总样本数 × 100%
实际占比(%i_Actual)= 第i箱实际样本数 / 实际总样本数 × 100%
假设我们将催收评分分为5箱,某次监控的计算示例如下:
| 箱编号 | 评分区间 | 预期样本数 | 预期占比(%) | 实际样本数 | 实际占比(%) |
|---|---|---|---|---|---|
| 1 | [300, 400) | 2,000 | 20.0 | 1,500 | 15.0 |
| 2 | [400, 500) | 2,000 | 20.0 | 2,200 | 22.0 |
| 3 | [500, 600) | 2,000 | 20.0 | 2,500 | 25.0 |
| 4 | [600, 700) | 2,000 | 20.0 | 1,800 | 18.0 |
| 5 | [700, 800] | 2,000 | 20.0 | 2,000 | 20.0 |
| 合计 | — | 10,000 | 100.0 | 10,000 | 100.0 |
避坑提示:若某箱实际占比为0%,会导致后续WOE计算出现无穷大。此时需将该箱与相邻箱合并,或对占比做平滑处理(如加0.5%的极小值)。
4.3 步骤三:计算WOE与差异(WOE & Difference)
WOE(Weight of Evidence,证据权重)用于衡量每个箱中实际占比相对于预期占比的偏移方向与幅度。计算公式为:
WOE_i = ln(实际占比_i / 预期占比_i)
差异项 = (实际占比_i - 预期占比_i) × WOE_i
WOE的正负含义:
- WOE > 0:实际占比高于预期,该箱客群占比上升
- WOE < 0:实际占比低于预期,该箱客群占比下降
- WOE = 0:占比无变化,分布完全稳定
以上述数据为例,计算各箱WOE与差异项:
| 箱编号 | 预期占比(%) | 实际占比(%) | WOE | 差异项 |
|---|---|---|---|---|
| 1 | 20.0 | 15.0 | ln(15/20) = -0.2877 | (15%-20%) × (-0.2877) = 0.0144 |
| 2 | 20.0 | 22.0 | ln(22/20) = 0.0953 | (22%-20%) × 0.0953 = 0.0019 |
| 3 | 20.0 | 25.0 | ln(25/20) = 0.2231 | (25%-20%) × 0.2231 = 0.0112 |
| 4 | 20.0 | 18.0 | ln(18/20) = -0.1054 | (18%-20%) × (-0.1054) = 0.0021 |
| 5 | 20.0 | 20.0 | ln(20/20) = 0.0000 | (20%-20%) × 0.0000 = 0.0000 |
4.4 步骤四:累加得到PSI值
将各箱的差异项求和,即得到最终的PSI值:
PSI = Σ[(实际占比_i - 预期占比_i) × ln(实际占比_i / 预期占比_i)]
根据上表数据:
PSI = 0.0144 + 0.0019 + 0.0112 + 0.0021 + 0.0000 = 0.0296
计算得到PSI = 0.0296(即2.96%)。根据行业通用判断标准:
| PSI值范围 | 稳定性判断 | 催收触达应对建议 |
|---|---|---|
| PSI < 0.10 | 稳定,无显著偏移 | 正常监控,无需干预 |
| 0.10 ≤ PSI < 0.25 | 轻度偏移,需关注 | 排查分箱内客群特征变化 |
| PSI ≥ 0.25 | 严重偏移,需立即行动 | 触发模型重训或策略调整 |
催收场景解读:上述示例PSI=0.0296,表明当前触达客群分布与模型开发时基本一致。若PSI超过0.10,需重点检查箱1(低分客群占比下降)和箱3(中分客群占比上升),这可能意味着催收策略调整导致高风险客群被提前过滤。
4.5 完整计算代码示例(Python)
以下代码展示了PSI计算的完整实现,可直接用于催收触达监控的自动化脚本:
import numpy as np
import pandas as pd
def calculate_psi(expected, actual, bins=10):
"""
计算PSI(群体稳定性指标)
Parameters:
expected: array-like, 预期样本数据
actual: array-like, 实际样本数据
bins: int, 分箱数量(默认10箱等频分箱)
Returns:
psi_value: float, PSI值
psi_df: DataFrame, 各箱详细计算结果
"""
# 步骤1:基于预期数据确定分箱边界(等频分箱)
percentiles = np.linspace(0, 100, bins + 1)
bin_edges = np.percentile(expected, percentiles)
# 确保边界唯一
bin_edges = np.unique(bin_edges)
# 步骤2:计算各箱占比
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)
# 步骤3:计算WOE与差异项
# 避免除零和取对数问题
eps = 0.0001
expected_pct = np.clip(expected_pct, eps, 1 - eps)
actual_pct = np.clip(actual_pct, eps, 1 - eps)
woe = np.log(actual_pct / expected_pct)
diff = (actual_pct - expected_pct) * woe
# 步骤4:累加得到PSI值
psi_value = np.sum(diff)
# 构建结果DataFrame
psi_df = pd.DataFrame({
'箱区间': [f'[{bin_edges[i]:.2f}, {bin_edges[i+1]:.2f})'
for i in range(len(bin_edges)-1)],
'预期占比': expected_pct,
'实际占比': actual_pct,
'WOE': woe,
'差异项': diff
})
return psi_value, psi_df
# 使用示例
if __name__ == "__main__":
# 模拟催收评分数据
np.random.seed(42)
expected_scores = np.random.normal(600, 100, 10000)
actual_scores = np.random.normal(610, 110, 10000)
psi, details = calculate_psi(expected_scores, actual_scores)
print(f"PSI值: {psi:.4f}")
print("\n各箱详细计算结果:")
print(details)
代码要点:
- 使用
np.percentile基于预期数据确定等频分箱边界,确保实际数据沿用相同边界 - 通过
np.clip将占比限制在[0.0001, 0.9999]区间,避免WOE计算出现无穷大 - 返回的
psi_df可直接用于监控报表,定位偏移最大的箱
通过以上四个步骤,即可完成PSI的完整计算。在实际催收触达监控中,建议将PSI计算封装为自动化函数,每日/每周定时运行,并将结果写入监控看板,实现分布偏移的实时预警。