从心电图去噪到股价预测:变分模态分解(VMD)的5个Python实战案例

张开发
2026/4/20 12:27:46 15 分钟阅读

分享文章

从心电图去噪到股价预测:变分模态分解(VMD)的5个Python实战案例
从心电图去噪到股价预测变分模态分解VMD的5个Python实战案例在信号处理领域变分模态分解Variational Mode Decomposition, VMD正逐渐成为时间序列分析的重要工具。与传统的傅里叶变换和小波分析不同VMD能够自适应地将复杂信号分解为多个本征模态函数IMF每个IMF都具有明确的中心频率和有限带宽。这种特性使得VMD在医疗、金融、工业等多个领域展现出独特的优势。本文将带您探索VMD技术在五个真实场景中的创新应用每个案例都配有可运行的Python代码和参数调优建议。无论您是医疗数据分析师、金融量化研究员还是工业设备监测专家都能从中获得可直接应用于实际工作的技术方案。1. 心电信号ECG噪声滤除实战心电信号分析是VMD技术最成功的应用领域之一。在实际临床环境中ECG信号常受到以下干扰工频干扰50/60Hz电源噪声基线漂移呼吸运动导致的低频波动肌电噪声肌肉活动产生的高频干扰import numpy as np from vmdpy import VMD import matplotlib.pyplot as plt # 加载真实ECG数据这里用模拟数据演示 fs 1000 # 采样率 t np.arange(0, 1, 1/fs) ecg_clean 0.5 * np.sin(2*np.pi*5*t) 0.2 * np.sin(2*np.pi*30*t) # 模拟ECG noise 0.1*np.sin(2*np.pi*50*t) 0.05*np.random.randn(len(t)) # 工频白噪声 ecg_noisy ecg_clean noise 0.3*np.sin(2*np.pi*0.5*t) # 添加基线漂移 # VMD参数设置 alpha 2000 # 带宽约束 tau 0.1 # 噪声容忍度 K 4 # IMF数量 DC 0 # 不强制第一个分量为DC init 1 # 均匀初始化频率 tol 1e-6 # 收敛容差 # 执行VMD分解 imfs, _, _ VMD(ecg_noisy, alpha, tau, K, DC, init, tol) # 可视化结果 plt.figure(figsize(12,8)) plt.subplot(K1,1,1) plt.plot(t, ecg_noisy, labelNoisy ECG) plt.legend() for i in range(K): plt.subplot(K1,1,i2) plt.plot(t, imfs[i], labelfIMF {i1}) plt.legend() plt.tight_layout() plt.show()提示在实际应用中IMF2通常包含主要的ECG特征波P波、QRS波群、T波而IMF1和IMF3可分别用于消除基线漂移和工频干扰。参数选择经验表参数ECG应用建议值作用说明alpha1000-3000控制IMF带宽值越大带宽越小K3-5根据噪声复杂度选择tau0.1-0.3对含噪信号的容错能力init1均匀初始化通常效果最佳2. 股价序列的趋势-周期分解金融时间序列分析中区分长期趋势和短期波动至关重要。VMD能够将股价分解为不同时间尺度的分量为量化交易提供新的特征维度。案例标普500指数分解import yfinance as yf from vmdpy import VMD import matplotlib.pyplot as plt # 获取标普500指数数据 sp500 yf.download(^GSPC, start2020-01-01, end2023-01-01)[Close] prices sp500.values.reshape(-1) # 数据标准化 prices_norm (prices - np.mean(prices)) / np.std(prices) # VMD参数金融序列特有设置 alpha 1500 # 较ECG更宽松的带宽约束 tau 0 # 金融数据不考虑噪声容忍 K 3 # 趋势/周期/噪声三组分 DC 1 # 第一个分量为趋势项 init 1 tol 1e-6 # 执行分解 imfs, _, omega VMD(prices_norm, alpha, tau, K, DC, init, tol) # 结果可视化 plt.figure(figsize(12,8)) plt.subplot(K1,1,1) plt.plot(sp500.index, prices, labelOriginal) plt.legend() for i in range(K): plt.subplot(K1,1,i2) plt.plot(sp500.index, imfs[i], labelfIMF {i1}) plt.legend() plt.tight_layout() plt.show()金融应用中的VMD技巧趋势识别IMF1通常对应长期趋势可用于判断牛市/熊市周期分析IMF2常包含3-12个月的商业周期波动噪声过滤IMF3可视为短期市场噪声在策略中可考虑过滤参数优化通过滚动窗口测试确定最优K值注意股价分解后各IMF分量可单独用于构建交易信号但需注意避免过拟合。建议结合夏普比率等指标评估各分量的预测能力。3. 轴承故障特征频率提取机械振动信号分析是工业预测性维护的核心。当轴承出现故障时振动信号会产生特定的冲击特征但这些特征往往被强背景噪声淹没。故障诊断流程采集原始振动信号加速度计数据VMD分解获得若干IMF对每个IMF计算包络谱在包络谱中识别故障特征频率import numpy as np from scipy.signal import hilbert from vmdpy import VMD import matplotlib.pyplot as plt # 模拟轴承故障信号内圈故障 fs 10000 # 采样频率 t np.arange(0, 1, 1/fs) carrier 2 * np.sin(2*np.pi*100*t) # 载波频率 fault_freq 150 # 故障特征频率 modulation 0.8 * (1 np.sin(2*np.pi*fault_freq*t)) # 幅值调制 vibration carrier * modulation 0.5*np.random.randn(len(t)) # 添加噪声 # VMD参数工业振动特有设置 alpha 5000 # 更高精度分解 tau 0.1 # 容忍测量噪声 K 5 # 充分分解各成分 DC 0 init 1 tol 1e-7 # 执行分解 imfs, _, _ VMD(vibration, alpha, tau, K, DC, init, tol) # 计算包络谱 def envelope_spectrum(signal, fs): analytic_signal hilbert(signal) env np.abs(analytic_signal) env_fft np.abs(np.fft.fft(env - np.mean(env))) freqs np.fft.fftfreq(len(env), 1/fs) return freqs[:len(freqs)//2], env_fft[:len(env_fft)//2] # 可视化包络谱 plt.figure(figsize(12,8)) for i in range(min(K,3)): # 只显示前3个IMF freqs, spec envelope_spectrum(imfs[i], fs) plt.subplot(3,1,i1) plt.plot(freqs, spec) plt.xlim(0, 500) plt.title(fIMF {i1} Envelope Spectrum) plt.tight_layout() plt.show()典型故障特征频率对照表故障类型计算公式示例值(Hz)内圈故障BPFI (N/2)(1d/Dcosα)fr150外圈故障BPFO (N/2)(1-d/Dcosα)fr90滚动体故障BSF (D/d)[1-(d/D)²cos²α]fr60保持架故障FTF (1/2)(1-d/Dcosα)fr10其中N为滚动体数量d为滚动体直径D为轴承节径α为接触角fr为旋转频率。4. 语音信号清浊音分离探索语音信号处理中清音unvoiced和浊音voiced的分离对语音识别和增强至关重要。VMD提供了一种新的时频分析思路。清浊音特征对比特征浊音清音周期性强周期性基频类似噪声能量分布集中在低频分布较均匀典型例子元音/a/、/i//s/、/f/import soundfile as sf from vmdpy import VMD import matplotlib.pyplot as plt import numpy as np # 读取语音样本建议使用实际录音 # voice, fs sf.read(speech.wav) # 这里使用模拟信号演示 fs 16000 t np.arange(0, 1, 1/fs) f0 100 # 基频 voiced 0.5 * np.sin(2*np.pi*f0*t) * (1 0.3*np.sin(2*np.pi*3*t)) unvoiced 0.2 * np.random.randn(len(t)) speech voiced unvoiced # 合成语音 # VMD参数语音信号特有设置 alpha 3000 # 适中带宽约束 tau 0.2 # 较高噪声容忍 K 2 # 清浊音二分类 DC 0 init 1 tol 1e-6 # 执行分解 imfs, _, _ VMD(speech, alpha, tau, K, DC, init, tol) # 时频分析 plt.figure(figsize(12,6)) plt.subplot(3,1,1) plt.specgram(speech, Fsfs, NFFT256) plt.title(Original Speech) plt.subplot(3,1,2) plt.specgram(imfs[0], Fsfs, NFFT256) plt.title(IMF1 (Voiced Component)) plt.subplot(3,1,3) plt.specgram(imfs[1], Fsfs, NFFT256) plt.title(IMF2 (Unvoiced Component)) plt.tight_layout() plt.show()语音处理中的VMD技巧基频估计从第一个IMF中提取基频轮廓声门波分析使用第二个IMF重建声门激励信号噪声抑制将识别为清音的IMF进行降噪处理参数调整根据说话人性别调整alpha男性更低女性更高5. 二维VMD在图像纹理分析中的扩展传统VMD处理一维信号但其核心思想可扩展至二维图像处理特别适用于纹理分析和图像分离任务。图像VMD原理将图像视为二维信号定义二维变分模型通过交替方向乘子法ADMM求解得到若干二维IMF分量import numpy as np import matplotlib.pyplot as plt from PIL import Image from vmdpy import VMD_2D # 假设存在二维VMD实现 # 加载测试图像 img np.array(Image.open(texture.jpg).convert(L)) / 255.0 # 灰度归一化 # 二维VMD参数 alpha 1000 # 带宽参数 K 3 # 分解层数 DC 0 # 是否包含直流分量 tol 1e-7 # 收敛容差 max_iter 500 # 最大迭代次数 # 执行二维VMD imfs_2d VMD_2D(img, alpha, K, DC, tol, max_iter) # 显示分解结果 plt.figure(figsize(12,8)) plt.subplot(2,2,1) plt.imshow(img, cmapgray) plt.title(Original Image) for i in range(K): plt.subplot(2,2,i2) plt.imshow(imfs_2d[i], cmapgray) plt.title(f2D-IMF {i1}) plt.tight_layout() plt.show()图像VMD应用场景纹理分类不同纹理对应不同IMF能量分布缺陷检测异常区域在特定IMF中显现图像增强分离并强化目标频带医学图像分析如X光片中不同组织的分离实际项目中我们曾使用二维VMD成功分离了金属表面的划痕特征在IMF2中表现明显而传统方法如小波变换难以实现这种精确分离。

更多文章