数据预处理基础:缺失值处理、异常值检测与处理、数据标准化与归一化、数据离散化

数据预处理是特征筛选前的关键步骤,直接影响后续模型训练的质量。原始数据通常包含缺失值、异常值,且各特征量纲不一致,若不处理会导致模型偏差或收敛困难。本节系统梳理四大预处理环节的核心方法与避坑要点。

2.1 缺失值处理

缺失值处理需根据缺失机制和数据特性选择策略,常见方法如下:

方法 适用场景 注意事项
删除(行/列) 缺失比例 < 5%,且随机缺失 避免删除过多导致样本量不足
均值/中位数填充 数值型特征,分布较对称 会降低方差,影响模型区分度
众数填充 分类型特征 可能引入偏差,尤其类别不均衡时
前向/后向填充 时间序列数据 需确保时间顺序正确
模型预测填充 缺失比例较高,特征间关联强 计算成本高,需防止过拟合
KNN 填充 数值型特征,样本量适中 K 值选择敏感,距离计算受量纲影响
避坑提示: 缺失值处理前务必分析缺失机制(MCAR/MAR/MNAR)。若为 MNAR(非随机缺失),直接填充会引入系统性偏差,建议结合业务逻辑单独处理。
# 使用 pandas 进行缺失值处理示例
import pandas as pd
import numpy as np

# 创建示例数据
df = pd.DataFrame({
    'age': [25, np.nan, 30, 35, np.nan, 28],
    'income': [50000, 60000, np.nan, 70000, 65000, 72000],
    'gender': ['M', 'F', 'F', np.nan, 'M', 'F']
})

# 查看缺失比例
print(df.isnull().mean())

# 数值型:中位数填充
df['age'] = df['age'].fillna(df['age'].median())
df['income'] = df['income'].fillna(df['income'].median())

# 分类型:众数填充
df['gender'] = df['gender'].fillna(df['gender'].mode()[0])

2.2 异常值检测与处理

异常值会扭曲统计量、影响模型拟合。常用检测方法包括统计法、距离法和模型法。

核心原则: 异常值 ≠ 错误值。需结合业务判断是否剔除、修正或保留。例如,信用卡欺诈中的大额交易本身就是目标信号。

常用检测方法对比

方法 原理 适用场景 局限性
Z-Score |Z| > 3 视为异常 近似正态分布 对非正态分布不敏感
IQR 四分位距 Q1 - 1.5*IQR 或 Q3 + 1.5*IQR 之外 偏态分布,稳健 阈值固定,可能漏检
DBSCAN 聚类 不在任何核心簇内的点 高维数据,簇形状复杂 参数 eps 和 min_samples 敏感
孤立森林 基于树模型隔离异常点 高维、大规模数据 对局部异常不敏感
# IQR 方法检测异常值
def detect_outliers_iqr(data, column):
    Q1 = data[column].quantile(0.25)
    Q3 = data[column].quantile(0.75)
    IQR = Q3 - Q1
    lower_bound = Q1 - 1.5 * IQR
    upper_bound = Q3 + 1.5 * IQR
    outliers = data[(data[column] < lower_bound) | (data[column] > upper_bound)]
    return outliers

# 示例
outliers_df = detect_outliers_iqr(df, 'income')
print(f"检测到 {len(outliers_df)} 个异常值")
常见误区: 不要对异常值直接做截尾处理(Winsorization)而不记录处理比例。若异常值占比超过 5%,说明数据分布本身存在长尾,建议考虑对数变换或分箱处理。

2.3 数据标准化与归一化

标准化和归一化解决特征量纲不一致问题,避免大数值特征主导模型训练。两者适用场景不同,需根据模型类型选择。

方法 公式 输出范围 适用模型
Z-Score 标准化 z = (x - μ) / σ 均值 0,标准差 1 SVM、线性回归、PCA、神经网络
Min-Max 归一化 x' = (x - min) / (max - min) [0, 1] KNN、神经网络(输入层)
Robust 缩放 x' = (x - median) / IQR 无固定范围 含异常值的数据
MaxAbs 缩放 x' = x / |max| [-1, 1] 稀疏数据
避坑提示: 标准化/归一化的参数(均值、标准差、min、max)必须从训练集计算,再应用到验证集和测试集。切勿对整个数据集统一计算,否则会造成数据泄露。
from sklearn.preprocessing import StandardScaler, MinMaxScaler

# 训练集拟合,转换训练集和测试集
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)  # 使用训练集的参数

# Min-Max 归一化
minmax_scaler = MinMaxScaler()
X_train_norm = minmax_scaler.fit_transform(X_train)
X_test_norm = minmax_scaler.transform(X_test)

2.4 数据离散化

离散化将连续特征转换为分类特征,可增强模型鲁棒性、降低过拟合风险,尤其适用于线性模型和决策树。

离散化方法对比

方法 策略 优点 缺点
等宽分箱 按值域等距划分 实现简单,直观 数据分布不均时箱内样本差异大
等频分箱 按分位数划分,每箱样本数相同 每箱样本均衡 可能将相近值分到不同箱
聚类分箱 使用 KMeans 聚类后分配箱标签 适应数据自然分布 K 值选择依赖经验
决策树分箱 用目标变量监督划分切分点 与目标变量关联强 易过拟合,需控制树深度
# 等频分箱示例
import pandas as pd

data = pd.Series([12, 15, 23, 24, 30, 35, 40, 45, 50, 60])
# 等频分箱为 3 箱
bins = pd.qcut(data, q=3, labels=['低', '中', '高'])
print(bins)
离散化避坑: 分箱数量不宜过多(通常 3~10 箱),否则失去离散化意义。等宽分箱对异常值敏感,建议先处理异常值再分箱。决策树分箱需在训练集上拟合切分点,避免在测试集上重新分箱。

2.5 预处理流程总览

下图展示数据预处理的标准流程及各环节的衔接关系:

数据预处理标准流程 数据预处理标准流程 原始数据 缺失值处理 异常值检测与处理 分支 标准化 / 归一化 数据离散化 预处理后数据 标准化与离散化 根据模型类型二选一
流程要点: 缺失值处理和异常值检测通常在前两步完成,标准化/归一化与离散化是互斥的预处理路径——树模型(如随机森林、XGBoost)对量纲不敏感,通常不需要标准化;而线性模型、SVM、神经网络则必须进行标准化。离散化更适合线性模型或需要可解释性的场景。