4. 数据预处理:缺失值处理、异常值处理、类别变量编码、数据标准化/归一化

在额度定价漂移检测任务中,原始数据通常包含缺失值、异常值、非数值型类别特征以及量纲差异较大的数值特征。这些“脏数据”会直接影响漂移检测模型的稳定性和准确性。本章将系统讲解数据预处理的四个核心环节,确保输入模型的数据干净、规范、可比。

4.1 缺失值处理

缺失值在信贷数据中十分常见,例如客户收入字段未填写、历史额度字段为空等。处理策略需根据缺失比例和业务含义选择。

缺失比例 推荐策略 适用场景
< 5% 删除缺失行 样本量充足,缺失随机
5% – 30% 均值/中位数/众数填充 数值型用中位数(抗异常值),类别型用众数
30% – 60% 模型预测填充(KNN/回归) 字段与其他特征相关性较强
> 60% 删除该特征列 信息量过低,保留反而引入噪声
实践建议:在额度定价场景中,收入字段缺失常采用中位数填充,避免极端值拉高均值;而“历史逾期天数”若缺失,可视为“无逾期”用 0 填充,但需单独标记缺失指示列。
import pandas as pd
import numpy as np

# 示例:中位数填充数值列,众数填充类别列
df['income'].fillna(df['income'].median(), inplace=True)
df['education'].fillna(df['education'].mode()[0], inplace=True)

# 标记缺失指示列
df['income_missing'] = df['income'].isna().astype(int)

4.2 异常值处理

异常值会扭曲统计分布,导致漂移检测产生误报。常用检测方法包括 IQR 规则和 Z-Score 方法。

  • IQR 规则:定义 Q1 – 1.5×IQR 到 Q3 + 1.5×IQR 为正常范围,超出视为异常。
  • Z-Score 方法:|Z| > 3 的样本视为异常(适用于近似正态分布)。
注意:在额度定价场景中,不要直接删除异常值。例如“年收入 500 万”对普通产品是异常,但对高端客户可能是真实值。建议先做业务研判,再决定截尾、替换或保留。
# IQR 方法检测异常值
Q1 = df['loan_amount'].quantile(0.25)
Q3 = df['loan_amount'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR

# 将异常值替换为边界值(截尾处理)
df['loan_amount'] = df['loan_amount'].clip(lower_bound, upper_bound)

4.3 类别变量编码

机器学习模型无法直接处理文本型类别变量,需要转换为数值形式。不同编码方式适用于不同数据类型。

编码方式 适用变量 特点
Label Encoding 有序类别(如教育等级) 保留顺序信息,但可能引入虚假大小关系
One-Hot Encoding 无序类别(如职业、地区) 避免顺序假设,但维度膨胀
Target Encoding 高基数类别(如城市代码) 用目标变量均值编码,需防过拟合
from sklearn.preprocessing import LabelEncoder, OneHotEncoder

# Label Encoding 用于有序变量
le = LabelEncoder()
df['education_level'] = le.fit_transform(df['education'])

# One-Hot Encoding 用于无序变量
df = pd.get_dummies(df, columns=['occupation'], drop_first=True)
漂移检测特别提示:One-Hot 编码后,每个虚拟变量都会独立参与漂移检测。如果原始类别有 50 个,编码后会产生 49 列,建议先合并低频类别(如占比 < 1% 的归为“其他”),再编码。

4.4 数据标准化与归一化

标准化和归一化用于消除量纲影响,使不同尺度的特征在漂移检测中具有可比性。两者适用场景不同。

方法 公式 输出范围 适用场景
Z-Score 标准化 \( z = \frac{x - \mu}{\sigma} \) 均值 0,标准差 1 数据近似正态分布,或使用距离度量
Min-Max 归一化 \( x' = \frac{x - min}{max - min} \) [0, 1] 数据有明确边界,或使用梯度下降算法
from sklearn.preprocessing import StandardScaler, MinMaxScaler

# Z-Score 标准化
scaler_std = StandardScaler()
df[['income', 'loan_amount']] = scaler_std.fit_transform(df[['income', 'loan_amount']])

# Min-Max 归一化
scaler_mm = MinMaxScaler()
df[['age', 'credit_score']] = scaler_mm.fit_transform(df[['age', 'credit_score']])
漂移检测场景建议:如果后续使用基于距离的漂移检测方法(如 MMD、KS 检验),推荐使用 Z-Score 标准化;如果使用基于分箱的 PSI 方法,Min-Max 归一化更便于分箱对齐。

4.5 数据预处理完整流程

下图展示了从原始数据到建模就绪数据的完整预处理流水线,四个环节按顺序执行,每个环节的输出作为下一环节的输入。

数据预处理完整流水线 原始数据 缺失值处理 异常值处理 类别变量编码 标准化/归一化 建模就绪数据 顺序不可颠倒 异常值影响标准化

4.6 预处理前后对比示例

以下表格展示一条样本在预处理前后的变化,直观感受数据清洗的效果。

字段 原始值 处理后值 处理方式
income NaN 58000.0 中位数填充
loan_amount 9999999 250000.0 IQR 截尾
education 本科 2 Label Encoding
occupation 工程师 [0, 0, 1, 0] One-Hot Encoding
age 45 0.52 Min-Max 归一化
credit_score 720 0.68 Z-Score 标准化
关键原则:预处理参数(填充值、边界值、缩放参数)必须在训练集上拟合,然后应用到验证集和测试集,避免数据泄露。建议使用 sklearn.pipeline.Pipeline 封装整个预处理流程。