第3章:数据采集与预处理——从传感器到干净数据的最后一公里

大家好,我是你们的老朋友。今天咱们聊聊数据采集与预处理。说实话,这一章是整个状态监测系统的地基。地基没打好,后面算法再牛也是白搭。我在项目里见过太多人,上来就调模型,结果数据里全是野点,最后折腾半天才发现是采集环节出了问题。

数据采集与预处理,说白了就是三件事:怎么把信号拿进来、怎么把脏东西去掉、怎么让数据规规矩矩。咱们一个一个说。

核心观点:预处理不是可有可无的步骤,而是决定监测系统成败的关键。80%的故障诊断问题,根源都在数据质量上。

数据采集与预处理知识体系 数据采集 数据采集卡 PLC通信 数据清洗 去噪 去野点 缺失值处理 删除法 插补法 数据归一化 预处理流程:采集 → 清洗 → 缺失处理 → 归一化 → 可用数据

3.1 数据采集卡与PLC通信——硬碰硬的活儿

数据采集卡,说白了就是传感器的翻译官。传感器把物理量变成电信号,采集卡把电信号变成数字。PLC呢,是工业现场的老大哥,它自己也能采集数据,但精度和采样率往往不如专用采集卡。

我个人习惯,振动信号用采集卡,温度压力走PLC。为什么?振动信号频率高,需要高速采样,采集卡更擅长。温度压力变化慢,PLC的模拟量模块足够用了。

3.1.1 采集卡选型要点

  • 采样率:至少是信号最高频率的2.56倍。我一般取5-10倍,留点余量。
  • 分辨率:16位是底线,24位更好。分辨率不够,小信号就淹没了。
  • 通道数:别抠门,多留几个备用通道。我在一个项目里就因为少算了一个通道,后期加传感器时只能换卡,折腾了三天。

3.1.2 PLC通信协议

PLC通信,Modbus TCP是主流。简单、稳定、几乎所有PLC都支持。我给大家一个Python读取PLC数据的示例:

import pyModbusTCP.client as modbus

# 连接PLC
client = modbus.ModbusClient(host="192.168.1.100", port=502)
client.open()

# 读取保持寄存器(温度值)
registers = client.read_holding_registers(0, 10)  # 从地址0读10个寄存器
if registers:
    temperature = registers[0] / 10.0  # 假设精度是0.1
    print(f"当前温度:{temperature}°C")
else:
    print("读取失败,检查网络或PLC状态")

client.close()

小技巧:PLC通信一定要加超时重试机制。工业现场网络不稳定,一次失败就报错,那系统就没法用了。我一般设3次重试,间隔1秒。

3.2 数据清洗——去噪与去野点

数据拿到手了,但别急着用。原始数据里什么妖魔鬼怪都有。电磁干扰、传感器松动、接线不良,都会产生噪声和野点。不清洗,后面分析全是错的。

3.2.1 去噪方法

去噪,我常用的就三种:

  1. 移动平均滤波:简单粗暴,适合慢变信号。窗口大小选3-5点,太大信号会失真。
  2. 中值滤波:对付脉冲噪声特别好。我在处理振动信号时经常用,能有效去掉尖刺。
  3. 小波去噪:高级玩法,适合非平稳信号。但参数调起来比较麻烦,新手慎用。
import numpy as np
from scipy.signal import medfilt

# 模拟原始信号(含噪声)
raw_signal = np.sin(np.linspace(0, 10, 1000)) + 0.1 * np.random.randn(1000)

# 中值滤波去噪
window_size = 5
clean_signal = medfilt(raw_signal, kernel_size=window_size)

print(f"原始信号均值:{np.mean(raw_signal):.4f}")
print(f"去噪后均值:{np.mean(clean_signal):.4f}")

3.2.2 去野点——3σ法则

野点,就是明显偏离正常范围的数据点。我判断野点的标准很简单:超过均值±3倍标准差,基本就是野点。为什么是3σ?正态分布下,99.7%的数据都在这个范围内,超出的大概率有问题。

注意:我曾经在一个项目里,用3σ法则去野点,结果把正常的高幅值振动信号也去掉了。后来才发现,那台设备在特定工况下振动就是大。所以,去野点前一定要先了解设备的正常工况范围。

