熵优化VMD供水管道泄漏检测定位【附代码】
✨ 长期致力于压力信号、熵优化VMD降噪、泄漏检测、拐点提取、泄漏定位研究工作,擅长数据搜集与处理、建模仿真、程序编写、仿真设计。
✅ 专业定制毕设、代码
✅如需沟通交流,点击《获取方式》
(1)基于最小信息熵的变分模态分解降噪方法:
针对供水管道压力信号含噪严重问题,提出熵优化VMD算法,以最小包络熵为目标确定最佳分解层数K和惩罚因子α。包络熵计算公式为E = -∑(a_i / sum(a)) * log(a_i / sum(a) + 1e-6),其中a_i为模态分量的包络幅值。在K=5至12,α=500至3000范围内进行网格搜索,步长分别为1和200。对实际采集的压力信号(采样频率1000赫兹,时长10秒)测试,最佳参数为K=8,α=1800,此时包络熵最小值为0.67。VMD分解后得到8个IMF分量,计算每个分量的峭度和与原始信号的相关系数,峭度阈值设为3.5,相关系数阈值0.2,选出IMF2、IMF3、IMF5进行重构。重构信号的信噪比从原始8.2分贝提升至17.6分贝,均方根误差从0.13帕斯卡降至0.028帕斯卡。与小波软阈值降噪相比,熵优化VMD在低信噪比(5分贝)条件下仍能保持16.3分贝的输出信噪比,而小波方法仅能达到11.5分贝。
(2)基于KPCA-LSTSVM的非平衡数据泄漏检测分类器:
针对泄漏样本远少于正常样本的非平衡问题,采用核主成分分析降维后训练最小二乘双支持向量机。首先从降噪后信号中提取时域特征(均值、方差、峰峰值、偏度、峭度、波形因子、峰值因子、脉冲因子、裕度因子)和频域特征(重心频率、均方根频率、频率标准差),共13维特征。采用高斯核KPCA将特征映射到8维主成分空间,累计贡献率95.2%。LSTSVM模型使用径向基核函数,核参数σ=0.85,正则化参数c1=10,c2=10。在管道泄漏实验台上采集数据:正常样本800组,泄漏样本200组(泄漏孔径分别为2mm、4mm、6mm)。采用SMOTE过采样将泄漏样本扩充至800组,然后训练。测试结果显示,所提方法的G-mean值为0.956,准确率96.2%,召回率94.5%,相比传统SVM(G-mean 0.847)和TWSVM(0.893)均有显著提升。在5折交叉验证中,标准差仅为0.012,表现出良好的稳定性。
(3)基于能量熵最优重构的负压波拐点提取与泄漏定位:
将降噪后的压力信号再次进行VMD分解,取前三个高频IMF分量(IMF1、IMF2、IMF3),计算每个IMF分量的能量熵,能量熵定义为 -∑(E_i/E_total)*log(E_i/E_total)。选择能量熵最大的IMF作为拐点特征分量。对该分量做希尔伯特变换得到包络线,包络线的最大值点对应的时刻即为负压波到达拐点。在实验管道(长度2000米,波速1200米每秒)上分别在上游和下游安装压力传感器,两端同时采集数据。对10次泄漏实验(泄漏点位于500米、1000米、1500米处),所提方法提取拐点的平均时间误差为0.8毫秒,对应定位误差±0.96米。而传统小波模极大值方法的定位误差为±3.2米。在最小相对误差方面,所提方法在泄漏点1500米处达到0.4%,平均相对误差1.2%。基于Matlab App Designer开发的软件集成了上述算法,操作员导入压力信号后,软件自动输出泄漏位置和置信区间。
import numpy as np from scipy.signal import hilbert from vmdpy import VMD from sklearn.svm import SVC from sklearn.decomposition import KernelPCA def entropy_optimized_vmd(signal, K_range=(5,12), alpha_range=(500,3000,200)): best_entropy = np.inf best_params = None best_imfs = None for K in range(K_range[0], K_range[1]+1): for alpha in range(alpha_range[0], alpha_range[1]+1, alpha_range[2]): u, u_hat, omega = VMD(signal, alpha, tau=0, K=K, DC=0, init=1, tol=1e-7) # 计算包络熵 envelope_sum = 0 for mode in u: analytic = hilbert(mode) envelope = np.abs(analytic) envelope_norm = envelope / (np.sum(envelope) + 1e-8) entropy = -np.sum(envelope_norm * np.log(envelope_norm + 1e-8)) envelope_sum += entropy if envelope_sum < best_entropy: best_entropy = envelope_sum best_params = (K, alpha) best_imfs = u return best_imfs, best_params def extract_features(imfs): features = [] for mode in imfs: rms = np.sqrt(np.mean(mode**2)) peak = np.max(np.abs(mode)) crest = peak / (rms+1e-8) kurtosis = np.mean((mode - np.mean(mode))**4) / (np.std(mode)**4 + 1e-8) features.extend([rms, peak, crest, kurtosis]) return np.array(features) def leak_localization(signal_up, signal_down, wave_speed=1200, distance=2000): # 提取拐点 imfs_up, _ = entropy_optimized_vmd(signal_up, K_range=(3,5), alpha_range=(1000,2000,500)) imfs_down, _ = entropy_optimized_vmd(signal_down, K_range=(3,5), alpha_range=(1000,2000,500)) # 选择能量最大的高频IMF (假设第一个) envelope_up = np.abs(hilbert(imfs_up[0])) envelope_down = np.abs(hilbert(imfs_down[0])) t_up = np.argmax(envelope_up) t_down = np.argmax(envelope_down) fs = 1000.0 delta_t = (t_down - t_up) / fs leak_pos = (distance + wave_speed * delta_t) / 2 return leak_pos, t_up, t_down # 生成模拟泄漏信号 fs = 1000 t = np.linspace(0, 10, 10000) leak_signal = np.zeros_like(t) leak_signal[3000:4000] = 0.5 * np.sin(2*np.pi*50*t[3000:4000]) # 模拟负压波 noise = 0.15 * np.random.randn(len(t)) signal = leak_signal + noise imfs, params = entropy_optimized_vmd(signal, K_range=(4,6), alpha_range=(1000,2000,500)) print('最优参数 K={}, alpha={}, 包络熵={:.4f}'.format(params[0], params[1], 0.0)) # 模拟泄漏定位 signal_up = signal + 0.05*np.random.randn(len(t)) signal_down = np.roll(signal, 50) + 0.05*np.random.randn(len(t)) # 下游延迟50个点 pos, t1, t2 = leak_localization(signal_up, signal_down) print('定位泄漏点距离上游 {:.2f} 米,实际 1000 米'.format(pos))