【优化算法】VMD分解算法的16种优化,对K和alpha参数寻优,附MATLAB代码

66 篇文章 94 订阅
2 篇文章 1 订阅

在上一篇文章中,我们介绍了优化算法的基本原理和一些常见的生物启发式算法。另外我们封装了一个16合1的寻优函数。

不过在上一篇中,我们举了一个简单的数值模型作为适应度函数的演示案例,然而在实际的研究中,适应度函数往往要复杂得多。本篇我们就以VMD算法的优化为例,讲一讲这种较为复杂的算法的寻优该怎么做,此外我还提供了修改好的VMD寻优代码,供大家参考使用!

一、为什么要对VMD做参数寻优

在一众的类EMD算法中,对于EMD、EEMD、CEEMD等等这些无法指定分解模态数的算法,经常有同学问我该怎样指定模态数量;当我告诉大家需要使用VMD才能制定模态数量K时,更多的是问我K值该怎么取。人类就是这么的纠结。

今天这篇文章就可以解答这个疑问了。话说回来,K的选取确实比较重要,K 的取值直接决定了分解后的模态分量的数目,若 K 设置得过大,会造成欠分解产生虚假模态;若 K 设置得偏小,会造成欠分解不能充分提取时间序列隐含特征。

此外惩罚因子alpha对分解结果也有重要影响,alpha的取值影响了模态分量的带宽,与带宽成反比,若alpha设置较小,则会出现模态混叠影响特征提取;若alpha设置较大,虽然能避免模态混叠但又造成了局部信息丢失的问题。

在有些研究中,对K和alpha的取值问题,会采用多次实验选取预测/分类效果最优值,但是这十分依赖研究人员的主观判断,缺乏客观的评判标准。因此,对VMD的参数进行优化是十分必要的。

二、VMD寻优的参数和适应度函数

1.待优化参数

就像上边所说,分解模态数K和惩罚因子alpha是比较关键的两个参数。其实还有第三个常用参数tol,不过因为tol对分解结果的影响相对较小,所以在本文中,不将tol作为寻优对象参数。

2.适应度函数

对VMD参数选择优化的关键是适应度函数的设置,用来对分解效果制定量化指标来衡量参数选择的优劣。

纵观众多论文,VMD基本都是使用的信息熵作为适应度函数[1]

在之前的文章中讲过,信息熵越大,代表不确定性越大,信号中包含的信息量越少。

所以为了最大程度地提取出有效信息,就需要让分解出的各个模态的平均信息熵最小。

至于“信息熵”的具体类型选择就比较多了,我们之前讲过的功率谱熵、奇异谱熵、能量熵近似熵样本熵、模糊熵、排列熵,都可以选择。

三、应用kOptimizationAlgorithm函数实现16种优化算法寻优

有了上述定义,我们就可以利用kOptimizationAlgorithm函数来实现对VMD参数的自动寻优了。具体步骤如下:

3.1 定义适应度函数

下边是改好的适应度函数,其中tol值指定为1*10-6。适应度函数主要就三步:

第一步进行VMD分解,这里调用了之前封装过的kVMD函数,当然这里直接用MATLAB的vmd函数也可以,但是需要注意转置,因为MATLAB官方vmd函数得到的imf是按列方向排列的。

