数据预处理:数据清洗、缺失值处理、数据标准化与归一化

说实话,很多初学者觉得数据预处理不如调模型酷。我一开始也这么想。直到有一次我在做金融风控的异常访问识别,原始数据里全是重复请求、缺失的 IP 字段、还有时间戳格式混乱……模型训练出来准确率只有 40%。

后来我把数据清洗了一遍,准确率直接跳到 85%。那次之后我才真正明白——数据预处理不是杂活,而是模型的基石。咱们这章就把这块讲透。

数据清洗:先把脏数据筛出来

数据清洗说白了就是“去脏”。我见过的脏数据大概分三类:

  • 重复记录——同一个用户一秒内发 100 次请求
  • 异常值——比如年龄字段出现 999,或者时间戳是 1970 年
  • 格式不一致——“2023-01-01”和“01/01/2023”混在一起

怎么处理?我的习惯是三步走:

  1. 先用 describe() 看数值分布,找到异常值区间
  2. 用 duplicated() 检查重复,直接 drop
  3. 最后一招——画箱线图,肉眼扫一遍

小经验: 我曾在日志数据里发现一条“访问时间=2100年”的记录。后来发现是服务器时钟漂移造成的。这种明显异常值直接删掉就好,别纠结。

# 快速去重 & 异常值过滤
import pandas as pd

df = pd.read_csv('access_log.csv')
# 去重
df = df.drop_duplicates()
# 过滤异常时间(假设时间戳单位是秒,合理范围是 1e9~2e9)
df = df[(df['timestamp'] > 1e9) & (df['timestamp'] < 2e9)]

缺失值处理:别急着删

缺失值很常见。你猜怎么着?我第一次处理缺失值就想省事,直接 dropna()。结果样本量少了 30%,模型直接欠拟合了。

所以我现在会用这几种策略:

方法 适用场景 缺点
直接删除 缺失率 < 5%,且随机缺失 损失样本量
均值/中位数填充 连续数值型,分布不太偏 可能引入偏差
前向/后向填充 时间序列数据 不适合非时序
插值法(线性/多项式) 数据有趋势或规律 计算成本高
模型预测填充 缺失值很重要,不能随意填 可能过拟合

注意: 我曾经在一个用户画像数据里用均值填充“收入”字段,结果把低收入群体和高收入群体混在一起,聚类结果完全失真。后来改用中位数填充,效果好了很多。嗯,遇到偏态分布,中位数比均值靠谱。

# 缺失值处理示例
# 数值列用中位数填充
for col in ['visit_count', 'session_duration']:
    median_val = df[col].median()
    df[col].fillna(median_val, inplace=True)

# 类别列用众数填充
df['device_type'].fillna(df['device_type'].mode()[0], inplace=True)

数据标准化与归一化:让特征在同一起跑线

想想看——如果“访问次数”的范围是 0~1000,而“页面停留时长”是 0~10 秒。直接扔进模型,访问次数的权重会被放大。这不合理。

解决办法就是标准化或归一化。我个人偏好这两种:

  • Z-score 标准化:将数据变为均值为0、标准差为1的分布。适合数据近似正态,或有异常值的情况。
  • Min-Max 归一化:将数据压缩到 [0,1] 区间。适合数据有明确边界,且分布均匀的情况。
方法 公式 优点 缺点
Z-score \( x' = \frac{x - \mu}{\sigma} \) 对异常值鲁棒 不保证在固定区间
Min-Max \( x' = \frac{x - \min}{\max - \min} \) 有界稳定 受异常值影响大

我一般怎么选?如果是决策树/随机森林这类树模型,其实不需要标准化。但如果是 SVM、KNN、神经网络——必须标准化,否则距离计算会出大问题。

# 标准化与归一化代码
from sklearn.preprocessing import StandardScaler, MinMaxScaler

# Z-score 标准化
scaler = StandardScaler()
df_scaled = scaler.fit_transform(df[['visit_count', 'session_duration']])

# Min-Max 归一化
minmax = MinMaxScaler()
df_norm = minmax.fit_transform(df[['visit_count', 'session_duration']])

整个流程串起来——一张图说清

下面这张图把咱们这章的核心流程串在一起。你看到红线就是“坏数据走左边”,绿线是“好数据继续往下走”。

数据预处理流程框架 原始访问日志 数据清洗 去重/异常过滤 格式统一 缺失值处理 删除/填充 插值/模型预测 标准化/归一化 Z-score 均值为0,标准差1 Min-Max 缩放到[0,1] 清洗后的标准数据集 送入模型训练 说明:每个分支都是可选步骤 根据数据质量灵活选择

实战选择策略——我的经验总结

讲到这里,你可能会问:“这么多方法,到底选哪个?”

我一般按这个优先级来:

  1. 先看数据类型。 数值型用标准化或归一化,类别型用 one-hot 或 label encoding。
  2. 再看分布。 如果数据是长尾分布,优先用中位数填充缺失值,Min-Max 归一化要谨慎。
  3. 最后看模型。 树模型不敏感,就直接跳过标准化。否则一定做。

我做过一个实验:在异常访问检测的 KNN 模型上,未标准化的准确率是 62%,标准化后直接到 79%。你不妨也跑一下试试,效果立竿见影。

嗯,这章就先到这儿。数据预处理这块看着琐碎,但做扎实了,后面的建模会非常顺畅。你上手的时候,记得先花 20% 的时间去看数据质量——这 20% 往往能省掉后面 80% 的返工。就这样,咱们继续往下。