3. 数据预处理基础:缺失值处理、异常值检测与标准化

在催收触达特征工程中,原始数据通常包含大量不完整、异常或量纲不一致的记录。直接使用这些数据建模会导致模型偏差、收敛缓慢甚至失效。本章系统讲解数据预处理的三大核心环节:缺失值处理、异常值检测与处理、数据标准化与归一化,并结合催收场景给出具体操作指南。

3.1 缺失值处理

催收数据中缺失值常见原因包括:客户未填写、系统采集故障、数据源合并遗漏等。缺失值处理策略分为删除、填充和模型预测三类,需根据缺失率、特征重要性及业务含义选择。

策略 适用场景 催收案例 注意事项
删除 缺失率 > 70% 或缺失完全随机 客户“第二联系人电话”缺失率 85% 删除后样本量仍充足;避免删除关键特征
统计填充 缺失率 < 30%,特征分布稳定 “近3月逾期天数”用中位数填充 均值受异常值影响大,优先用中位数/众数
模型预测 缺失率 10%~50%,特征间关联强 用“收入”“职业”预测“可支配收入”缺失值 避免信息泄露;需交叉验证评估预测误差
催收场景提示: 对于“历史催收次数”这类关键特征,即使缺失率仅 5%,也建议使用模型预测填充,避免删除或简单填充导致模型对高逾期客户识别能力下降。

3.1.1 删除策略

直接删除缺失记录或特征,适用于缺失率极高或缺失完全随机的场景。在 Python 中可通过 dropna() 实现。

import pandas as pd

# 删除缺失率超过 70% 的特征
df = df.loc[:, df.isnull().mean() < 0.7]

# 删除缺失值超过 3 个的样本
df = df.dropna(thresh=df.shape[1] - 3)

3.1.2 填充策略

根据特征分布选择填充值:连续型特征用中位数或均值,离散型特征用众数或“未知”类别。填充后建议增加“是否缺失”指示列。

# 中位数填充连续特征
df['逾期天数'] = df['逾期天数'].fillna(df['逾期天数'].median())

# 众数填充离散特征
df['职业类型'] = df['职业类型'].fillna(df['职业类型'].mode()[0])

# 增加缺失指示列
df['逾期天数_missing'] = df['逾期天数'].isnull().astype(int)

3.1.3 模型预测填充

利用非缺失特征构建回归或分类模型,预测缺失值。常用算法包括 KNN、随机森林、线性回归。需注意避免目标变量泄露。

from sklearn.ensemble import RandomForestRegressor

# 分离缺失与非缺失样本
train = df[df['可支配收入'].notna()]
test = df[df['可支配收入'].isna()]

# 特征与目标
features = ['年龄', '收入', '职业编码', '历史还款次数']
X_train = train[features]
y_train = train['可支配收入']
X_test = test[features]

# 训练预测
model = RandomForestRegressor(n_estimators=100)
model.fit(X_train, y_train)
df.loc[df['可支配收入'].isna(), '可支配收入'] = model.predict(X_test)
避坑提醒: 模型预测填充时,务必确保训练集和测试集来自同一分布,且预测特征中不包含与目标变量高度相关的未来信息(如“是否已还款”),否则会造成数据泄露。

3.2 异常值检测与处理

催收数据中的异常值可能源于录入错误、系统故障或极端客户行为。异常值会拉偏模型参数,需通过统计方法识别并处理。常用方法包括 IQR 和 Z-score。

核心原则: 异常值 ≠ 错误值。催收场景中,高逾期天数、高负债率等“异常”可能正是模型需要捕捉的风险信号。处理前需结合业务判断是否保留。

3.2.1 IQR 方法(四分位距法)

适用于非正态分布数据。定义下界为 Q1 - 1.5×IQR,上界为 Q3 + 1.5×IQR,超出范围视为异常。

Q1 = df['逾期天数'].quantile(0.25)
Q3 = df['逾期天数'].quantile(0.75)
IQR = Q3 - Q1

lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR

# 标记异常
df['逾期天数_异常'] = ((df['逾期天数'] < lower_bound) | (df['逾期天数'] > upper_bound)).astype(int)

3.2.2 Z-score 方法

适用于近似正态分布数据。计算每个样本的 Z 分数,通常 |Z| > 3 视为异常。

