3. 特征漂移基础概念:数据分布、总体分布与样本分布、平稳性、概念漂移与特征漂移的区别
在贷后预警系统中,模型性能下降往往不是因为算法失效,而是因为输入数据或业务环境发生了不可逆的变化。理解特征漂移的前提,是掌握数据分布、平稳性以及漂移类型之间的本质区别。本节从最基础的统计概念出发,逐步构建漂移检测的理论框架。
3.1 数据分布:总体分布与样本分布
数据分布是描述数据取值规律的核心工具。在风控建模中,我们通常区分两个层次:
- 总体分布:理论上所有可能样本的分布,通常未知,只能通过历史数据近似估计。
- 样本分布:实际观测到的有限样本的分布,是总体分布的一个近似。
特征漂移检测的本质,就是比较不同时间窗口下样本分布之间、或样本分布与参考分布之间的差异是否显著。
| 对比维度 | 总体分布 | 样本分布 |
|---|---|---|
| 定义 | 所有可能数据的概率分布 | 实际采集到的有限数据的分布 |
| 可观测性 | 不可直接观测 | 可直接计算(直方图、核密度估计) |
| 在漂移检测中的角色 | 作为参考基准(通常用训练集近似) | 作为待检测对象(新批次数据) |
| 变化含义 | 业务环境发生根本性改变 | 可能由随机波动或真实漂移引起 |
关键认知:我们永远无法直接观测总体分布,只能通过样本分布推断总体是否发生变化。漂移检测的所有统计方法,本质上都是在控制“样本随机波动”这一噪声的前提下,判断分布差异是否达到统计显著水平。
3.2 平稳性:时间序列视角下的分布稳定性
平稳性(Stationarity)是时间序列分析的核心概念,也是特征漂移检测的重要理论基础。一个平稳时间序列的统计性质(均值、方差、自协方差)不随时间推移而改变。
- 严平稳:任意时间点的联合分布完全相同。条件极强,实际中很少满足。
- 弱平稳(宽平稳):均值恒定、方差有限且恒定、自协方差仅与时间间隔有关。这是风控特征检测中最常用的假设。
当特征序列不满足弱平稳性时,说明该特征存在趋势、季节性或其他结构性变化,这正是特征漂移的典型表现。
实战提示:在贷后预警场景中,我们通常对每个特征单独进行平稳性检验(如ADF检验、KPSS检验)。如果检验结果显示非平稳,则意味着该特征在时间维度上存在漂移风险,需要进一步定位漂移发生的时间点。
3.3 概念漂移与特征漂移的区别
这是风控建模中最容易混淆的两个概念。两者的核心区别在于:变化发生在哪里。
| 对比维度 | 概念漂移(Concept Drift) | 特征漂移(Feature Drift) |
|---|---|---|
| 变化对象 | P(Y|X) —— 给定特征下标签的条件分布 | P(X) —— 特征本身的边际分布 |
| 典型表现 | 同样的特征值,违约概率发生变化 | 特征取值整体偏移,但映射关系可能不变 |
| 对模型的影响 | 直接导致模型预测失效 | 可能导致模型输入超出训练范围 |
| 检测方法 | 需结合标签反馈(如DDM、ADWIN) | 仅需特征数据(如KS检验、PSI) |
| 在贷后预警中的优先级 | 高(直接影响风险排序) | 中高(特征漂移常先于概念漂移出现) |
避坑指南:不要将特征漂移与概念漂移混为一谈。特征漂移不一定导致模型失效——如果模型对特征变化具有鲁棒性,P(Y|X) 可能保持不变。反之,概念漂移发生时即使特征分布完全不变,模型输出也会失准。在贷后预警系统中,建议先检测特征漂移作为早期预警信号,再结合标签反馈确认是否存在概念漂移。
3.4 三种漂移类型的关系图谱
下面的SVG图展示了总体分布、样本分布、平稳性、特征漂移和概念漂移之间的逻辑关系,帮助建立完整的知识框架。
3.5 平稳性检验与漂移检测的衔接
在贷后预警特征漂移检测的实战流程中,平稳性检验通常作为第一步筛选工具。下面的SVG图展示了从特征采集到漂移判定的完整技术链路。
3.6 实战代码:平稳性检验与分布比较
以下代码演示如何对贷后特征进行平稳性检验,并计算两个时间窗口之间的分布差异。这是后续章节中漂移检测的核心基础。
import pandas as pd
import numpy as np
from scipy import stats
from statsmodels.tsa.stattools import adfuller
# 模拟贷后特征数据:近6个月月均收入
np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=180, freq='D')
# 前90天:稳定分布
income_stable = np.random.normal(15000, 3000, 90)
# 后90天:均值偏移(特征漂移)
income_shift = np.random.normal(18000, 3500, 90)
income = np.concatenate([income_stable, income_shift])
df = pd.DataFrame({'date': dates, 'income': income})
df.set_index('date', inplace=True)
# 1. 平稳性检验(ADF检验)
adf_result = adfuller(df['income'])
print(f'ADF统计量: {adf_result[0]:.4f}')
print(f'p值: {adf_result[1]:.6f}')
print('结论: 序列非平稳' if adf_result[1] > 0.05 else '结论: 序列平稳')
# 2. 分布比较:前90天 vs 后90天
window1 = df.iloc[:90]['income']
window2 = df.iloc[90:]['income']
# KS检验
ks_stat, ks_p = stats.ks_2samp(window1, window2)
print(f'\nKS统计量: {ks_stat:.4f}, p值: {ks_p:.6f}')
print('两个窗口分布存在显著差异' if ks_p < 0.05 else '两个窗口分布无显著差异')
# 3. 计算PSI(群体稳定性指标)
def calculate_psi(expected, actual, bins=10):
"""计算PSI值"""
breaks = np.percentile(expected, np.linspace(0, 100, bins + 1))
breaks[0] = breaks[0] - 0.001 # 确保最小值包含
breaks[-1] = breaks[-1] + 0.001
expected_counts = np.histogram(expected, bins=breaks)[0]
actual_counts = np.histogram(actual, bins=breaks)[0]
expected_pct = expected_counts / len(expected)
actual_pct = actual_counts / len(actual)
# 处理零值
expected_pct = np.clip(expected_pct, 0.001, 1)
actual_pct = np.clip(actual_pct, 0.001, 1)
psi = np.sum((actual_pct - expected_pct) * np.log(actual_pct / expected_pct))
return psi
psi_value = calculate_psi(window1, window2)
print(f'PSI值: {psi_value:.4f}')
if psi_value < 0.1:
print('PSI < 0.1: 分布无显著变化')
elif psi_value < 0.25:
print('0.1 ≤ PSI < 0.25: 分布轻度变化,需关注')
else:
print('PSI ≥ 0.25: 分布显著变化,触发预警')
代码解读:上述代码完整演示了从平稳性检验到分布比较的链路。ADF检验用于判断特征时间序列是否平稳;KS检验和PSI用于量化两个时间窗口之间的分布差异。在贷后预警系统中,建议将PSI阈值设为0.1作为关注线、0.25作为预警线,并结合业务经验调整。
3.7 本节要点总结
- 总体分布 vs 样本分布:漂移检测只能基于样本分布推断,需控制随机波动的影响。
- 平稳性:是特征漂移检测的前置条件,非平稳序列必然存在某种形式的分布变化。
- 特征漂移 vs 概念漂移:特征漂移关注P(X)变化,概念漂移关注P(Y|X)变化,两者检测方法和影响范围不同。
- 检测优先级:特征漂移可作为概念漂移的先行指标,建议先检测特征漂移,再结合标签反馈确认概念漂移。
- 实战工具:ADF检验用于平稳性判断,KS检验和PSI用于分布差异量化,三者构成贷后预警特征漂移检测的基础工具箱。