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%的故障诊断问题。下一章我们进入频域,看看频谱分析能给我们带来什么新视角。


专注资料整理