数据清洗与预处理

数据清洗这项工作,说白了就是给原始数据「洗澡」。我见过太多团队,模型怎么调都不收敛,最后发现是特征里藏着各种垃圾。今天咱们就聊聊缺失值、异常值、重复数据这三座大山。

数据清洗与预处理流程 原始数据 缺失值处理 异常值检测 数据去重 一致性检查 清洗后数据 缺失值→异常值→去重→一致性,四步环环相扣,顺序不能乱

缺失值处理:别让空洞毁了模型

我最开始做特征工程时,以为缺失值就是简单的「扔掉」或者「填个平均值」。直到在一次风控项目中,特征缺失模式直接暴露了数据采集漏洞——嗯,从那以后我再也不随便填数了。

判断缺失类型

  • 完全随机缺失 (MCAR):缺失与任何变量无关。可以直接删除或简单填充。
  • 随机缺失 (MAR):缺失与其他观测变量有关。需要用模型预测填充。
  • 非随机缺失 (MNAR):缺失与缺失值本身有关。最棘手,必须了解业务背景。

我个人习惯先画一张缺失热力图——用 missingno 库几行代码就能看出缺失模式。如果是MCAR且缺失率低于5%,直接删行通常没问题;但超过20%,就要小心了。

常用填充策略

方法适用场景注意事项
均值/中位数填充数值型、低缺失率会降低方差,影响模型区分度
众数填充分类型如果众数占比太高,可能引入偏差
前向/后向填充时间序列注意时间窗口边界处理
KNN填充中小数据集计算量随样本数平方增长
模型预测填充缺失与其他特征强相关防止过拟合,需要用交叉验证
import pandas as pd
from sklearn.impute import KNNImputer

# 我常用的KNN填充
imputer = KNNImputer(n_neighbors=5, weights='distance')
df_imputed = pd.DataFrame(imputer.fit_transform(df), columns=df.columns)

千万不要在填充前做特征缩放!标准差会被填充值拉偏。我曾经踩过这个坑,导致模型训练时loss死活下不去。

异常值检测与修正:一粒老鼠屎坏一锅粥

异常值不只是「大数」或「小数」,还包括不合逻辑的组合。比如年龄=200,或者性别=3。你想想看,这些数据喂进模型,梯度下降直接迷路。

检测方法对比

方法原理最佳使用场景
Z-Score计算偏离均值的标准差倍数数据近似正态分布
IQR(四分位距)Q1-1.5*IQR 和 Q3+1.5*IQR 之外偏态分布或含有大量离群点
Isolation Forest随机切割,孤立点更容易被切出高维数据,特征数>10
DBSCAN密度聚类,低密度点为异常空间数据或地理坐标
import numpy as np
from scipy import stats

# Z-Score 检测:以3倍标准差为阈值
z_scores = np.abs(stats.zscore(df['column']))
outliers = np.where(z_scores > 3)
print(f"检测到 {len(outliers[0])} 个异常值")

修正策略

  • 截断(Winsorization):将异常值限制在99%分位数以内。我在电商价格特征里经常用。
  • 模型预测替换:用正常值训练回归模型,预测异常点应取值。
  • 标记为缺失:先标记再走缺失值处理流程。

曾经有个客户数据集里用户年龄列有大量999。用IQR一查,999离中位数远了40个IQR……直接标记为缺失,然后用KNN填充,最终模型AUC提升了3%。

数据去重与一致性检查

重复数据比缺失数据更隐蔽。我见过一个项目,模型性能很好,但上线后发现预测结果毫无价值——原因就是训练集里90%都是重复样本。你想想看,模型学会了「背答案」,哪来的泛化能力?

去重三步走

  1. 完全去重:所有字段完全一致,直接删除多余行。
  2. 部分去重:关键字段一致(比如用户ID+时间戳),但其他字段略有差异——需要聚合或保留最新记录。
  3. 近似去重:使用SimHash、MinHash等算法检测文本相似度,例如评论数据中的刷帖。
# 完全去重
df.drop_duplicates(inplace=True)

# 部分去重:保留每个用户的最新记录
df.sort_values('timestamp').drop_duplicates(subset=['user_id'], keep='last')

一致性检查清单

检查项示例处理方法
数据范围性别字段出现'M'、'F'、'男'、'女'、'1'统一编码映射
单位统一部分记录是米,部分是厘米全部转换为同一单位
时间格式2024-01-01 和 01/01/2024使用pandas.to_datetime统一格式
逻辑约束订单日期 > 发货日期标记异常或修正
编码一致性省份名称拼写错误("四川" vs "四州")建立标准字典模糊匹配

我建议每个数据集开始时都跑一个「数据质量报告」:统计缺失率、唯一值数、最大值最小值、常见脏数据。pandas-profiling(现ydata-profiling)能一键生成,省时省力。

数据清洗没有一招鲜。但你只要把缺失、异常、重复、一致这四个关口把好,后续的特征工程会顺很多。别急,一步一个坑踩过来,模型自然就稳了。