3. 信号处理与特征提取
各位同事,咱们搞风电运维的,每天面对的就是一堆传感器数据。振动、温度、电流……这些原始信号就像病人的心电图,光看波形是看不出名堂的。你得会“翻译”,把信号里的故障特征给揪出来。
我个人习惯把特征提取分成三大类:时域、频域、时频域。说白了,就是三个不同的“放大镜”,各有各的用处。今天咱们就一个一个捋清楚。
核心逻辑:信号处理的目的,是把高维、冗余的原始数据,压缩成低维、敏感的特征向量,喂给后面的诊断模型。这一步做不好,后面全是白搭。
3.1 时域特征:最直观的“体检报告”
时域特征,就是直接在时间轴上算统计量。你想想看,一个健康的轴承,振动波形应该是平稳的、随机的。一旦出现故障,波形就会“炸毛”。
常用的时域指标:
| 特征 | 物理意义 | 故障敏感度 |
|---|---|---|
| 均值 | 信号的平均水平,反映静态分量 | 低(对磨损不敏感) |
| 方差/标准差 | 信号的能量波动,反映振动剧烈程度 | 中(能看出整体恶化) |
| 峭度 | 信号分布的“尖峰”程度 | 高(对早期冲击故障非常敏感) |
| 偏度 | 信号分布的不对称性 | 中(反映磨损方向性) |
| 峰值因子 | 峰值与有效值的比值 | 高(识别冲击性故障) |
我的经验:峭度这个指标,我建议你重点关注。我在项目中遇到过好几次,轴承早期出现点蚀时,有效值还没什么变化,峭度已经飙升了。它就像个“侦察兵”,能提前预警。
举个例子,计算峭度的Python代码很简单:
import numpy as np
def calculate_kurtosis(signal):
# 信号去均值
x = signal - np.mean(signal)
# 计算四阶矩
n = len(x)
kurt = (np.sum(x**4) / n) / (np.var(signal)**2) - 3
return kurt
# 假设你采集了一段振动数据
vibration_data = np.random.randn(1024) # 模拟健康信号
print(f"峭度值: {calculate_kurtosis(vibration_data):.2f}")
3.2 频域特征:把信号“掰开揉碎”看成分
时域看不出来的东西,换到频域就一目了然。比如齿轮的啮合频率、轴承的故障特征频率,在频谱上就是一根根“谱线”。
FFT(快速傅里叶变换)是最基础的工具。但我要提醒你,直接做FFT有个坑——它假设信号是平稳的。风电的转速经常变,直接做FFT会得到一堆“糊”在一起的频谱。
避坑指南:我曾经在变桨轴承诊断上吃过亏。直接用原始振动信号做FFT,频谱上全是干扰。后来我加了阶次跟踪,把时域信号重采样到角度域,才把故障特征频率清晰地分离出来。记住:变转速工况下,先做阶次跟踪,再做FFT。
包络谱是另一个利器。它专门用来解调高频冲击信号。比如轴承内圈故障,冲击会调制在高频共振上。包络谱能把那个“调制信号”解出来,看到清晰的故障频率。
from scipy import signal
import numpy as np
def envelope_spectrum(data, fs):
# 希尔伯特变换求包络
analytic_signal = signal.hilbert(data)
envelope = np.abs(analytic_signal)
# 对包络做FFT
freqs = np.fft.rfftfreq(len(envelope), 1/fs)
spectrum = np.fft.rfft(envelope)
return freqs, np.abs(spectrum)
3.3 时频域特征:给信号拍“CT”
时域和频域各有局限。时域看不到频率成分,频域看不到时间变化。时频域分析,就是给信号拍“CT”,同时看到时间和频率两个维度。
小波变换是我个人比较喜欢的方法。它用不同尺度的“小波”去匹配信号,能同时捕捉到突变和缓变。比如叶片开裂瞬间的冲击,小波能精确定位到发生时刻。
经验模态分解(EMD)则更“智能”。它不需要预设基函数,完全根据信号自身的时间尺度来分解。我处理非平稳信号时,经常先用EMD把信号拆成几个本征模态函数(IMF),再对每个IMF做频谱分析。
实用建议:小波变换适合已知故障频率范围的情况(比如齿轮啮合频率附近)。EMD更适合未知故障模式,但要注意端点效应和模态混叠。我一般两个都试,看哪个效果更好。
3.4 特征选择与降维:别让“垃圾特征”淹没了真相
你想想看,时域算10个特征,频域算20个,时频域再算30个……加起来五六十个特征。这么多特征直接扔给模型,不仅计算慢,还会引入噪声。
PCA(主成分分析)是最经典的降维方法。它把原始特征投影到几个“主成分”方向上,保留方差最大的成分。说白了,就是抓住主要矛盾。
t-SNE则更适合可视化。它能把高维特征映射到2D或3D空间,让同类故障聚在一起,不同故障分开。我经常用t-SNE来快速判断:我提取的特征到底能不能区分不同故障类型?
from sklearn.decomposition import PCA
from sklearn.manifold import TSNE
# 假设 features 是 (样本数, 特征数) 的矩阵
# PCA降维到10维
pca = PCA(n_components=10)
features_pca = pca.fit_transform(features)
# t-SNE可视化到2维
tsne = TSNE(n_components=2, perplexity=30)
features_tsne = tsne.fit_transform(features_pca)
我的习惯:先做PCA降维到10-20维,保留95%以上的方差。然后用t-SNE看看聚类效果。如果不同故障类型在t-SNE图上混在一起,说明特征提取没做好,得回去重新选特征。
嗯,信号处理这块内容比较多,但核心就一句话:选对特征,事半功倍;选错特征,白费力气。 你在实际项目中,不妨多试几种方法,找到最适合你那个机组、那个故障类型的特征组合。
公众号:蓝海资料掘金营,微信deep3321