3. 漂移检测的统计学基础:假设检验与分布距离度量

贷后预警特征发生漂移时,我们需要用统计学方法量化“分布是否改变”以及“改变的程度有多大”。本章聚焦两类核心工具:假设检验(KS检验、卡方检验)用于判断漂移是否显著;分布距离度量(KL散度、Wasserstein距离)用于衡量漂移的幅度。两者结合,才能为告警阈值提供科学依据。

3.1 假设检验:判断漂移是否显著

假设检验的核心逻辑是:设定原假设 H₀(特征分布未发生漂移),通过检验统计量计算 p 值,若 p 值小于显著性水平 α(通常取 0.05 或 0.01),则拒绝 H₀,认为漂移显著。

3.1.1 KS检验(Kolmogorov-Smirnov Test)

KS检验用于比较连续型特征的分布差异。它计算两个经验累积分布函数(ECDF)之间的最大垂直距离 D 作为统计量。

  • 适用场景:收入、年龄、信用评分、负债率等连续数值特征。
  • 统计量:D = max |F₁(x) - F₂(x)|,其中 F₁、F₂ 分别为参考窗口和监测窗口的 ECDF。
  • 优点:无需假设数据分布形态,对位置和形状变化敏感。
  • 缺点:对尾部差异不敏感,大样本下容易拒绝 H₀。
贷后应用提示:KS检验常用于监测“收入分布”是否因客群结构变化而整体偏移。若 D 值超过 0.1 且 p < 0.05,通常触发预警。

3.1.2 卡方检验(Chi-Square Test)

卡方检验用于比较离散型特征或分箱后的类别分布。它检验观测频数与期望频数之间的差异是否显著。

  • 适用场景:逾期等级、职业类型、地区编码、分箱后的年龄组等。
  • 统计量:χ² = Σ (Oᵢ - Eᵢ)² / Eᵢ,其中 Oᵢ 为观测频数,Eᵢ 为期望频数。
  • 优点:直观、计算简单,适合类别型特征。
  • 缺点:对样本量敏感,期望频数过小(<5)时结果不可靠。
KS检验 vs 卡方检验:核心对比
维度 KS检验 卡方检验
数据类型 连续型 离散型 / 分箱后连续型
统计量含义 ECDF 最大垂直距离 观测与期望频数偏差平方和
对样本量敏感度 高(大样本易显著) 高(大样本易显著)
贷后典型特征 收入、额度、利率 逾期等级、地区、职业
漂移方向感知 可感知整体偏移 可感知类别比例变化
实操建议:在贷后预警系统中,建议对连续特征优先使用 KS 检验,对离散特征使用卡方检验。若特征同时包含连续和离散属性,可先分箱再使用卡方检验。
假设检验流程:KS检验与卡方检验 参考窗口分布 监测窗口分布 数据类型判断 KS检验(连续型) 卡方检验(离散型) p < α → 漂移显著 p < α → 漂移显著 显著性水平 α 通常取 0.05 或 0.01 p < α 时拒绝 H₀,触发预警

3.2 分布距离度量:量化漂移幅度

假设检验只能回答“是否显著”,但无法衡量“漂移有多大”。分布距离度量弥补了这一不足,为告警阈值提供连续、可比较的数值依据。

3.2.1 KL散度(Kullback-Leibler Divergence)

KL散度衡量两个概率分布 P 和 Q 之间的相对熵,即用 Q 近似 P 时损失的信息量。

  • 公式:DKL(P || Q) = Σ P(x) log(P(x) / Q(x))
  • 特点:非对称(DKL(P||Q) ≠ DKL(Q||P)),对分布尾部差异敏感。
  • 取值范围:[0, +∞),0 表示完全相同。
  • 贷后应用:监测“逾期率分布”在时间窗口间的信息损失,常用于评分卡特征漂移检测。
注意:KL散度要求 Q(x) > 0 时 P(x) 也必须 > 0,否则会出现无穷大。实际应用中需做平滑处理(如加极小值 ε)。

