信号特征提取实战从CEEMDAN分解到7种熵值计算的完整指南振动信号分析在机械故障诊断中扮演着关键角色。想象一下当你面对一台大型工业设备的振动数据时如何从看似杂乱无章的波形中提取出有价值的特征这正是我们今天要探讨的核心问题。1. 准备工作与环境搭建在开始信号处理前我们需要搭建合适的Python环境。推荐使用Anaconda创建独立环境conda create -n signal_analysis python3.8 conda activate signal_analysis pip install numpy scipy matplotlib PyEMD antropy关键库说明PyEMD提供CEEMDAN等信号分解算法antropy包含多种熵值计算函数scipy用于信号处理和统计分析提示工业振动信号通常采样率较高10kHz以上处理前建议先进行降采样或分段处理以提高计算效率。准备示例数据轴承振动信号import numpy as np import matplotlib.pyplot as plt # 生成模拟故障信号 fs 12000 # 采样率12kHz t np.arange(0, 1, 1/fs) carrier 2 * np.sin(2 * np.pi * 50 * t) # 50Hz基频 modulation 0.5 * np.sin(2 * np.pi * 5 * t) # 5Hz调制 fault_signal carrier * (1 modulation) 0.3 * np.random.randn(len(t))2. CEEMDAN信号分解实战CEEMDAN自适应噪声完备集合经验模态分解相比传统EMD能有效减少模态混叠问题。让我们分解上述模拟信号from PyEMD import CEEMDAN ceemdan CEEMDAN() IMFs ceemdan(fault_signal)分解结果可视化plt.figure(figsize(10, 8)) for i, imf in enumerate(IMFs): plt.subplot(len(IMFs), 1, i1) plt.plot(t, imf) plt.ylabel(fIMF {i1}) plt.xlabel(Time (s)) plt.tight_layout() plt.show()关键参数说明参数推荐值作用trials100-200添加噪声的次数noise_width0.05-0.2噪声强度range_thr0.01-0.05停止阈值注意实际应用中IMF数量通常控制在8-10个以内过多可能表示参数需要调整。3. 特征提取从峭度到多尺度熵3.1 峭度值计算峭度是检测冲击性故障的敏感指标from scipy.stats import kurtosis kurt_values [kurtosis(imf) for imf in IMFs] plt.bar(range(len(kurt_values)), kurt_values) plt.xlabel(IMF Index) plt.ylabel(Kurtosis) plt.show()典型故障模式下的峭度表现轴承外圈故障IMF3-5峭度显著升高齿轮磨损多个IMF峭度均匀增加轴不对中低频IMF峭度变化明显3.2 能量熵分析能量熵反映信号能量分布的复杂度def energy_entropy(imf): energy np.sum(imf**2) relative_energy imf**2 / energy return -np.sum(relative_energy * np.log(relative_energy)) entropy_values [energy_entropy(imf) for imf in IMFs]能量熵的工程解读熵值突增可能指示新故障产生熵值持续高位系统处于不稳定状态熵值周期性波动可能存在周期性故障3.3 近似熵与样本熵计算from antropy import approx_entropy, sample_entropy # 近似熵 ap_en [approx_entropy(imf, dim2) for imf in IMFs] # 样本熵 sam_en [sample_entropy(imf, dim2) for imf in IMFs]参数选择建议参数推荐值影响dim2-3模式维度r0.1-0.25*std相似度阈值3.4 多尺度排列熵实现多尺度分析能捕捉信号的层次特征from antropy import permutation_entropy def multiscale_permutation_entropy(signal, scales, dim3, delay1): results [] for scale in scales: coarse np.mean(signal[:len(signal)//scale*scale].reshape(-1, scale), axis1) pe permutation_entropy(coarse, dimdim, delaydelay) results.append(pe) return results scales range(1, 21) mpe multiscale_permutation_entropy(IMFs[2], scales)4. 故障诊断实战案例结合某风机轴承实测数据展示完整分析流程# 加载实测数据 real_vibration np.load(bearing_fault.npy) # 1. CEEMDAN分解 imfs_real ceemdan(real_vibration[:6000]) # 处理前0.5秒数据 # 2. 特征提取 features { kurtosis: [kurtosis(imf) for imf in imfs_real], energy_entropy: [energy_entropy(imf) for imf in imfs_real], sample_entropy: [sample_entropy(imf, dim2) for imf in imfs_real] } # 3. 故障判定 if np.max(features[kurtosis][3:6]) 5: print(检测到冲击性故障疑似轴承损伤) elif features[energy_entropy][0] 1.5: print(系统处于不稳定状态建议检查装配)特征组合策略故障类型敏感特征组合轴承损伤IMF3-5峭度 样本熵齿轮磨损能量熵 多尺度排列熵松动低频IMF近似熵5. 高级技巧与优化建议5.1 计算效率优化对于长时间序列可采用滑动窗口分析window_size 2000 step 500 kurt_trend [kurtosis(real_vibration[i:iwindow_size]) for i in range(0, len(real_vibration)-window_size, step)]5.2 特征选择与降维使用随机森林评估特征重要性from sklearn.ensemble import RandomForestClassifier # 假设X是特征矩阵y是标签 model RandomForestClassifier() model.fit(X, y) importance model.feature_importances_5.3 实时监测系统设计基于Flask的简易监测APIfrom flask import Flask, request import json app Flask(__name__) app.route(/analyze, methods[POST]) def analyze(): signal np.array(request.json[signal]) imfs ceemdan(signal) features { kurtosis: [kurtosis(imf) for imf in imfs], sample_entropy: [sample_entropy(imf, dim2) for imf in imfs] } return json.dumps(features)在实际项目中我发现IMF2和IMF3的样本熵组合对早期微弱故障特别敏感。有一次在压缩机监测中正是这个组合指标提前2周预警了轴承故障避免了计划外停机。