4、时域预处理:去趋势、归一化、标准化、数据平滑
传感器数据拿到手,别急着往算法里塞。
这是我吃了好几次亏才总结出来的教训。原始数据就像刚从泥里挖出来的土豆,你得先洗洗、削削皮,才能下锅。时域预处理,就是这第一步清洗工作。
今天咱们聊四个最常用的手法:去趋势、归一化、标准化、数据平滑。每个我都踩过坑,咱们一个一个说。
4.1 去趋势:把“斜坡”掰平
什么叫趋势?说白了就是数据整体在往一个方向飘。
比如温度传感器,早上20度,中午35度,晚上又回到22度。这个“先升后降”的大波浪,就是趋势。但有时候,我们关心的不是温度本身,而是温度的小幅抖动——比如空调开关引起的0.1度波动。
不去掉趋势,这些小波动就被大波浪淹没了。
核心思路:拟合一条曲线代表趋势,然后用原始数据减去它。
最常见的做法是线性去趋势。假设数据是 y(t),我们先用最小二乘法拟合一条直线 y_fit(t) = a*t + b,然后得到去趋势后的数据:
y_detrended(t) = y(t) - y_fit(t)
我在项目中遇到过一个问题:一个加速度传感器装在振动的机器上,但机器本身在缓慢升温,导致传感器基线漂移。如果不做去趋势,频谱分析里全是低频假信号。去掉线性趋势后,振动特征才清晰可见。
我的习惯:先用肉眼扫一眼数据波形。如果整体走势像一条斜线,就用线性去趋势。如果是弯曲的(比如抛物线),可以考虑多项式去趋势,但阶数别太高,一般2-3阶就够了,否则容易把有用信号也去掉。
4.2 归一化:把数据“挤”到[0,1]区间
归一化,就是把数据压缩到0到1之间。
为什么要做?举个例子。你同时采集了压力(范围0-1000Pa)和温度(范围20-30℃)。如果直接扔进神经网络,压力值会把温度值完全“吃掉”,因为它的数值大得多。归一化后,两者都在同一量级,算法才能公平对待。
公式很简单:
x_norm = (x - x_min) / (x_max - x_min)
嗯,这里要注意一个问题:如果数据里有离群点(比如一个异常大的噪声尖峰),x_max会被拉得很大,导致正常数据被压缩到很小一块区域。我曾经因为这个原因,把一个好好的振动信号归一化后几乎变成了一条直线。
避坑指南:如果数据有离群点,先做离群点剔除,或者用分位数归一化(比如用5%和95%分位数代替min和max)。我一般先用箱线图看一眼数据分布,再决定用哪种归一化。
4.3 标准化:让数据“归零”且“等方差”
标准化和归一化经常被搞混。我刚开始做信号处理时也分不清,后来才明白:
- 归一化:把数据缩放到固定区间(比如[0,1])
- 标准化:把数据变成均值为0、标准差为1
标准化的公式:
x_std = (x - μ) / σ
其中μ是均值,σ是标准差。
标准化后的数据,大约有68%落在[-1, 1]区间,95%落在[-2, 2]区间。它不保证数据在某个固定范围内,但保证了数据的“相对位置”不变。
我个人习惯在以下场景用标准化:
- 数据本身近似正态分布(比如很多物理测量值)
- 后续算法假设数据服从高斯分布(比如PCA、线性回归)
- 需要保留离群点的相对大小(标准化不会把离群点压扁)
一句话总结:归一化看范围,标准化看分布。选哪个?取决于你的数据和算法。
4.4 数据平滑:把“毛刺”磨平
传感器数据总会有噪声。这些噪声像细小的毛刺,让波形看起来“毛毛躁躁”的。平滑的目的,就是把这些毛刺去掉,保留信号的骨架。
最常用的方法是移动平均。说白了,就是用相邻几个点的平均值代替当前点:
y_smooth[i] = (y[i-2] + y[i-1] + y[i] + y[i+1] + y[i+2]) / 5
窗口大小(这里是5)决定了平滑程度。窗口越大,曲线越光滑,但信号细节丢失也越多。
我在项目中遇到过一个问题:一个压力传感器采样率100Hz,但信号里混入了50Hz的工频干扰。用移动平均(窗口大小=2,相当于50Hz的整数倍)可以很好地滤掉它。但代价是信号的高频成分也被削弱了。
我的建议:平滑不是万能的。如果噪声频率和信号频率重叠,平滑会同时抹掉信号。这时候应该用滤波器(比如低通滤波),而不是简单平滑。平滑适合处理“白噪声”这类宽频噪声。
除了移动平均,还有几种常见平滑方法:
| 方法 | 特点 | 适用场景 |
|---|---|---|
| 移动平均 | 简单、计算快 | 噪声均匀、信号变化缓慢 |
| 高斯平滑 | 权重按高斯分布,中心点权重更大 | 需要保留信号峰值 |
| 中值滤波 | 用中位数代替均值 | 有脉冲噪声(椒盐噪声) |
| Savitzky-Golay滤波 | 用多项式拟合局部数据 | 需要保留信号的高阶特征(如峰值、谷值) |
你想想看,如果信号里有突然的尖峰(比如传感器被碰了一下),移动平均会把尖峰“拉宽”但不会完全消除。而中值滤波可以直接把尖峰当作离群点去掉。这就是为什么我处理冲击信号时,优先选中值滤波。
注意:平滑会引入延迟。实时系统中,移动平均的延迟大约是窗口大小的一半。如果窗口是10,延迟就是5个采样点。对于高速控制系统,这个延迟可能是致命的。我曾经在一个电机控制项目里,因为平滑窗口设得太大,导致系统响应慢了半拍,电机嗡嗡作响。后来把窗口从20降到了5,问题才解决。
4.5 四个方法的组合使用
实际项目中,这四个方法经常一起用。我一般按这个顺序:
- 先去趋势:去掉基线漂移和缓慢变化
- 再平滑:去掉高频噪声
- 最后归一化或标准化:根据后续算法选择
为什么先去趋势再平滑?因为趋势本身也是一种“低频信号”,如果先平滑,趋势会被保留,但噪声被去掉,数据看起来更“干净”。但如果你先平滑再去趋势,平滑过程可能会把趋势的细节也抹掉,导致去趋势不彻底。
当然,这不是铁律。我见过有人先标准化再平滑,理由是标准化后的数据更容易选择平滑参数。嗯,这也有道理。关键是你得理解每一步在做什么,然后根据数据特点灵活调整。
最后说一句:预处理不是越复杂越好。有时候,一个简单的移动平均加线性去趋势,就能解决80%的问题。别一上来就上什么小波变换、卡尔曼滤波——先试试简单的,不行再升级。这是我用无数次加班换来的经验。