from scipy import stats

z_scores = stats.zscore(df['负债率'])
df['负债率_异常'] = (abs(z_scores) > 3).astype(int)
方法 适用分布 阈值 催收场景示例
IQR 偏态分布、有离群点 1.5×IQR “逾期天数”右偏严重,IQR 更稳健
Z-score 近似正态分布 |Z| > 3 “年龄”近似正态,Z-score 更合适

3.2.3 异常值处理策略

  • 截尾(Capping): 将异常值替换为边界值(Q3+1.5×IQR 或 Q1-1.5×IQR),保留样本量。
  • 删除: 确认是录入错误且样本量充足时直接删除。
  • 单独标记: 保留原始值,增加“是否异常”指示列,让模型自行学习。
# 截尾处理
df['逾期天数'] = df['逾期天数'].clip(lower=lower_bound, upper=upper_bound)

# 单独标记(保留原始值)
df['逾期天数_异常标记'] = ((df['逾期天数'] < lower_bound) | (df['逾期天数'] > upper_bound)).astype(int)
催收场景建议: 对于“历史逾期次数”“最大逾期天数”等风险特征,建议优先使用截尾或单独标记,避免删除极端高风险样本导致模型对高逾期客户识别不足。
异常值检测与处理流程 原始催收数据 选择检测方法 IQR 方法(偏态分布) Z-score 方法(正态分布) 处理策略:截尾 / 删除 / 单独标记 清洗后特征

3.3 数据标准化与归一化

催收特征量纲差异巨大(如“年龄”0~100 vs “逾期金额”0~100000),直接输入模型会导致梯度下降震荡、距离度量失效。标准化和归一化是消除量纲影响的两种主要方法。

方法 公式 输出范围 适用模型
Z-score 标准化 z = (x - μ) / σ 均值 0,标准差 1 线性回归、SVM、PCA、神经网络
Min-Max 归一化 x' = (x - min) / (max - min) [0, 1] KNN、神经网络、梯度下降类模型
Robust 缩放 x' = (x - median) / IQR 受异常值影响小 含异常值的催收数据

3.3.1 Z-score 标准化

将数据转换为均值为 0、标准差为 1 的分布,适用于数据近似正态分布的场景。在 sklearn 中通过 StandardScaler 实现。

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
df[['逾期天数', '负债率', '收入']] = scaler.fit_transform(df[['逾期天数', '负债率', '收入']])

3.3.2 Min-Max 归一化

将数据线性映射到 [0, 1] 区间,适用于有明确边界且无极端异常值的特征。注意:新数据超出原范围时需重新计算。

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()
df[['年龄', '历史还款次数']] = scaler.fit_transform(df[['年龄', '历史还款次数']])

3.3.3 Robust 缩放

使用中位数和 IQR 代替均值和标准差,对异常值不敏感,适合催收数据中常含极端值的场景。

from sklearn.preprocessing import RobustScaler

scaler = RobustScaler()
df[['逾期金额', '催收次数']] = scaler.fit_transform(df[['逾期金额', '催收次数']])
关键提醒: 标准化/归一化必须在训练集上拟合参数(μ、σ、min、max 等),然后用同一参数转换验证集和测试集,避免数据泄露。切勿对全量数据统一 fit_transform。
标准化与归一化方法对比 原始特征(不同量纲) Z-score 标准化 z = (x - μ) / σ Min-Max 归一化 x' = (x - min) / (max - min) Robust 缩放 x' = (x - median) / IQR 均值 0,标准差 1 映射到 [0, 1] 区间 对异常值鲁棒 无量纲化特征

3.4 本章小结

  • 缺失值处理: 根据缺失率选择删除、填充或模型预测;填充后建议增加缺失指示列。
  • 异常值检测: IQR 适用于偏态分布,Z-score 适用于正态分布;处理时优先截尾或单独标记,避免丢失高风险样本。
  • 标准化与归一化: Z-score 标准化、Min-Max 归一化、Robust 缩放各有适用场景;必须在训练集上拟合参数,再转换验证/测试集。
  • 催收场景要点: 异常值可能包含风险信号,处理前需结合业务判断;Robust 缩放对含异常值的催收数据更稳健。