3、数据预处理:清洗、去重、异常值处理
数据预处理,说白了就是给设备画像「洗菜切菜」。你从现场采集回来的数据,脏、乱、差,什么都有。我见过太多项目,模型算法选得再好,数据一塌糊涂,最后全白搭。
这一章,咱们就聊聊怎么把原始数据收拾得服服帖帖。
3.1 数据清洗:把垃圾倒掉
数据清洗,核心就三件事:补缺失、纠错误、整格式。
3.1.1 缺失值处理
设备传感器偶尔掉线,或者传输丢包,数据就缺了一块。怎么办?
- 直接删除:缺失比例小于5%,且是随机缺失,删了影响不大。
- 均值/中位数填充:连续型数值,比如温度、压力,用前后均值补上。
- 前向/后向填充:时间序列数据,用上一个有效值填充。我习惯用
ffill()。 - 模型预测填充:缺失值很重要,就用KNN或回归模型预测。但别滥用,计算量太大。
3.1.2 格式统一
同一个设备,不同时间段的温度单位可能不一样。有的用摄氏度,有的用华氏度。这必须统一。
# 温度统一转成摄氏度
def temp_convert(value, unit):
if unit == 'F':
return (value - 32) * 5 / 9
elif unit == 'C':
return value
else:
return None
df['temperature'] = df.apply(lambda x: temp_convert(x['temp_value'], x['temp_unit']), axis=1)
时间格式也得统一。我遇到过最坑的,同一个设备,时间戳有的用 YYYY-MM-DD HH:MM:SS,有的用 YYYY/MM/DD。不统一,后面排序、聚合全乱套。
3.2 数据去重:别让重复数据骗了你
设备数据重复,原因很多:网络重传、采集程序bug、人工误操作。重复数据会让统计结果失真,比如平均故障间隔时间(MTBF)算出来偏大。
3.2.1 完全去重
所有字段都一样,直接删掉。
df.drop_duplicates(inplace=True)
3.2.2 部分去重
关键字段相同,但时间戳不同。比如同一台设备,同一时刻上报了两次数据。这种情况,保留第一条或最后一条。
df.drop_duplicates(subset=['device_id', 'timestamp'], keep='first', inplace=True)
3.3 异常值处理:揪出捣乱的「坏数据」
异常值,就是那些明显偏离正常范围的数据点。可能是传感器故障、通信干扰,或者设备真的出了异常。但注意,异常值不一定是错误值——设备故障前的剧烈波动,恰恰是我们要捕捉的信号。
3.3.1 统计方法
| 方法 | 原理 | 适用场景 |
|---|---|---|
| 3σ原则 | 超出均值±3倍标准差的数据视为异常 | 数据近似正态分布 |
| 箱线图(IQR) | 超出Q1-1.5×IQR或Q3+1.5×IQR的数据视为异常 | 数据分布偏态,或不知道分布形态 |
| Z-Score | 计算每个数据点的Z分数,超过阈值(通常3)视为异常 | 数据量较大,需要标准化处理 |
我个人更偏爱箱线图法。为什么?因为它不受极端值影响,鲁棒性好。你想想看,如果数据本身就有几个极端值,用3σ原则算出来的均值和标准差都被带偏了,反而检测不出真正的异常。
# 箱线图法检测异常值
Q1 = df['vibration'].quantile(0.25)
Q3 = df['vibration'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
df['is_outlier'] = (df['vibration'] < lower_bound) | (df['vibration'] > upper_bound)
3.3.2 时序方法
设备数据是时间序列,相邻数据点之间有关联。这时候,可以用移动平均或指数平滑来检测异常。
# 移动平均法检测异常
df['rolling_mean'] = df['temperature'].rolling(window=5).mean()
df['rolling_std'] = df['temperature'].rolling(window=5).std()
df['is_anomaly'] = abs(df['temperature'] - df['rolling_mean']) > 3 * df['rolling_std']
3.4 知识体系总览
下面这张图,把数据预处理的整个流程串起来了。你可以把它当作操作手册,每次做预处理前看一眼。
3.5 处理策略总结
数据预处理没有银弹。不同场景,策略不同。我整理了一个决策表,你可以对照着用。
| 数据类型 | 常见问题 | 推荐处理方式 | 注意事项 |
|---|---|---|---|
| 连续型数值(温度、压力) | 缺失、跳变、漂移 | 前向填充 + 箱线图检测 | 跳变可能是真实故障,别一刀切 |
| 离散型状态(开关、档位) | 重复、非法值 | 完全去重 + 枚举校验 | 非法值直接置为NaN或前向填充 |
| 时间戳 | 格式不统一、时区混乱 | 统一转成UTC时间戳 | 注意夏令时和闰秒 |
| 文本型(设备型号、厂商) | 大小写不一致、拼写错误 | 统一小写 + 模糊匹配 | 建立标准字典表,自动映射 |
is_anomaly 标记,而不是直接删除或修改原始值。这样,模型训练时可以选择是否使用异常标记样本,灵活得多。
数据预处理,看似繁琐,但它是设备画像的基石。你花80%的时间做数据准备,后面20%的时间建模就够了。反过来,数据没处理好,后面花200%的时间也救不回来。