数据预处理基础:缺失值处理、异常值检测、数据标准化与归一化
在可解释性建模中,数据预处理是决定模型质量与稳定性的基石。原始数据通常包含缺失值、异常值以及量纲不一致的问题,若不经处理直接建模,会导致模型偏倚、过拟合或解释性失真。本节系统梳理三大预处理任务的核心方法与适用场景。
1. 缺失值处理
缺失值产生的原因包括设备故障、用户未填写、数据合并错位等。处理策略分为删除、填充与模型预测三类,选择依据为缺失比例、缺失机制(MCAR/MAR/MNAR)及业务含义。
| 策略 | 方法 | 适用场景 | 注意事项 |
|---|---|---|---|
| 删除 | 行删除、列删除 | 缺失比例 < 5%,且随机缺失 | 可能损失样本量,导致偏差 |
| 固定值填充 | 均值、中位数、众数、常数 | 数值型或有序型变量 | 均值填充会降低方差,影响分布 |
| 模型预测填充 | KNN、回归、随机森林 | 缺失变量与其他变量相关性较强 | 计算成本高,需避免数据泄露 |
| 插值法 | 线性插值、时间序列插值 | 时间序列或有序数据 | 对非线性趋势可能不准确 |
| 标记法 | 新增“是否缺失”指示列 | 缺失本身具有业务信息 | 增加特征维度,需配合填充使用 |
可解释性提示:在风控或医疗建模中,缺失本身常携带信息(如用户未填写收入可能暗示高风险)。建议对关键变量同时使用填充值 + 缺失指示列,保留缺失模式的可解释性。
2. 异常值检测
异常值指显著偏离正常分布的数据点,可能由录入错误、设备故障或真实极端事件引起。检测方法需结合数据分布与业务阈值。
常用检测方法对比
| 方法 | 原理 | 适用分布 | 阈值设定 |
|---|---|---|---|
| Z-Score | 基于均值与标准差 | 近似正态分布 | |Z| > 3 |
| IQR(四分位距) | 基于中位数与四分位数 | 偏态分布、含离群点 | Q1 - 1.5×IQR 或 Q3 + 1.5×IQR |
| DBSCAN | 基于密度聚类 | 任意形状分布 | eps 与 minPts 参数 |
| 孤立森林 | 随机切割,异常点易被孤立 | 高维数据 | 异常分数阈值 |
避坑提醒:不要对异常值一律删除。在欺诈检测、设备故障诊断等场景中,异常值往往是建模目标本身。建议先标记、再分箱或单独建模,保留其业务解释性。
3. 数据标准化与归一化
不同量纲的变量会主导距离计算与梯度更新,标准化与归一化是消除量纲影响的两种核心手段。选择依据为数据分布与后续模型要求。
| 方法 | 公式 | 输出范围 | 适用模型 |
|---|---|---|---|
| Z-Score 标准化 | \( x' = \frac{x - \mu}{\sigma} \) | 均值0,标准差1 | 线性回归、SVM、PCA、聚类 |
| Min-Max 归一化 | \( x' = \frac{x - \min}{\max - \min} \) | [0, 1] | 神经网络、KNN、图像数据 |
| Robust 缩放 | \( x' = \frac{x - \text{median}}{\text{IQR}} \) | 受异常值影响小 | 含异常值的数据 |
| MaxAbs 缩放 | \( x' = \frac{x}{\max|x|} \) | [-1, 1] | 稀疏数据 |
可解释性建模建议:对于树模型(决策树、随机森林、XGBoost),标准化不影响分裂点选择,通常不需要。但对于线性模型、距离模型和神经网络,标准化是强制步骤。在分箱前,建议先对连续变量做标准化,使分箱边界具有可比性。
4. 预处理流程架构
下图展示数据预处理的标准流程,从原始数据到可用于建模的干净数据集,各步骤之间可能存在反馈循环。
5. 代码示例:Python 实现
以下代码展示使用 scikit-learn 完成标准化与缺失值填充的典型操作,适用于后续分箱与建模。
import pandas as pd
import numpy as np
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler, MinMaxScaler
# 示例数据
data = pd.DataFrame({
'age': [25, 30, np.nan, 35, 40, 28],
'income': [50000, 60000, 55000, np.nan, 80000, 48000],
'score': [0.8, 0.6, 0.9, 0.7, np.nan, 0.85]
})
print("原始数据:\n", data)
# 1. 缺失值填充:中位数填充
imputer = SimpleImputer(strategy='median')
data_filled = pd.DataFrame(imputer.fit_transform(data), columns=data.columns)
print("\n填充后数据:\n", data_filled)
# 2. 标准化:Z-Score
scaler = StandardScaler()
data_scaled = pd.DataFrame(scaler.fit_transform(data_filled), columns=data.columns)
print("\n标准化后数据(均值0,标准差1):\n", data_scaled.round(3))
# 3. 归一化:Min-Max
minmax = MinMaxScaler()
data_normalized = pd.DataFrame(minmax.fit_transform(data_filled), columns=data.columns)
print("\n归一化后数据(范围[0,1]):\n", data_normalized.round(3))
6. 预处理策略选择矩阵
下表帮助根据数据特征与建模目标快速选择预处理组合。
| 数据特征 | 缺失值策略 | 异常值策略 | 缩放策略 | 典型模型 |
|---|---|---|---|---|
| 正态分布、无异常值 | 均值填充 | Z-Score 截断 | Z-Score 标准化 | 线性回归、LDA |
| 偏态分布、有异常值 | 中位数填充 | IQR 截断或 Winsorize | Robust 缩放 | 逻辑回归、SVM |
| 稀疏数据(如文本TF-IDF) | 0值填充 | 保留或单独标记 | MaxAbs 缩放 | 朴素贝叶斯、线性SVM |
| 时间序列 | 线性插值 | 滑动窗口检测 | 差分或Z-Score | ARIMA、LSTM |
| 树模型(RF、XGBoost) | 不处理或标记法 | 保留或分箱 | 不需要 | 随机森林、XGBoost |
核心原则:预处理策略的选择直接影响模型的可解释性。建议在变量衍生与分箱之前,先对每个连续变量进行缺失率统计、分布可视化与异常值标记,形成预处理报告,作为后续建模决策的依据。