2. 漂移概念与类型:模型漂移定义、概念漂移、数据漂移、业务漂移
2.1 模型漂移的核心定义
在信用额度定价场景中,模型漂移指已上线模型在真实生产环境中的预测性能随时间推移而持续下降的现象。这种下降并非由模型参数或算法本身引起,而是由外部环境、客户行为或数据分布的变化导致。
关键指标:模型漂移通常通过监控 PSI(群体稳定性指标)、KS(Kolmogorov-Smirnov)、AUC(曲线下面积) 等指标的变化来量化。当这些指标超出预设阈值时,即触发漂移告警。
2.2 三种漂移类型的对比
根据漂移的根源,可将其分为三类:概念漂移、数据漂移、业务漂移。下表从定义、成因、影响和检测方法四个维度进行对比:
| 维度 | 概念漂移 | 数据漂移 | 业务漂移 |
|---|---|---|---|
| 定义 | 输入特征与目标变量之间的映射关系发生变化 | 输入特征的分布(如均值、方差、分位数)发生变化 | 业务规则、产品策略或监管要求发生改变 |
| 典型成因 | 经济周期切换、客户还款意愿结构性改变 | 获客渠道调整、数据采集系统升级、季节性波动 | 利率政策调整、额度审批规则变更、新客群引入 |
| 对模型的影响 | 模型预测逻辑失效,AUC/KS 显著下降 | 模型输入分布偏移,评分卡分数整体偏移 | 模型输出与业务目标脱节,定价策略失效 |
| 检测方法 | PSI、KS 趋势监控、残差分析 | 特征分布对比(t检验、KS检验)、PSI | 业务指标监控(通过率、逾期率、平均额度) |
2.3 概念漂移详解
概念漂移是三种漂移中影响最深远的一种。它意味着模型学习到的“特征→目标”函数已经改变。例如,在信用额度定价模型中,原本“收入高→违约率低”的规律,可能因经济下行而变为“收入高但负债率高的客户违约率上升”。
- 突发型概念漂移:由突发事件引起,如疫情爆发导致短期内所有客群违约率飙升。
- 渐进型概念漂移:随时间缓慢变化,如客户群体平均收入逐年增长。
- 周期型概念漂移:呈现季节性规律,如节假日消费信贷需求增加。
实操提示:在信用额度定价场景中,建议同时监控 PSI 和 KS。PSI 反映整体分布偏移,KS 反映区分能力变化。两者结合可有效区分概念漂移与数据漂移。
2.4 数据漂移详解
数据漂移指模型输入特征的统计分布发生变化,但特征与目标之间的映射关系保持不变。例如,由于获客渠道从线下转为线上,客户年龄分布从 35-45 岁变为 25-35 岁,但“年龄→违约率”的关系曲线形状未变。
数据漂移的常见来源:
- 数据采集变化:数据源切换、字段定义变更、缺失值处理逻辑调整。
- 样本选择偏差:训练集与生产集客群结构不一致。
- 特征工程变化:特征计算方式或聚合窗口期改变。
2.5 业务漂移详解
业务漂移是金融风控领域特有的漂移类型,指业务规则、产品策略或监管环境的变化导致模型输出不再适用。例如:
- 监管要求将信用卡最低还款额从 10% 提升至 15%,导致客户还款行为改变。
- 公司调整额度定价策略,将利率下限从 12% 降至 8%,模型预测的违约概率不再直接对应定价。
- 引入新的客群(如大学生群体),其信用行为模式与原有客群完全不同。
注意:业务漂移往往需要人工干预,无法通过纯数据驱动的方法完全检测。建议建立业务变更日志,与模型监控系统联动。
2.6 三种漂移的关系与交互
在实际生产环境中,三种漂移往往同时发生并相互影响。下图展示了它们之间的交互关系:
2.7 漂移检测的实操框架
在信用额度定价场景中,建议采用以下分层检测框架:
| 检测层级 | 监控对象 | 常用指标 | 告警阈值 |
|---|---|---|---|
| L1:特征级 | 每个输入特征的分布 | PSI、KS检验、t检验 | PSI > 0.1 或 KS p值 < 0.05 |
| L2:模型级 | 模型预测分数分布 | PSI、AUC、KS | PSI > 0.2 或 AUC下降 > 0.03 |
| L3:业务级 | 业务结果指标 | 通过率、逾期率、平均额度 | 通过率波动 > 5% 或逾期率上升 > 20% |
最佳实践:建议将三个层级的监控结果汇总到统一的漂移看板中。当 L1 或 L2 触发告警时,立即检查 L3 的业务指标是否同步变化,以快速定位漂移类型。
2.8 代码示例:PSI 计算与漂移判断
以下 Python 代码演示如何计算 PSI 并判断是否存在数据漂移:
import numpy as np
import pandas as pd
def calculate_psi(expected, actual, bins=10):
"""
计算群体稳定性指标 (PSI)
:param expected: 期望分布(训练集)
:param actual: 实际分布(生产集)
:param bins: 分箱数
:return: PSI 值
"""
# 基于期望分布确定分箱边界
percentiles = np.linspace(0, 100, bins + 1)
bin_edges = np.percentile(expected, percentiles)
# 分箱
expected_counts = np.histogram(expected, bins=bin_edges)[0]
actual_counts = np.histogram(actual, bins=bin_edges)[0]
# 计算比例
expected_pct = expected_counts / len(expected)
actual_pct = actual_counts / len(actual)
# 避免除零
expected_pct = np.clip(expected_pct, 0.001, 0.999)
actual_pct = np.clip(actual_pct, 0.001, 0.999)
# 计算 PSI
psi = np.sum((actual_pct - expected_pct) * np.log(actual_pct / expected_pct))
return psi
# 示例数据
train_scores = np.random.normal(0.5, 0.1, 10000)
prod_scores = np.random.normal(0.55, 0.12, 10000)
psi_value = calculate_psi(train_scores, prod_scores)
print(f"PSI = {psi_value:.4f}")
# 漂移判断
if psi_value < 0.1:
print("✅ 无显著漂移")
elif psi_value < 0.25:
print("⚠️ 轻度漂移,需关注")
else:
print("❌ 严重漂移,立即排查")
实操要点:PSI 阈值可根据业务容忍度调整。在信用额度定价场景中,建议将 0.1 作为关注阈值,0.25 作为告警阈值。同时,建议按客群分层计算 PSI,避免整体分布掩盖局部漂移。