3. 数据采集与预处理:传感器选型、采集频率、清洗与异常检测
数据采集与预处理,说白了就是给设备态势评估“喂饭”。饭好不好,直接决定了后面模型能不能干活。我见过太多项目,算法模型调得天花乱坠,结果数据一塌糊涂,最后全白搭。这一章,咱们就把这顿饭怎么做透。
核心原则:数据质量 > 算法复杂度。宁可用简单的模型配高质量数据,也别拿脏数据去跑深度学习。
3.1 传感器选型:别光看参数,要看场景
传感器选型,不是参数越高越好。你想想看,一个振动传感器精度做到0.01μm,但现场环境温度80度、湿度90%,它扛得住吗?
我个人习惯,选型时重点看三个维度:
- 量程与精度匹配:设备正常运行时,信号幅值最好落在量程的30%~70%之间。留点余量,别让信号削顶。
- 环境适应性:温度、湿度、电磁干扰、粉尘——这些现场条件决定了传感器能不能活过三个月。我曾经在钢厂项目里,一批进口传感器三个月内坏了七成,后来发现是现场的高频电磁干扰把内部电路烧了。
- 安装方式与维护成本:有些传感器需要停机才能安装,有些可以在线安装。别等装上去才发现,换个电池要拆整条产线。
| 传感器类型 | 典型应用 | 量程建议 | 环境限制 |
|---|---|---|---|
| 加速度传感器 | 旋转机械振动监测 | ±50g | 温度<120°C |
| 温度传感器(PT100) | 轴承/绕组温度 | -50~200°C | 无特殊限制 |
| 压力传感器 | 液压/气动系统 | 0~40MPa | 防震、防腐蚀 |
| 电流互感器 | 电机电流监测 | 0~500A | 避免强磁场干扰 |
我的经验:选型时多花一天去现场看工况,比在办公室翻三天手册管用。有一次我坚持要去现场,结果发现设备旁边有个高频焊机——所有没做电磁屏蔽的传感器方案全得重来。
3.2 数据采集频率:不是越快越好
采集频率怎么定?很多人觉得越高越好,其实不是。频率太高,数据量爆炸,存储和计算成本都上去了;频率太低,关键特征抓不到。
我一般按这个逻辑来:
- 先确定目标信号的最高频率。比如振动信号,设备转速3000rpm,基频50Hz,那最高关注到10倍频(500Hz)就够了。
- 采样频率至少是最高频率的2.5倍。这是工程经验,比理论上的2倍多留点余量。我习惯取3~5倍。
- 考虑数据存储和传输带宽。一个通道10kHz采样,32通道同时采,一天的数据量就是几十个GB。你算算你的硬盘和网络扛不扛得住。
避坑指南:我曾经在一个风电项目里,为了省硬盘空间,把采样频率从10kHz降到了2kHz。结果设备的高频故障特征全丢了,模型怎么调都不准。后来花了两个月重新采集数据——教训深刻。
3.3 数据清洗:把垃圾扔出去
数据清洗,就是去掉那些明显不合理的数据。别小看这一步,原始数据里什么妖魔鬼怪都有。
我常用的清洗方法:
- 范围检查:传感器有量程,数据超出量程的,直接标记为无效。比如一个0~100°C的温度传感器,突然蹦出个-999,那肯定是通讯错误。
- 重复值检查:有时候数据采集系统会重复发送同一帧数据。连续N个完全相同的时间戳或数值,大概率是重复。
- 时间戳对齐:多传感器系统里,时间戳不同步是家常便饭。我习惯用NTP服务器统一授时,然后按固定时间窗口重采样对齐。
# 一个简单的数据清洗示例(Python伪代码)
def clean_sensor_data(df, sensor_range):
# 范围检查
df = df[(df['value'] >= sensor_range[0]) & (df['value'] <= sensor_range[1])]
# 去除连续重复值(超过5个相同值视为异常)
df = df[~(df['value'].diff() == 0).rolling(5).sum() >= 5]
# 时间戳对齐到整秒
df['timestamp'] = df['timestamp'].dt.round('1s')
return df
3.4 缺失值处理:别乱填,先搞清楚为什么缺失
缺失值处理,很多人上来就填均值、填中位数。但我想说——先搞清楚为什么缺失,比怎么填更重要。
缺失原因一般分三类:
- 随机缺失:比如通讯偶尔丢包。这种可以用前向填充、线性插值或均值填充。
- 系统缺失:比如设备停机期间,传感器不工作。这种不能乱填,填了反而引入错误信息。我一般直接标记为“停机状态”,不参与建模。
- 传感器故障:连续长时间缺失,大概率是传感器坏了。这时候填什么都没用,得先修传感器。
| 缺失类型 | 常见原因 | 推荐处理方法 |
|---|---|---|
| 随机缺失 | 通讯干扰、缓存溢出 | 线性插值、前向填充 |
| 系统缺失 | 设备停机、维护周期 | 标记状态,不填充 |
| 传感器故障 | 硬件损坏、线路断开 | 先修复传感器,再补采数据 |
我的习惯:对于随机缺失,我优先用线性插值。因为它保留了数据的趋势信息,比简单填均值更靠谱。但注意——如果缺失段太长(超过连续10个点),插值就不准了,这时候宁可删掉这段数据。
3.5 异常值检测:抓住那些“不对劲”的点
异常值检测,是数据预处理里最考验经验的一步。因为“异常”的定义,往往取决于具体的设备和工况。
我常用的方法:
- 3σ原则:数据服从正态分布时,超过均值±3倍标准差的值视为异常。简单粗暴,但有效。
- IQR(四分位距)法:不受极端值影响,适合非正态分布。Q1-1.5*IQR 到 Q3+1.5*IQR 之外的值,视为异常。
- 滑动窗口法:在时间序列上,用滑动窗口计算局部均值和标准差,检测局部异常。这个方法对设备工况变化特别有用。
# 滑动窗口异常检测示例
def sliding_window_anomaly(data, window=100, threshold=3):
anomalies = []
for i in range(window, len(data)):
window_data = data[i-window:i]
mean = np.mean(window_data)
std = np.std(window_data)
if abs(data[i] - mean) > threshold * std:
anomalies.append(i)
return anomalies
避坑指南:我曾经在化工项目里,用3σ原则检测一个压力传感器的异常值。结果发现每次设备正常启动时,压力都会瞬间冲高,被算法判定为异常。后来我加了一个“工况识别”的前置步骤——先判断设备处于什么状态,再决定是否算异常。这个坑,很多人都会踩。
3.6 知识体系总览
下面这张图,把数据采集与预处理的整个流程串起来了。你可以把它当作一个检查清单——每次做数据预处理时,对着走一遍,基本不会漏东西。
嗯,到这里,数据采集与预处理的核心内容就讲完了。记住一句话:数据预处理花的时间,永远值得。后面模型跑得顺不顺,全看这一步做得扎不扎实。