VMD-SVM-GWO,基于变分模态分解的灰狼算法优化支持向量机的时间序列预测 直接从Excel中导入数据即可运行,代码注释清晰,适合初学者 在该框架下,可实现 1)GWO算法的改进(领域搜索策略改进灰狼算法,非线性映射改进); 2)基于差分算法DE,鲸鱼算法WOA,麻雀算法SSA、蜣螂算法等的SVM参数优化 3)基于EMD、EMD、CEEMD的分解预测
import pandas as pd from vmdpy import VMD # 从Excel读取数据(记得把文件扔到同一目录) raw_data = pd.read_excel('your_time_series.xlsx', header=None).values.flatten() # VMD分解参数设置 alpha = 2000 # 惩罚因子 tau = 0.1 # 噪声容忍度 K = 5 # 分解模态数 DC = 0 # 是否包含直流分量 init = 1 # 初始化方式 tol = 1e-7 # 收敛阈值 # 执行VMD分解 imfs, _, _ = VMD(raw_data, alpha, tau, K, DC, init, tol)这里有个坑要注意:K值别设太大,不然分解出的模态可能包含大量噪声。建议先用官方示例数据测试,摸清规律再上真实数据。
接下来是重头戏——灰狼算法优化SVM。咱们直接看GWO怎么和SVM参数对接:
from sklearn.svm import SVR def gwo_objective(params): C, gamma = params model = SVR(kernel='rbf', C=C, gamma=gamma) # 交叉验证代码略... return -val_score # 负值因为我们要最大化准确率 # GWO核心更新逻辑 def update_position(alpha_pos, beta_pos, delta_pos, current_pos): a = 2 - iter*(2/max_iter) # 非线性收敛因子 A1 = 2*a*np.random.rand() - a C1 = 2*np.random.rand() D_alpha = abs(C1*alpha_pos - current_pos) X1 = alpha_pos - A1*D_alpha # 类似地更新X2,X3... return (X1+X2+X3)/3 # 位置加权平均重点来了!传统GWO容易陷入局部最优,咱们加个领域扰动策略:
# 在位置更新后增加扰动 if np.random.rand() < 0.1: # 10%概率触发 new_pos = current_pos + 0.5*(np.random.randn()*(ub-lb)) new_pos = np.clip(new_pos, lb, ub)预测阶段要特别注意模态重构顺序。这里有个实用技巧——动态权重分配:
# 对各IMF分量预测结果进行加权融合 dynamic_weights = np.array([0.2, 0.3, 0.25, 0.15, 0.1]) # 需根据熵值计算调整 final_prediction = np.sum(predictions * dynamic_weights, axis=0)想换优化算法?简单!比如改用鲸鱼算法WOA:
def woa_update(position, best_pos, a, b=1): r = np.random.rand() if r < 0.5: # 包围猎物 D = abs(2*r*best_pos - position) return best_pos - a*D else: # 气泡网攻击 D = abs(best_pos - position) return D*np.exp(b)*np.cos(2*np.pi*b) + best_pos对于不同分解方法,建议封装成统一接口:
def decompose_signal(method='vmd', signal=None, **kwargs): if method == 'vmd': return VMD(signal, **kwargs) elif method == 'ceemd': from PyEMD import CEEMDAN return CEEMDAN().ceemdan(signal) # 其他分解方法扩展...最后来个效果对比彩蛋:
plt.plot(test_data, label='真实值') plt.plot(vmd_svm_gwo_pred, linestyle='--', label='VMD-SVM-GWO') plt.plot(ceemd_ssa_pred, ':', label='CEEMD-SSA') plt.legend() plt.title('不同算法预测效果对比') plt.show()注意几个实践要点:
- 数据归一化要放在分解前做
- IMF数量建议通过观察频谱确定
- 参数搜索范围设置:C取2^-5到2^15,gamma取2^-15到2^3
这个框架最大的优势是模块化设计,想换哪个部分直接替换对应模块就行。比如今天想试试蜣螂算法,只需要把优化器换成DBO类,其他部分完全不用动!