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

大家好,我是你们的老朋友。今天咱们聊聊数据预处理。

说实话,很多刚入行的同学觉得建模就是调参、选算法。但我得说句大实话:数据预处理做不好,后面全是白忙活。我在工业界摸爬滚打这些年,见过太多模型跑出来效果差,最后发现是数据没洗干净。嗯,今天就把这块硬骨头啃下来。

核心观点:数据预处理占整个建模流程的60%-80%时间,它决定了模型性能的上限。

3.1 缺失值处理:别让空值毁了你的模型

缺失值,说白了就是数据里某些字段是空的。为什么会这样?可能是传感器故障、人工录入遗漏、或者数据本身就不存在。

我常用的三种处理方式:

  1. 直接删除:如果缺失比例很小(比如<5%),而且数据量够大,直接删掉那几行。简单粗暴,但有效。
  2. 填充法:用均值、中位数、众数去填。我个人习惯用中位数,因为它对异常值不敏感。我在做轴承寿命预测时,振动数据的缺失值就是用中位数填的,效果不错。
  3. 模型预测填充:把缺失字段当目标变量,用其他字段去预测它。这个方法精度高,但计算量大。适合关键字段缺失较多的情况。

小技巧:填充前先看看数据分布。如果是正态分布,用均值;如果是偏态分布,用中位数。别问为什么,问就是经验。

# 代码示例:缺失值处理
import pandas as pd
import numpy as np

# 读取数据
df = pd.read_csv('sensor_data.csv')

# 查看缺失情况
print(df.isnull().sum())

# 用中位数填充数值列
for col in ['temperature', 'vibration', 'pressure']:
    df[col].fillna(df[col].median(), inplace=True)

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

print("缺失值处理完成!")

避坑指南:我曾经在一个项目中,直接用0填充了所有缺失值。结果模型学出来全是错的——因为0在物理意义上代表“无信号”,而不是“缺失”。记住:填充值必须符合业务逻辑

3.2 异常值检测:揪出那些“捣乱”的数据点

异常值,就是那些明显偏离正常范围的数据点。比如传感器突然跳变、人为录入错误。它们会严重干扰模型训练。

我常用的检测方法:

方法 适用场景 优缺点
3σ原则 数据近似正态分布 简单快速,但对非正态数据效果差
箱线图法(IQR) 任意分布 鲁棒性强,不受极端值影响
孤立森林 高维数据 适合大规模数据,但解释性差

我个人最常用的是箱线图法。为什么?因为它不假设数据分布,而且直观。你想想看,Q1-1.5*IQR到Q3+1.5*IQR这个区间,基本能覆盖99%的正常数据。

# 代码示例:箱线图法检测异常值
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 = detect_outliers_iqr(df, 'vibration')
print(f"发现 {len(outliers)} 个异常值")

# 处理方式:要么删除,要么用上下界替换
df['vibration'] = df['vibration'].clip(lower=lower_bound, upper=upper_bound)

重要提醒:异常值不一定是“坏”的。在寿命预测中,设备故障前的异常波动恰恰是重要信号。所以,先理解业务,再决定是否处理

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

标准化和归一化,说白了就是把不同量纲的数据拉到同一个尺度。比如温度是0-100℃,振动是0-0.5mm,如果不处理,模型会天然偏向数值大的特征。

两种主流方法:

  • 归一化(Min-Max Scaling):把数据缩放到[0,1]区间。公式:x' = (x - min) / (max - min)。适合数据有明确上下界的场景。
  • 标准化(Z-score):把数据变成均值为0、标准差为1的分布。公式:x' = (x - μ) / σ。适合数据近似正态分布的场景。

我建议:如果后续要用PCA、SVM、神经网络,优先用标准化。为什么?因为这些算法假设数据服从正态分布。归一化会破坏分布形态。

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

# 标准化
scaler_std = StandardScaler()
df_scaled = scaler_std.fit_transform(df[['temperature', 'vibration', 'pressure']])

# 归一化
scaler_mm = MinMaxScaler()
df_normalized = scaler_mm.fit_transform(df[['temperature', 'vibration', 'pressure']])

print("标准化后均值:", df_scaled.mean(axis=0))
print("归一化后范围:", df_normalized.min(axis=0), df_normalized.max(axis=0))

实战经验:我在做锂电池寿命预测时,发现容量衰减数据用标准化效果更好,而电压数据用归一化更稳定。所以,不同特征可以不同处理,别一刀切。

3.4 知识体系总览

下面这张图,是我自己总结的数据预处理核心流程。你看一遍,基本就明白今天讲的内容怎么串起来了。

数据预处理核心流程 原始数据 缺失值处理 异常值检测 标准化 / 归一化 干净数据 处理要点 • 删除/填充/预测 • 3σ/IQR/孤立森林 • Min-Max/Z-score • 先理解业务逻辑 • 不同特征不同处理 • 保存scaler供预测用

好了,今天的内容就到这里。数据预处理这块,说白了就是“磨刀不误砍柴工”。你花时间把数据洗干净,后面建模会顺畅很多。记住:垃圾进,垃圾出——这是机器学习领域最朴素的真理。

专注资料整理