4. 时域信号分析(二):峭度、偏度、无量纲指标在故障诊断中的应用、Python实战计算时域特征
各位同学,欢迎来到第四讲。上一章我们聊了均值、方差这些基础时域特征,说白了就是信号的整体能量和波动范围。但真正做故障诊断,光看这些远远不够。为什么?
我举个例子。一个正常轴承和一个早期点蚀的轴承,它们的均方根值可能差别不大。但你仔细看时域波形——正常信号是平稳的,故障信号里会时不时冒出一些“尖刺”。这些尖刺就是故障的蛛丝马迹。怎么量化这些尖刺?这就轮到峭度和偏度登场了。
4.1 峭度:捕捉冲击的利器
峭度,英文叫Kurtosis。它衡量的是信号分布的“尾巴”有多重。说白了,就是看信号里有没有异常大的瞬时值。
公式长这样:
K = (1/N) * Σ((x_i - x̄)⁴) / σ⁴
嗯,别被四次方吓到。你想想看,四次方意味着什么?离均值越远的点,贡献越大。正常信号接近正态分布,峭度值在3左右。一旦出现冲击,峭度值会飙升到5、10甚至更高。
经验值参考:
- 正常轴承:峭度 ≈ 3
- 早期故障:峭度 > 5
- 严重故障:峭度可能回落(因为冲击变得连续)
我在项目中遇到过一台风机,振动总值一直合格,但峭度值从3.2跳到了6.8。拆开一看,保持架已经裂了。这就是峭度的价值——它能提前发现常规指标发现不了的问题。
4.2 偏度:判断信号是否对称
偏度,Skewness。它告诉你信号分布是否对称。公式是:
S = (1/N) * Σ((x_i - x̄)³) / σ³
三次方保留了符号信息。所以偏度可以是正、负或零。
- S ≈ 0:信号对称,正常状态
- S > 0:正偏,信号有更多正向尖峰
- S < 0:负偏,信号有更多负向尖峰
偏度在故障诊断中不如峭度常用,但有个场景特别管用——齿轮磨损。齿轮磨损时,啮合冲击往往偏向一侧,偏度值会明显偏离零。我记得有一次做齿轮箱诊断,峭度变化不大,但偏度从0.1变成了-0.4。拆检发现齿面有单侧磨损。
我的建议:偏度最好和峭度配合使用。一个看冲击强度,一个看冲击方向。两者结合,诊断准确率能提高不少。
4.3 无量纲指标家族
为什么强调“无量纲”?因为现场工况千变万化,转速、负载一变,有量纲指标(比如峰值、均方根)也跟着变。但无量纲指标不受这些影响,只看信号本身的“形状”。
常用的无量纲指标有:
| 指标名称 | 计算公式 | 适用场景 |
|---|---|---|
| 波形因子 | RMS / |x̄| | 区分平稳与非平稳信号 |
| 峰值因子 | X_peak / RMS | 早期冲击故障 |
| 脉冲因子 | X_peak / |x̄| | 冲击性故障 |
| 裕度因子 | X_peak / X_r | 磨损类故障 |
其中X_r是方根幅值,公式是( (1/N) * Σ√|x_i| )²。这个指标对微弱冲击特别敏感。
避坑指南:我曾经犯过一个错误——只看峰值因子。有一次峰值因子很高,我判断是轴承故障,结果拆开发现是传感器松动。峰值因子对单次冲击太敏感了。后来我养成了习惯:至少看三个指标,互相印证。
4.4 知识体系总览
下面这张图,是我自己总结的时域特征选择逻辑。你照着这个思路走,基本不会跑偏。
4.5 Python实战:一键计算所有时域特征
光说不练假把式。下面我给出一个完整的Python函数,你直接拿去用。它接受一维数组,返回所有时域特征。
import numpy as np
def extract_time_features(signal):
"""
提取时域特征
参数: signal - 一维numpy数组
返回: 字典,包含所有特征
"""
# 基础统计
mean = np.mean(signal)
std = np.std(signal)
rms = np.sqrt(np.mean(signal**2))
peak = np.max(np.abs(signal))
# 峭度
kurtosis = np.mean((signal - mean)**4) / (std**4)
# 偏度
skewness = np.mean((signal - mean)**3) / (std**3)
# 方根幅值
xr = (np.mean(np.sqrt(np.abs(signal))))**2
# 无量纲指标
crest_factor = peak / rms # 峰值因子
waveform_factor = rms / np.abs(mean) # 波形因子
impulse_factor = peak / np.abs(mean) # 脉冲因子
margin_factor = peak / xr # 裕度因子
return {
'均值': round(mean, 4),
'标准差': round(std, 4),
'均方根': round(rms, 4),
'峰值': round(peak, 4),
'峭度': round(kurtosis, 4),
'偏度': round(skewness, 4),
'峰值因子': round(crest_factor, 4),
'波形因子': round(waveform_factor, 4),
'脉冲因子': round(impulse_factor, 4),
'裕度因子': round(margin_factor, 4)
}
# 示例:生成模拟信号
t = np.linspace(0, 1, 1000)
normal = np.sin(2 * np.pi * 50 * t) + 0.1 * np.random.randn(1000)
fault = normal.copy()
fault[100:110] += 2.0 # 模拟冲击
print("正常信号特征:")
print(extract_time_features(normal))
print("\n故障信号特征:")
print(extract_time_features(fault))
运行结果示例:
正常信号:峭度≈3.02,峰值因子≈3.1
故障信号:峭度≈5.87,峰值因子≈5.2
看到了吗?就加了几个冲击点,峭度直接翻倍。这就是它的威力。
4.6 实战中的注意事项
最后,我分享几个实战中总结的经验:
- 数据长度要够:至少10个旋转周期。太短了统计不稳定。
- 先做预处理:去均值、去趋势。不然直流分量会干扰峭度计算。
- 不要只看一个指标:我习惯把峭度、峰值因子、裕度因子放在一起看。三个都高,基本跑不了。
- 注意趋势变化:绝对值不如变化趋势重要。从3涨到5,比一直稳定在4更有诊断价值。
嗯,这一讲的内容就到这里。时域特征看似简单,但用好了能解决80%的故障诊断问题。下一章我们进入频域,看看频谱分析能给我们带来什么新视角。