4. 数据预处理:缺失值处理、异常值检测与标准化
在压力测试情景分析中,原始数据通常来自多个业务系统,存在不同程度的缺失、异常和量纲差异。若不经过预处理直接建模,会导致特征筛选结果失真、模型参数不稳定,甚至使压力情景的传导路径产生系统性偏差。本节围绕缺失值处理、异常值检测和标准化/归一化三个核心环节,给出适用于压力测试场景的实践方法。
4.1 缺失值处理
缺失值在压力测试数据中常见于:历史违约记录不全、宏观经济指标发布频率不一致、部分情景参数未采集等场景。处理方式需结合缺失机制(MCAR/MAR/MNAR)和数据分布特征选择。
| 方法 | 适用场景 | 压力测试中的典型应用 | 注意事项 |
|---|---|---|---|
| 均值/中位数填充 | 数值型变量,缺失率 < 5%,数据分布对称或轻度偏态 | GDP增速、CPI等宏观指标月度缺失 | 会降低方差,可能导致压力情景尾部风险低估 |
| 中位数填充 | 数值型变量,存在明显偏态或异常值 | 不良贷款率、企业杠杆率等金融指标 | 对异常值稳健,但可能破坏时间序列自相关结构 |
| 线性插补 | 时间序列数据,缺失点前后有观测值 | 利率期限结构、汇率日频数据缺失 | 适用于连续变化变量,不适用于突变情景 |
| KNN插补 | 多变量关联缺失,样本量充足 | 客户信用评分卡中多个特征同时缺失 | 计算成本高,需先标准化;K值通常取5~10 |
| 多重插补(MICE) | 缺失率较高(5%~30%),需保留不确定性 | 压力测试情景参数集的多维缺失 | 生成多个完整数据集,后续建模需合并估计 |
压力测试实践建议:对于宏观压力测试中的关键驱动变量(如GDP、失业率),优先使用线性插补或时间序列插补,避免均值填充抹平周期波动。对于微观层面的客户特征,若缺失率超过30%,建议将该特征标记为“缺失指示变量”后纳入筛选流程,而非直接填充。
4.2 异常值检测
异常值在压力测试中具有双重含义:一是数据采集或录入错误导致的“脏数据”,二是极端但真实发生的“压力事件”。预处理阶段主要处理前者,后者应保留并作为压力情景的校准参考。
4.2.1 IQR(四分位距)法
适用于非正态分布数据,对极端值不敏感。定义下界为 Q1 - 1.5×IQR,上界为 Q3 + 1.5×IQR,超出范围视为异常。
import numpy as np
def detect_outliers_iqr(data):
Q1 = np.percentile(data, 25)
Q3 = np.percentile(data, 75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
outliers = (data < lower_bound) | (data > upper_bound)
return outliers, lower_bound, upper_bound
4.2.2 3σ(三倍标准差)法
适用于近似正态分布数据。以均值μ为中心,超出μ±3σ范围视为异常。在压力测试中,对于尾部风险较大的金融数据(如收益率、违约率),建议使用更宽松的5σ阈值,避免误删真实压力事件。
def detect_outliers_3sigma(data):
mean = np.mean(data)
std = np.std(data)
lower_bound = mean - 3 * std
upper_bound = mean + 3 * std
outliers = (data < lower_bound) | (data > upper_bound)
return outliers, lower_bound, upper_bound
| 对比维度 | IQR法 | 3σ法 |
|---|---|---|
| 分布假设 | 无严格假设 | 近似正态分布 |
| 对极端值稳健性 | 高(基于分位数) | 低(均值和标准差易受极端值影响) |
| 压力测试适用性 | 适用于偏态金融指标(如LGD、PD) | 适用于对称宏观指标(如GDP增速、通胀率) |
| 阈值调整 | 可调整IQR倍数(如3×IQR更严格) | 可调整σ倍数(如5σ更宽松) |
异常值处理原则:在压力测试情景分析中,切勿自动删除所有检测到的异常值。应先结合业务逻辑判断:若为录入错误(如负的贷款金额),则修正或删除;若为真实极端事件(如2008年金融危机期间的违约率飙升),应保留并作为极端情景的校准锚点。
4.3 数据标准化与归一化
压力测试特征通常具有不同量纲(如贷款金额以万元计、利率以百分比计、违约概率以小数计)。若不进行标准化,量纲大的特征会在距离计算、正则化模型中占据主导地位,导致特征筛选偏差。
4.3.1 Z-score 标准化
将数据转换为均值为0、标准差为1的分布。适用于特征本身近似正态分布或后续使用线性模型、SVM、PCA等对尺度敏感的场景。
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 转换后:X_scaled ~ N(0, 1)
4.3.2 Min-Max 归一化
将数据线性映射到[0,1]区间。适用于特征有明确边界(如违约率0~1、资本充足率0~100%)或使用神经网络、距离度量(KNN、K-Means)的场景。
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
X_normalized = scaler.fit_transform(X)
# 转换后:X_normalized ∈ [0, 1]
| 对比维度 | Z-score 标准化 | Min-Max 归一化 |
|---|---|---|
| 输出范围 | 无固定范围(通常约[-3,3]) | 固定[0,1]或[-1,1] |
| 对异常值敏感度 | 低(基于均值和标准差) | 高(受最大值最小值影响大) |
| 适用模型 | 线性回归、SVM、PCA、Lasso | 神经网络、KNN、K-Means、深度学习 |
| 压力测试场景 | 宏观因子标准化(GDP、通胀、利率) | 风险指标归一化(PD、LGD、EAD) |
| 保留分布形状 | 是(保持原始分布形态) | 否(改变分布形状,压缩尾部) |
标准化顺序:在压力测试特征筛选流程中,标准化/归一化应在缺失值处理和异常值处理之后进行。若先标准化再处理异常值,异常值会扭曲均值和标准差,导致标准化后的数据仍然存在尺度偏差。建议流程为:缺失值填充 → 异常值识别/处理 → 标准化/归一化 → 特征筛选。
4.4 预处理顺序与注意事项
- 先处理缺失值,再检测异常值:缺失值会影响分位数和标准差的计算,导致异常值检测阈值偏移。
- 异常值处理需保留业务含义:压力测试中,极端值可能是未来压力情景的参照,建议建立“异常值标签”字段,而非直接删除。
- 标准化参数需从训练集估计:在时间序列压力测试中,应使用历史窗口的均值和标准差进行标准化,避免未来信息泄露。
- 分组标准化:对于面板数据(多个主体×多个时间点),建议按主体或行业分组标准化,保留组间差异。
- 记录预处理参数:保存每个特征的填充值、异常值阈值、标准化参数,用于后续模型解释和回溯验证。
关键提醒:数据预处理不是一次性工作。在压力测试情景分析中,每次新增情景或更新数据后,应重新评估缺失模式、异常值分布和标准化参数的稳定性。预处理步骤应作为特征筛选pipeline的一部分,实现自动化、可复现的预处理流程。