3. PSI指标数学原理:公式推导、分箱策略与阈值设定

群体稳定性指标(Population Stability Index, PSI)是反洗钱风控中衡量模型评分或特征分布随时间漂移的核心量化工具。本章从数学公式推导出发,深入解析分箱策略与阈值设定逻辑,为后续Flink实时计算PSI打下理论基础。

3.1 PSI计算公式推导

PSI的核心思想是比较两个分布——期望分布(Expected, E)与实际分布(Actual, A)——在每个分箱上的占比差异,并加权求和。其数学本质是相对熵(KL散度)的对称化变体。

假设将特征或评分划分为 n 个分箱,对于第 i 个分箱:

  • 期望占比:E_i = count_i(期望样本) / 总期望样本数
  • 实际占比:A_i = count_i(实际样本) / 总实际样本数

PSI计算公式如下:

PSI = Σ_{i=1}^{n} (A_i - E_i) * ln(A_i / E_i)

其中:

  • (A_i - E_i):占比差异,反映分布偏移幅度。
  • ln(A_i / E_i):对数比率,放大微小偏移的敏感度。
  • 当 A_i = E_i 时,该箱贡献为0;当差异越大,贡献值越大。
关键理解: PSI值越大,说明实际分布与期望分布偏离越严重,模型或特征越不稳定。PSI为0表示完全一致,无漂移。

3.2 分箱策略:等距分箱 vs 等频分箱

分箱是PSI计算的前置步骤,直接影响指标敏感度与稳定性。两种主流策略对比如下:

对比维度 等距分箱(Equal Width) 等频分箱(Equal Frequency)
分箱方式 将数值范围等分为固定宽度的区间 将样本按数量均分,每个箱包含近似相等的样本数
适用场景 评分卡分数、概率值等有明确上下界的连续变量 长尾分布、偏态严重的特征(如交易金额)
优点 分箱边界固定,跨时间可比性强;计算简单 避免空箱或样本过少;对异常值不敏感
缺点 数据稀疏时可能出现空箱,导致PSI计算异常 分箱边界随分布变化,跨期对比时边界不一致
反洗钱推荐 模型评分、风险等级概率 交易金额、账户余额、交易频次
实战建议: 在Flink实时PSI计算中,建议对模型评分使用等距分箱(如10箱,每箱0.1),对交易金额使用等频分箱(基于历史分布分位点),并在状态后端持久化分箱边界。

3.3 PSI阈值设定逻辑

PSI阈值决定了何时触发漂移告警。阈值设定需结合业务容忍度与统计显著性,常见经验规则如下:

PSI范围 漂移程度 建议动作
PSI < 0.1 无显著漂移 无需干预,持续监控
0.1 ≤ PSI < 0.25 轻度漂移 触发预警,人工复核特征分布
PSI ≥ 0.25 严重漂移 立即告警,暂停模型或特征使用,启动重训练

阈值设定需考虑以下因素:

  • 业务敏感性:高风险场景(如大额交易、跨境汇款)可收紧阈值至0.1。
  • 样本量:小样本时PSI波动大,可适当放宽至0.2。
  • 分箱数:分箱越多,PSI对微小偏移越敏感,需相应调整阈值。
  • 时间窗口:日级监控使用0.1~0.2,周级或月级监控使用0.2~0.3。
避坑提示: 不要直接套用0.1/0.25的固定阈值。建议在Flink作业中配置动态阈值,结合历史PSI分布的均值与标准差,使用3σ原则或百分位法自动调整。

3.4 PSI计算流程与分箱策略选择

下图展示了PSI从数据输入到告警输出的完整计算流程,以及分箱策略的决策路径:

PSI计算流程与分箱策略决策 期望分布 + 实际分布 选择分箱策略 等距分箱 等频分箱 计算各箱 E_i 与 A_i PSI = Σ(A_i - E_i)·ln(A_i/E_i) PSI ≥ 阈值? 触发告警 持续监控

3.5 分箱策略对PSI的影响对比

以下SVG图直观对比了同一组数据在等距分箱与等频分箱下的PSI计算差异,帮助理解策略选择对漂移敏感度的影响:

等距分箱 vs 等频分箱 PSI 对比示例 等距分箱(10箱) 期望分布(蓝色) 实际分布(红色) 等频分箱(10箱) 期望分布(紫色) 实际分布(红色) 等距分箱对尾部偏移更敏感,等频分箱对主体分布偏移更敏感

3.6 分箱策略选择决策树

在实际反洗钱场景中,可按以下决策树快速选择分箱策略:

  1. 特征是否有明确业务边界?(如评分0~1、概率0%~100%)→ 是 → 等距分箱
  2. 特征是否呈长尾分布?(如交易金额、账户余额)→ 是 → 等频分箱
  3. 特征是否为类别型?(如交易类型、国家代码)→ 每个类别作为一个自然箱,无需分箱
  4. 样本量是否极小?(如<1000)→ 减少分箱数(如5箱),优先使用等频分箱避免空箱
Flink实现要点: 在Flink SQL或DataStream API中,等距分箱可通过 CASE WHEN 或 FLOOR(score * 10) 实现;等频分箱需预先计算分位点并广播至作业,使用 KeyedProcessFunction 动态分配箱号。