4、数据清洗基础:缺失值处理、异常值检测、重复数据去重、噪声平滑

数据融合这件事,我做了快十年。说实话,最让我头疼的从来不是算法选型,也不是架构设计,而是——数据太脏了。

你想想看,多源数据从不同系统、不同格式、不同时间窗口汇聚过来,缺失、异常、重复、噪声几乎是家常便饭。我见过一个项目,80%的时间花在清洗上,真正建模只用了20%。所以这一章,咱们就把这四块硬骨头啃下来。

核心观点:数据清洗不是体力活,而是策略活。每一类脏数据都有对应的处理套路,选对了,事半功倍。

4.1 缺失值处理:别急着删

缺失值是最常见的问题。我个人习惯,拿到数据先看一眼缺失率。低于5%的,直接删除行,简单粗暴。但超过20%的,就得小心了——删除会损失大量信息。

我在项目中遇到过这样一个场景:某传感器数据缺失率达到40%,但业务方坚持要保留所有字段。怎么办?我用了多重插补法,把缺失值当成未知参数,用贝叶斯估计去填充。效果还不错,模型精度只下降了2%。

常用的缺失值处理方法,我整理了一张表:

方法 适用场景 缺点
删除行 缺失率 < 5%,随机缺失 样本量减少
均值/中位数填充 数值型,缺失率低 引入偏差
前向/后向填充 时间序列数据 不适合突变场景
KNN插补 特征间有相关性 计算量大
多重插补 缺失率高,非随机缺失 实现复杂

我的小技巧:对于时间序列数据,我一般先用前向填充,再检查一下填充后的序列是否平滑。如果出现阶梯状跳变,就改用线性插值。

4.2 异常值检测:别把宝贝当垃圾

异常值检测,说白了就是找那些「不对劲」的数据点。但什么算「不对劲」?这得看业务。

我记得有一次做金融风控,一个用户的交易金额突然暴涨100倍。模型直接把它标记为异常,准备删除。但我多看了一眼——原来是该用户卖了一套房。这哪是异常?这是正常的大额交易。

所以,我建议先做业务理解,再动手检测。常用的方法有:

  • 3σ原则:适用于正态分布的数据,超出均值±3倍标准差就算异常。
  • 箱线图法:用IQR(四分位距)判断,超出Q1-1.5IQR或Q3+1.5IQR就算异常。
  • 孤立森林:适合高维数据,随机切分,孤立点就是异常。
  • DBSCAN聚类:不在任何簇中的点,视为异常。

避坑指南:我曾经在某个项目中直接用3σ原则删除了所有异常值,结果模型在测试集上表现极差。后来发现,那些「异常值」其实是极端但真实的业务场景。所以,异常值不一定要删除,有时候需要单独建模处理。

4.3 重复数据去重:看似简单,实则暗藏玄机

重复数据去重,听起来很简单对吧?直接drop_duplicates()就完事了。但实际项目中,重复的定义往往很模糊。

比如,两个用户记录,姓名相同、地址相同,但手机号不同。算不算重复?这取决于你的业务主键是什么。我见过一个CRM系统,因为没处理好这种「半重复」数据,导致同一个客户被营销了三次,用户体验极差。

我的处理流程是这样的:

  1. 精确去重:所有字段完全一致,直接删除。
  2. 模糊去重:用编辑距离或Jaccard相似度,设定阈值(比如0.85),超过就算重复。
  3. 业务规则去重:比如同一身份证号、同一设备ID,视为同一实体。

代码示例(Python):

import pandas as pd
from fuzzywuzzy import fuzz

# 精确去重
df.drop_duplicates(inplace=True)

# 模糊去重:对"姓名"字段做相似度匹配
def fuzzy_dedup(df, col, threshold=85):
    duplicates = []
    for i in range(len(df)):
        for j in range(i+1, len(df)):
            score = fuzz.ratio(df.iloc[i][col], df.iloc[j][col])
            if score >= threshold:
                duplicates.append(j)
    return df.drop(duplicates)

df_clean = fuzzy_dedup(df, 'name', threshold=85)

经验之谈:模糊去重计算量很大,数据量超过10万行时,建议先用Blocking技术(比如按姓氏首字母分组),再在组内做相似度计算。

4.4 噪声平滑:让数据「安静」下来

噪声,说白了就是数据里的毛刺。传感器采集的数据尤其明显,一个抖动就能让曲线变得锯齿状。平滑的目的,就是去掉这些毛刺,保留趋势。

我常用的平滑方法:

  • 移动平均:简单,但会引入滞后。窗口大小选3-5比较稳妥。
  • 指数加权平均:给近期数据更高权重,滞后更小。
  • Savitzky-Golay滤波:用多项式拟合局部窗口,保留峰形效果很好。
  • 小波去噪:适合非平稳信号,但参数调起来比较麻烦。

举个例子,某温度传感器数据,原始信号噪声很大。我用移动平均(窗口=5)处理后,曲线平滑了,但峰值被削平了。后来换成Savitzky-Golay滤波(窗口=7,阶数=3),既去除了噪声,又保留了温度突变的细节。

核心原则:平滑不是越光滑越好。过度平滑会丢失信息,欠平滑又去不掉噪声。我的经验是——先做一次轻度平滑,然后对比原始数据,看看趋势是否保留。

知识体系总览

下面这张图,是我自己梳理的数据清洗知识体系。你可以把它当成一张地图,遇到具体问题时,按图索骥就好。

数据清洗基础 缺失值处理 删除行 / 均值填充 前向填充 / KNN插补 多重插补 异常值检测 3σ原则 / 箱线图法 孤立森林 / DBSCAN 业务规则判断 重复数据去重 精确去重 模糊去重(编辑距离) 业务规则去重 噪声平滑 移动平均 / 指数加权 Savitzky-Golay / 小波 核心原则:先理解业务,再选择方法。没有万能方案,只有最适合的方案。

嗯,这一章的内容就到这里。数据清洗看起来琐碎,但它是整个数据融合流程的基石。你想想看,如果输入的数据都是脏的,再牛的算法也白搭。所以,别嫌麻烦,把每一步做扎实了,后面的工作才会顺畅。