3.2.2 Wasserstein距离(Earth Mover's Distance)

Wasserstein距离衡量将一个分布“搬运”成另一个分布所需的最小成本,直观理解为“推土机距离”。

  • 公式(一维):W(P, Q) = ∫ |F⁻¹(t) - G⁻¹(t)| dt,其中 F、G 为累积分布函数。
  • 特点:对称、对分布形状变化敏感、支持离散与连续分布。
  • 取值范围:[0, +∞),0 表示完全相同。
  • 贷后应用:监测“授信额度分布”的平移和形变,比 KL 散度更稳定。
KL散度 vs Wasserstein距离:核心对比
维度 KL散度 Wasserstein距离
对称性 非对称 对称
对尾部敏感度 高(对数尺度) 中(线性尺度)
对平移敏感度 低 高
计算复杂度 低 中(一维可排序优化)
贷后典型特征 逾期率、违约概率 额度、利率、收入
阈值设定难度 需经验参考 可结合业务单位
分布距离度量:从信息损失到搬运成本 KL散度:信息损失视角 分布 P(参考) 分布 Q(监测) KL(P||Q) DKL(P||Q) = Σ P(x) log(P(x)/Q(x)) 非对称 | 对尾部敏感 | 需平滑 贷后:逾期率分布信息损失 Wasserstein距离:搬运成本视角 分布 P(参考) 分布 Q(监测) W(P,Q) W(P,Q) = ∫ |F⁻¹(t) - G⁻¹(t)| dt 对称 | 对平移敏感 | 线性尺度 贷后:额度分布搬运成本

3.3 从统计量到告警阈值:实践框架

将假设检验与距离度量结合,形成贷后预警特征漂移的阈值设定框架:

  1. 选择检验方法:根据特征数据类型选择 KS 检验(连续)或卡方检验(离散)。
  2. 计算距离度量:同步计算 KL 散度或 Wasserstein 距离,作为漂移幅度的连续指标。
  3. 设定显著性水平:α 通常取 0.05,对高风险特征可收紧至 0.01。
  4. 确定距离阈值:基于历史漂移分布的分位数(如 95% 分位数)或业务容忍度设定。
  5. 组合决策:当 p < α 且距离度量超过阈值时,触发告警;仅 p < α 但距离较小时,可降级为观察。
最佳实践:在贷后预警系统中,建议对每个特征维护一个“漂移档案”,记录历史 KS 统计量、Wasserstein 距离和 p 值序列。当新窗口的统计量超过历史 95% 分位数时,即使 p 值未显著,也应触发低级别告警。

3.4 代码示例:Python 实现漂移检测

import numpy as np
from scipy.stats import ks_2samp, chi2_contingency
from scipy.special import rel_entr
from scipy.stats import wasserstein_distance

# 示例:连续特征漂移检测(KS检验 + Wasserstein距离)
np.random.seed(42)
ref_data = np.random.normal(50000, 15000, 10000)  # 参考窗口:收入分布
mon_data = np.random.normal(52000, 16000, 10000)  # 监测窗口:收入分布

# KS检验
ks_stat, ks_p = ks_2samp(ref_data, mon_data)
print(f"KS统计量: {ks_stat:.4f}, p值: {ks_p:.4f}")

# Wasserstein距离
w_dist = wasserstein_distance(ref_data, mon_data)
print(f"Wasserstein距离: {w_dist:.2f}")

# 示例:离散特征漂移检测(卡方检验 + KL散度)
ref_cat = np.random.choice(['A', 'B', 'C'], 5000, p=[0.5, 0.3, 0.2])
mon_cat = np.random.choice(['A', 'B', 'C'], 5000, p=[0.4, 0.35, 0.25])

# 构建列联表
ref_counts = np.array([np.sum(ref_cat == c) for c in ['A', 'B', 'C']])
mon_counts = np.array([np.sum(mon_cat == c) for c in ['A', 'B', 'C']])
contingency = np.array([ref_counts, mon_counts])

# 卡方检验
chi2_stat, chi2_p, dof, expected = chi2_contingency(contingency)
print(f"卡方统计量: {chi2_stat:.4f}, p值: {chi2_p:.4f}")

# KL散度(需归一化为概率)
ref_prob = ref_counts / ref_counts.sum()
mon_prob = mon_counts / mon_counts.sum()
kl_div = np.sum(rel_entr(ref_prob, mon_prob))
print(f"KL散度: {kl_div:.4f}")
阈值参考:在贷后场景中,KS 统计量 > 0.1 且 p < 0.05 通常视为显著漂移;Wasserstein 距离阈值需结合特征量纲(如收入以元为单位时,阈值可设为 2000-5000);KL 散度 > 0.01 时建议关注。