def remove_outliers(data, threshold=3):
    mean = np.mean(data)
    std = np.std(data)
    lower_bound = mean - threshold * std
    upper_bound = mean + threshold * std
    clean_data = data[(data >= lower_bound) & (data <= upper_bound)]
    return clean_data

# 示例
data = np.array([1.2, 1.3, 1.1, 15.7, 1.4, 1.2, 1.3])  # 15.7是野点
clean = remove_outliers(data)
print(f"原始数据:{data}")
print(f"清洗后数据:{clean}")

3.3 缺失值处理——别让数据断档

数据采集过程中,难免会有缺失。网络断了、传感器故障、存储满了,都会导致数据缺失。缺失值不处理,很多算法会报错,或者结果偏差很大。

处理缺失值,我一般分三步走:

  1. 先判断缺失比例:如果超过30%,建议重新采集。硬补出来的数据不可靠。
  2. 再选方法:缺失少用插补,缺失多用删除。
  3. 最后验证:补完的数据要检查合理性,别补出负的温度值。

3.3.1 常用插补方法

方法 适用场景 优点 缺点
均值插补 数据平稳,波动小 简单快速 会降低数据方差
线性插值 数据有趋势变化 保留趋势信息 对突变不敏感
前向填充 传感器短暂掉线 保持最近值 会引入滞后
KNN插补 多维数据,有相关性 精度高 计算量大
import pandas as pd
import numpy as np

# 创建含缺失值的数据
df = pd.DataFrame({
    '温度': [25.1, 25.3, np.nan, 25.6, 25.8],
    '压力': [101.2, 101.5, 101.8, np.nan, 102.1]
})

# 线性插值
df_interpolated = df.interpolate(method='linear')
print("插值前:")
print(df)
print("\n插值后:")
print(df_interpolated)

我的习惯:对于时间序列数据,我优先用线性插值。它简单,而且能保留数据的变化趋势。如果缺失点前后数据变化剧烈,我会改用样条插值,效果更好。

3.4 数据归一化——让所有特征站在同一起跑线

归一化,说白了就是把不同量纲的数据拉到同一个尺度上。温度是几十度,振动是几个g,压力是几百kPa。不归一化,算法会偏向数值大的特征。

我常用的归一化方法有两种:

  • Min-Max归一化:把数据映射到[0,1]区间。适合数据分布比较均匀的情况。
  • Z-score标准化:把数据变成均值为0、标准差为1。适合数据有异常值的情况。
from sklearn.preprocessing import MinMaxScaler, StandardScaler
import numpy as np

# 模拟多特征数据
data = np.array([[25.0, 101.0, 0.5],
                 [30.0, 102.0, 0.8],
                 [28.0, 100.5, 0.6]])

# Min-Max归一化
minmax_scaler = MinMaxScaler()
data_minmax = minmax_scaler.fit_transform(data)
print("Min-Max归一化结果:")
print(data_minmax)

# Z-score标准化
zscore_scaler = StandardScaler()
data_zscore = zscore_scaler.fit_transform(data)
print("\nZ-score标准化结果:")
print(data_zscore)

避坑指南:我曾经犯过一个错误——先归一化再划分训练集和测试集。结果测试集的信息泄露到了训练集里,模型评估虚高。正确的做法是:先划分数据集,再用训练集的参数去归一化测试集

3.5 预处理流程总结

好了,咱们把整个流程串起来。一个完整的预处理管线应该是这样的:

  1. 数据采集:从采集卡或PLC读取原始数据
  2. 去噪:用中值滤波或小波去噪去掉噪声
  3. 去野点:用3σ法则或IQR方法剔除异常值
  4. 缺失值处理:用线性插值或前向填充补全数据
  5. 归一化:用Min-Max或Z-score统一量纲

每一步都有坑,但只要你按这个流程走,数据质量基本就有保障了。记住,预处理不是一次性工作。设备状态变了、工况变了,预处理参数也要跟着调。我一般每三个月重新评估一次预处理效果,该调就调。

嗯,这一章就到这儿。数据准备好了,下一章咱们就可以开始真正的特征提取了。


专注资料整理