3. 数据清洗基础:缺失值处理与异常值检测
在授信决策引擎中,原始数据几乎不可能完美。缺失值会破坏模型训练,异常值会扭曲统计分布。本章聚焦两类最核心的清洗操作:缺失值填充与异常值截断,并给出工程落地的选择依据。
3.1 缺失值处理
缺失值处理需先判断缺失机制:完全随机缺失(MCAR)、随机缺失(MAR)或非随机缺失(MNAR)。不同机制影响填充方法的选择。工程上常用以下三类方法:
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 均值/中位数填充 | 连续型变量,分布对称(均值)或偏态(中位数) | 计算极快,可批量处理 | 降低方差,扭曲分布形态 |
| 众数填充 | 分类型变量(如婚姻状况、学历等级) | 保持类别分布 | 可能引入偏差,丢失稀有类别信息 |
| 模型预测填充 | 缺失率较低(<30%),且变量间存在相关性 | 保留数据分布,精度高 | 计算成本高,需避免数据泄露 |
工程建议:在授信决策引擎中,中位数填充是连续变量的默认首选,因为它对收入、负债比等右偏分布更稳健。模型预测填充仅用于关键变量(如收入、征信评分),且必须在训练集内做交叉验证,防止目标泄露。
3.1.1 模型预测填充流程
- 划分数据集:将原始数据分为缺失组(X_missing)和完整组(X_complete)。
- 特征选择:选取与待填充变量高度相关且自身无缺失的特征作为预测变量。
- 训练预测模型:在完整组上训练回归(连续变量)或分类(离散变量)模型。
- 填充:用训练好的模型预测缺失组的值,回填至原数据。
- 验证:检查填充后变量的分布与原始完整组是否一致。
# Python 示例:使用随机森林预测填充收入缺失值
from sklearn.ensemble import RandomForestRegressor
import pandas as pd
# 假设 df 包含 'income' 列,且存在缺失
train = df[df['income'].notna()]
test = df[df['income'].isna()]
features = ['age', 'education_years', 'work_years', 'debt_ratio']
X_train = train[features]
y_train = train['income']
X_test = test[features]
model = RandomForestRegressor(n_estimators=100, random_state=42)
model.fit(X_train, y_train)
predicted_income = model.predict(X_test)
df.loc[df['income'].isna(), 'income'] = predicted_income
避坑提醒:模型预测填充时,绝对不要将待填充变量本身作为预测特征,也不要在填充前对全数据集做标准化,否则会导致数据泄露和过拟合。
3.2 异常值检测与截断
异常值在授信数据中常见于收入、负债、交易金额等字段。异常值可能来自录入错误、欺诈行为或真实极端客户。处理原则是:先检测,后截断(而非删除),保留样本量。
3.2.1 三种主流检测方法
| 方法 | 原理 | 阈值 | 适用场景 |
|---|---|---|---|
| IQR(四分位距) | 基于箱线图:Q1 - 1.5×IQR 至 Q3 + 1.5×IQR | 1.5×IQR(温和异常) 3×IQR(极端异常) |
偏态分布,对极端值不敏感 |
| Z-Score | 基于正态分布:|Z| > 3 视为异常 | 通常 3 或 3.5 | 近似正态分布,样本量较大 |
| 业务阈值 | 基于领域知识设定硬边界 | 如年龄 18-100,收入 0-500万 | 所有场景,必须作为第一道防线 |
3.2.2 截断(Winsorization)操作
检测到异常值后,不删除样本,而是将异常值替换为阈值边界值。例如:将低于 Q1-1.5×IQR 的值设为 Q1-1.5×IQR,高于 Q3+1.5×IQR 的值设为 Q3+1.5×IQR。
# Python 示例:IQR 截断
import numpy as np
def iqr_cap(series, multiplier=1.5):
Q1 = series.quantile(0.25)
Q3 = series.quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - multiplier * IQR
upper_bound = Q3 + multiplier * IQR
return series.clip(lower=lower_bound, upper=upper_bound)
# 对收入列做 IQR 截断
df['income_capped'] = iqr_cap(df['income'], multiplier=1.5)
关键原则:在授信决策引擎中,业务阈值优先于统计阈值。例如,年龄字段若出现 0 或 200,应直接按业务规则截断,而非依赖 IQR 或 Z-Score。统计方法仅用于无明确业务边界的连续变量。
3.3 本章小结
- 缺失值处理:优先中位数填充(连续)和众数填充(分类);模型预测填充仅用于低缺失率的关键变量,且需防数据泄露。
- 异常值检测:业务阈值是必选项,IQR 适合偏态分布,Z-Score 适合正态分布。
- 截断而非删除:保留样本量,避免因删除异常值导致授信模型对极端客户失效。
- 工程落地:所有清洗步骤必须在特征工程流水线中固化,并在训练集和测试集上保持一致的参数。