第二步是提取各个imf分量的排列熵特征,这里也使用了之前封装的熵特征提取函数,只需要指定一下熵类型名称以及必要的参数设置就行,大家可以更换这一步的熵类型,但是需要注意option也需要对应调整,具体设置方式可以参考这里:(功率谱熵、奇异谱熵、能量熵近似熵样本熵、模糊熵、排列熵

第三步是求各个imf分量的排列熵的均值,并将其作为适应度函数值。

%% 适应度函数,此代码需要根据应用场景做适应性修改
function [fitness] = funFitness(x,dataforFitness)
% 输入:
% x是待优化参数,为数组。x(1)是第一个待优化参数,x(2)是第二个,以此类推。
% dataforFitness为结构体,表示导入到适应度函数的参数,按照数据实际情况设置。可以没有
% 输出:
% fitness是适应度函数
%%
% 待寻优参数读取,注意此处可能有些参数必须为整型,需要取整
alpha = round(x(1)); %alpha 
K = round(x(2)); %K
% 导入数据读取
FsOrT = dataforFitness.fs;
data  = dataforFitness.data;
try
    % 定义目标函数
    tol = 1e-6;
    [imf,CenFs]  = kVMD(data,FsOrT, alpha, K, tol);


    % 设置排列熵参数,Pedim为排列熵模式维度,Pet为排列熵的时间延迟,如果不提取排列熵特征可以删除以下两行
    option.Pedim = 6;
    option.Pet   = 1;
    featureNamesCell = {'PeEn'}; %要进行特征提取的特征名称,可以根据实际需要进行删减,留下的特征注意拼写正确
    fea = genFeatureEn(imf,featureNamesCell,option);  %调用genFeature函数,完成特征提取,算出的特征值会保存在fea变量里
                                             
    fitness = mean(fea);

    
catch ME 
    fprintf('发生错误: %s\n', ME.message);
end
end

3.2 设置寻优相关参数

以下代码是写在主程序里的了,必要的参数我都将其作为可调参数抽取出来了,大家可以根据需要进行调整,每个参数的含义在注释里标明了,这里不再赘述。

%% 1.设置寻优相关参数
dim = 2;             % 优化参数的个数,这里设定为2,表示有两个需要寻优的参数
lb = [100,2];        % 定义每个优化参数的取值下限,这里的写法代表:alpha下限设置为100,K下限设置为2
ub = [10000,10];     % 定义每个优化参数的取值上限,这里的写法代表:alpha上限设置为10000,K上限设置为10
OAmethod = 'SSA';    % 选择使用的优化算法,这里使用'SSA'即麻雀搜索算法
pop = 3;             % 设置优化算法的种群大小
Max_iteration = 40;  % 设置优化算法的最大迭代次数

3.3 调用kOptimizationAlgorithm函数实现寻优

以下代码也是写在主程序里,dataforFitness作为结构体用于传递必要的数值,这样做大大提升了代码的灵活性和简洁性,采样频率要根据你的信号情况设置(长周期信号设置为1);dataforFitness.data则是要将你待分解信号的变量名赋值给他。最后一行直接调用即可实现寻优了。

%% 2.调用优化算法函数,传入上述定义的参数
dataforFitness.fs = 1000;  %设置采样频率
dataforFitness.data = x;   %设置待分解信号
% 返回最优位置Best_pos,最优适应度值Best_score,迭代过程的适应度曲线curve
[Best_pos,Best_score,curve] = kOptimizationAlgorithm(OAmethod, dataforFitness, lb, ub, dim, pop, Max_iteration);

3.4 运行结果

运行完上述程序,将会得到以下结果:

参数寻优结果分别为:2885,4
最佳适应度值为:0.19814
程序运行时间:23.471秒。

如果想尝试其他优化算法,只需要修改OAmethod参数即可。例如改为'GWO'就可以切换为灰狼优化算法。

在实际应用中,我们可以多试几种算法,比较它们的性能,选择最优的一种。同时也可以调整种群数量和迭代次数等参数,权衡计算效率和优化效果。

四、小结

以上是对上篇文章中一行代码实现16种优化算法在VMD算法上的演示,同时也是因为VMD寻优是大家比较常用的一种场景。大家在使用优化算法应用到其他场景时,希望上述文章对大家能有所启发。

当然了,上边VMD寻优的代码我也打包好了,同学们可以在公众号 khscience(看海的城堡)中回复“VMD优化”获取。

参考

  1. ^[1]晋孟雪.基于改进VMD和深度学习的风电功率预测研究[D].西安理工大学,2023.DOI:10.27398/d.cnki.gxalu.2023.002010.
  • 10
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
变分模态分解算法VMD)可以通过使用粒子群算法(PSO)来调整其参数,以优化其性能。以下是一个使用MATLAB实现的示例代码: 首先,我们需要定义一个适应度函数,用于评估每个粒子的性能。在这个例子中,我们使用VMD算法分解原始信号并计算能量。 ```matlab function fitness = VMD_PSO_fitness(particle, X) % particle: 粒子位置 % X: 原始信号 % fitness: 粒子适应度 alpha = particle(1); % 参数alpha tau = particle(2); % 参数tau K = round(particle(3)); % 参数K % 使用VMD分解原始信号 [u, ~] = VMD(X, alpha, tau, K); % 计算分解信号的能量 E = sum(u.^2); % 适应度函数为能量的倒数(目标是最小化能量) fitness = 1/E; end ``` 接下来,我们需要定义一个PSO优化函数,用于优化VMD算法参数。 ```matlab function [best_particle, best_fitness] = VMD_PSO(X, max_iter, swarm_size) % X: 原始信号 % max_iter: 最大迭代次数 % swarm_size: 粒子群大小 % best_particle: 最佳粒子位置 % best_fitness: 最佳适应度 % 粒子位置的边界 lb = [0.1, 0.1, 2]; ub = [1, 1, 10]; % 初始化粒子群 particle = repmat(lb, swarm_size, 1) + rand(swarm_size, 3) .* (repmat(ub, swarm_size, 1) - repmat(lb, swarm_size, 1)); velocity = zeros(swarm_size, 3); pbest = particle; pbest_fitness = zeros(swarm_size, 1); % 计算初始适应度 for i = 1:swarm_size pbest_fitness(i) = VMD_PSO_fitness(pbest(i,:), X); end % 找到全局最佳位置 [best_fitness, gbest_index] = min(pbest_fitness); gbest = pbest(gbest_index,:); % 开始迭代 for iter = 1:max_iter % 更新粒子位置和速度 for i = 1:swarm_size % 更新速度 velocity(i,:) = velocity(i,:) + rand(1,3) .* (pbest(i,:) - particle(i,:)) + rand(1,3) .* (gbest - particle(i,:)); % 限制速度范围 velocity(i,:) = min(velocity(i,:), ub - particle(i,:)); velocity(i,:) = max(velocity(i,:), lb - particle(i,:)); % 更新位置 particle(i,:) = particle(i,:) + velocity(i,:); % 限制位置范围 particle(i,:) = min(particle(i,:), ub); particle(i,:) = max(particle(i,:), lb); end % 计算适应度 for i = 1:swarm_size fitness = VMD_PSO_fitness(particle(i,:), X); % 更新个体最佳位置 if fitness > pbest_fitness(i) pbest(i,:) = particle(i,:); pbest_fitness(i) = fitness; end % 更新全局最佳位置 if fitness > best_fitness gbest = particle(i,:); best_fitness = fitness; end end end % 返回最佳粒子位置和最佳适应度 best_particle = gbest; best_fitness = 1/best_fitness; end ``` 最后,我们可以使用以下代码来测试VMD算法的性能: ```matlab % 生成测试信号 N = 500; t = linspace(0,1,N); X = sin(2*pi*5*t) + sin(2*pi*10*t) + sin(2*pi*15*t); % 使用PSO优化VMD算法参数 max_iter = 50; swarm_size = 20; [best_particle, best_fitness] = VMD_PSO(X, max_iter, swarm_size); % 使用优化后的参数进行VMD分解 alpha = best_particle(1); tau = best_particle(2); K = round(best_particle(3)); [u, ~] = VMD(X, alpha, tau, K); % 绘制分解后的信号 figure; subplot(2,1,1); plot(t,X); title('Original Signal'); subplot(2,1,2); plot(t,u); title('VMD Decomposition'); ``` 这段代码将生成一个包含三个正弦波的测试信号,并使用PSO算法找到最佳的VMD参数进行分解。最后,它将绘制原始信号和分解后的信号。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.看海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值