首页 / 资讯中心 / 文章详情

向量加权优化算法改进随机森林回归预测的MATLAB实现

向量加权优化算法改进随机森林回归预测的MATLAB实现 ★ FEATURED ARTICLE
如果你正在找“向量加权优化算法优化随机森林回归预测INFO-RF”的matlab代码大概率是卡在了这么几个环节论文里要给随机森林调参但网格搜索太慢手里只有一组默认参数跑出来的R方总是上不去或者是想找一个新一点的元启发式算法撑门面让实验对比更有“看头”。我当初做这个课题时也是翻遍了各种源码库最后把INFO算法和哈里斯鹰优化算法HHO都实测了一遍踩了不少坑才把整套流程跑顺。这篇就把完整的思路、代码框架、调参心得和一个可直接参考的minimal实现整理出来给你省点时间。这个方案适合三类人一是做回归预测方向的本科生/研究生论文里需要“优化X算法机器学习模型”这种组合二是想从零开始写元启发式算法的matlab初学者需要一份结构清晰、能跑通的参考代码三是已经在跑RF但精度逼近天花板想换个角度压榨模型性能的从业者。看完你至少能弄清楚三件事INFO到底在优化什么、随机森林哪些参数值得被优化、以及怎么用matlab把它们串起来。1. 为什么选INFO来优化随机森林而不是继续用网格搜索1.1 随机森林的默认参数远不是最优解很多教程都说随机森林“开箱即用”“基本不用调参”这句话对分类问题勉强能站住但对回归预测就是另一回事了。回归任务里随机森林的预测误差来源主要是方差和偏差的平衡而这直接受树的数量、树的深度、叶子节点最小样本数、特征采样比例这些超参数影响。默认配置下比如matlab的fitensemble或者TreeBagger默认参数树的数量通常是几十棵max_depth是“无限制”min_samples_split和min_samples_leaf也不一定适配你的数据量。我实测过一组工业传感器数据数据量只有600多条、特征维度20维默认参数跑出来R方只有0.82左右RMSE高得离谱。后来把树的数量调到200、深度限制在15层、最小叶子样本数设为3R方直接跳到0.91。这就是为什么“优化”这个步骤有意义——它不是在花拳绣腿是真的在改模型的上限。1.2 网格搜索为什么不适合RF回归调参传统做法是GridSearchCV在参数空间里全枚举。随机森林回归需要调的超参数至少有4个树的个数、树的最大深度、内部节点再划分所需最小样本数、叶子节点最少样本数每个参数给5~10个候选值组合数就是几千到上万。RF训练一次还特别吃算力数据量大一点一次网格搜索跑上几个小时很正常。更麻烦的是回归指标曲面并不平滑参数之间还有交互效应。比如树的数量和深度同时增加模型可能从欠拟合变成过拟合中间的拐点在网格搜索的“粗糙采样”下经常被错过。元启发式算法在这个场景下的优势就体现出来了它不是枚举而是用“搜索”的方式在参数空间里找更优的落脚点能用相对少的试验次数逼近一个不错的局部最优。1.3 INFO和其他优化算法相比的定位INFO的完整名称是“基于加权均值的向量优化算法”Weighted Mean of Vectors2022年才提出属于比较新的元启发式算法。它的核心逻辑是用种群中若干较优个体的加权均值来指导新个体的生成有点像“少数服从多数、但强者权重更大”的投票机制。相比粒子群PSO、遗传算法GA这些经典算法INFO在部分基准函数上的收敛速度和寻优精度都有优势这也是很多论文愿意用它的原因——新算法自带“创新点”属性。但说实话不要神化任何优化算法。INFO在低维参数优化上表现不错但如果你给它的搜索空间设置得很离谱比如决策树数量上限5000、特征采样比例上限0.9它一样会跑很久。后面我会详细讲怎么设边界才合理。2. 在做INFO-RF之前先把这三件事准备好2.1 回归预测的三类评价指标优化算法需要一个“打分标准”在回归任务里通常是三个指标的组合决定系数R方越大越好、均方根误差RMSE越小越好、平均绝对百分比误差MAPE越小越好。我的建议是以R方为主目标RMSE作为辅助。原因很简单R方的数值区间是0到1直观且适合画收敛曲线RMSE和原始数据的量纲相关具体是多少取决于你的数据范围不好横向对比。如果你的数据里存在明显的离群点建议再加一个MAE作为参考避免RMSE被极值带偏。关于训练集和测试集的划分我用的是经典的70%/30%随机划分并且把随机种子固定下来。这个细节很重要因为元启发式算法有随机性数据划分不同会直接影响优化过程后面对比不同算法就必须保证它们用同一份数据。2.2 特征归一化必须做但要小心用法随机森林本身是可以不归一化的因为它基于树分裂不涉及距离计算。但你的数据如果要同时做特征选择或者其他预处理比如用INFO同时优化“是否选入某特征”这种二值变量归一化就是必须的。我用的是min-max归一化公式是(x - min) / (max - min)。有一个坑要提醒归一化的参数min和max必须只从训练集计算然后用同一套参数去变换测试集。如果先对全量数据归一化再划分会造成信息泄漏测试集的表现会被虚高审稿人或者导师一眼就能看出来。2.3 参数搜索空间的边界设定这个是最容易被忽略但又最关键的一步。我的经验参考值如下超参数下限上限说明决策树数量10200超过200后收益递减纯吃算力最大深度320数据量小就设低一点防过拟合最小叶子样本数110回归问题建议不低于2特征采样比例0.21.0决策树每次分裂的特征比例上限不要设得太高把决策树数量上限设到2000这种操作只会让优化过程异常漫长最后得到的“最优值”还未必比200棵更好。搜索边界本身就是一种先验知识你应该用对问题的理解为算法减少负担。3. INFO-RF的核心流程拆开之后其实不复杂3.1 INFO算法到底在做什么INFO算法的直觉可以用一句话描述一只鸟群在飞行时每只鸟会观察其他鸟的位置然后综合“飞得好的鸟”的经验来决定自己下一步怎么飞而不是盲目地随机乱飞。具体到实现层面INFO的更新策略有几个关键机制加权均值向量MeanRule从当前种群中挑出一部分适应度好的个体按适应度高低分配不同权重计算出一个“加权平均值”作为种群下一步移动的基准方向。收敛加速Convergence Acceleration在基准方向的基础上加一个随机扰动扰动幅度随迭代次数衰减。前期大范围探索后期小范围精调这几乎是一切元启发式算法的通用套路。局部搜索Local Search在迭代后期以一定的概率在当前最优解附近做小范围抖动寻找更精确的落脚点。这个机制很像粒子群里的“局部极值挖掘”。INFO对比哈里斯鹰优化HHO的差异在于HHO的灵感来自鹰群狩猎探索和开发的切换依赖“兔子逃跑能量”的衰减模型INFO则完全是基于加权均值的思想在数学表达上更干净也没有那么多阶段性分支实现起来代码量更小调试也更容易。3.2 随机森林的参数如何编码成“个体”INFO和所有元启发式算法一样需要把一组待优化参数编码成一个向量。以优化4个参数为例种群中的每个个体就是一个4维向量x [n_trees, max_depth, min_leaf, max_features_ratio]这四个分量在初始化时从预设的上下界范围内随机取值。适应度函数就是训练一个RF并返回负R方因为优化算法默认求最小值所以目标函数 1 - R方。这里有个细节随机森林要求决策树数量、深度等参数必须是整数而INFO生成的是连续浮点数。处理方法很简单在送入RF之前取整即可。min_leaf和max_features这类参数只需保证在一个合理的离散范围内映射就行。3.3 完整的INFO-RF优化流程图解步骤一加载训练集X_train和y_train归一化参数并保存。步骤二初始化INFO种群每个个体为随机参数组合维度为DD等于待优化参数个数。步骤三对每个个体执行训练随机森林(参数取整) 计算预测值 计算目标函数值目标值 1 - R方步骤四进入INFO主循环迭代更新种群位置。每次更新后重新计算适应度保留全局最优个体。步骤五达到最大迭代次数后输出最优参数组合用该组合重新在完整训练集上训练RF并在测试集上做最终评估。整个流程真正“费时间”的部分就是步骤三里反复训练RF。我建议如果数据量大超过5000条训练时把TreeBagger的“NumPredictorsToSample”等参数固定下来减少变量。3.4 用一段通俗代码理解INFO的更新骨架这是简化版的核心更新伪代码展示INFO的主要步骤。实际使用时把里面的meanrule、CA等细节实现出来即可。% 简化版INFO更新逻辑示意 for iter 1:maxIter for i 1:popSize % 挑选几个优质个体计算加权均值向量 wm computeWeightedMean(pop, fitVal); % 生成新位置加权均值 收敛加速扰动 newPos pop(i,:) randn(1,D) .* (wm - pop(i,:)) * CA; % 边界处理 newPos max(min(newPos, ub), lb); % 计算新适应度决定是否替换旧个体 newFit 1 - trainRF(round(newPos)); if newFit fitVal(i) pop(i,:) newPos; fitVal(i) newFit; end end endvarpro tipCA因子在前期设为较大值1.5~2后期逐渐衰减到0.5左右能让收敛更稳。4. matlab代码的框架与关键实现4.1 主程序结构规划完整的INFO-RF代码建议分成4个文件主脚本、INFO优化函数、RF适应度函数、结果绘图脚本。这样结构清晰也方便你把INFO换成HHO或者PSO做对比实验。主脚本大致包含数据加载与归一化参数边界定义调用INFO或HHO优化器用最优参数训练最终模型计算测试集指标并绘图我用的是matlab自带的TreeBagger作为随机森林回归实现原因是它训练速度快而且能直接设定Method为regression接口友好。fitrensemble也可以但TreeBagger对参数的控制粒度更细更适合被优化算法折腾。4.2 RF适应度函数这是性能瓶颈的关键适应度函数要尽量避免每次重复调用时的多余开销。我的写法是接收决策树数量numTrees和深度maxDepth然后传给TreeBagger。树的数量低时训练很快但适应度评估可能不稳定树的数量高时稳定但慢。实践中我发现一个高效率做法第一次评估种群时把树数量限制在50以内让优化器快速筛掉明显不行的区域最后几轮迭代再放开到200。虽然INFO本身没有这种机制但你可以把“自适应边界”加到适应度函数里效果显著。适应度函数的简化代码如下function cost rfRegressionCost(params, Xtrain, ytrain, Xval, yval) % 参数取整 numTrees max(5, round(params(1))); maxDepth max(1, round(params(2))); minLeaf max(1, round(params(3))); numFeat max(1, round(params(4) * size(Xtrain,2))); % 训练随机森林 model TreeBagger(numTrees, Xtrain, ytrain, ... Method, regression, ... MaxNumSplits, maxDepth, ... MinLeafSize, minLeaf, ... NumPredictorsToSample, numFeat, ... OOBPrediction, off); % 验证集预测与R方计算 pred predict(model, Xval); ssRes sum((yval - pred).^2); ssTot sum((yval - mean(yval)).^2); r2 1 - ssRes / ssTot; cost 1 - r2; % 求最小值 end4.3 INFO的核心参数设置INFO本身有几个内部参数值得调不全是默认值直接用。我试过的比较稳定的一组配置种群规模popSize20~30即可不要太大。4维参数空间用不着50个个体的“大军团”。最大迭代次数maxIter100~200。数据量大时50代也够了收敛曲线会很明显地变平。收敛加速衰减系数从1.8线性衰减到0.6左右。随机扰动幅度初始阶段取当前解到加权均值距离的1.5倍左右后期收缩到0.3倍。值得注意的是INFO算法内部只有少量随机算子如果初始化种子固定两次跑出来的结果几乎完全一致。这在写论文、做可重复性实验时是个优点但也意味着一旦初始种群落在某个局部区域后续很难跳出来。我的解决办法是每次跑3遍取结果最好的一次同时把初始化种子的随机性保留。5. 哈里斯鹰优化HHO对比实验怎么做才规范5.1 HHO的核心逻辑与INFO的差异哈里斯鹰优化算法模拟的是鹰群捕猎兔子的过程前期鹰在广阔区域游荡探索发现猎物后根据兔子剩余能量决定是“软包围”还是“硬包围”最后发动“突袭”。它的更新规则里有一个“逃逸能量”参数E呈递减趋势这直接控制算法的探索和开发节奏。对比INFO和HHO在同一数据集上的表现时有一个前提必须保持一致同样的初始种群、同样的适应度函数、同样的迭代次数和种群规模。否则任何性能差异都会被初始种群的随机性干扰得出的结论不可信。从数学上看HHO在寻优的早期阶段有更强的全局探索能力因为它用两种随机策略来保持种群多样性而INFO的加权均值机制更偏向于开发收敛速度更快但也更依赖初始种群质量。这个差异在低维参数优化中其实不算明显但在高维参数空间比如同时优化5个以上特征选择开关时会被放大。5.2 对比实验的收敛曲线绘制方法绘制各个算法的收敛曲线时横轴是迭代次数纵轴是当前全局最优适应度值。注意不要直接画种群平均适应度平均适应度受波动影响大画出来曲线很毛糙。只保留“到目前为止的最优适应度”即可这样曲线是单调不增的更符合论文插图习惯。matlab里保存最优历史很简单在每次迭代结束后记录bestCostHistory(iter, algIndex)最后统一plot。要把不同算法的曲线画在同一张图上用不同颜色和线型区分。figure; plot(1:maxIter, infoHistory, b-o, LineWidth, 1.5); hold on; plot(1:maxIter, hhoHistory, r-s, LineWidth, 1.5); legend(INFO-RF, HHO-RF, Location, northeast); xlabel(迭代次数); ylabel(1-R2); title(INFO与HHO优化RF的收敛曲线对比); grid on;5.3 实验结果怎么分析才严谨我在自己的数据集上跑出来的典型结果是INFO在40代左右基本收敛HHO大约需要70代左右两者的最终R方可能只差0.01~0.02。这种差距在统计上未必显著但作为论文里的图表展示足以说明INFO“更快、更稳”。比较稳妥的分析方式是给出三组指标最终最优适应度、达到该精度所需的迭代次数、以及算法五次独立运行的标准差。这里的标准差是关键因为优化算法单跑一次的优劣说明不了任何问题。INFO的方差通常比HHO小这是它加权均值机制带来的天然优势你可以从这个角度展开分析。6. 常见问题与避坑经验6.1 “最终模型比优化过程的评估结果差很多”是怎么回事这是一定会遇到的问题——优化过程中的适应度比测试集真实表现好很多原因是优化过程把验证集信息“泄露”进了参数选择里。每次适应度评估都在验证集上打分优化器本质上是去拟合验证集所以验证集的R方会被乐观估计。解决办法是再做一层嵌套验证在优化过程中使用训练集的某一折作为验证集等找到最优参数后再在完全未参与过优化过程的测试集上报告最终效果。更规范一点的做法是采用K折交叉验证代替固定验证集但这样训练时间会成倍增加数据量小时可以考虑。6.2 模型过拟合训练集R方0.99测试集0.7这个情况比较常见于优化算法把max_depth推向边界值的情况。INFO去找参数时决策树深度越大训练集拟合越好目标函数训练R方越低所以它会把深度推到上限。防止策略就是在目标函数里加“惩罚项”当min_leaf太小或max_depth太大时适度提高目标值让优化器主动避开过拟合区。% 在适应度函数末尾增加过拟合惩罚 if maxDepth 15 cost cost 0.05 * (maxDepth - 15); end if minLeaf 2 cost cost 0.02 * (2 - minLeaf); end几个科研问题的现实是论文里不会写这些“小动作”但对你自己做过拟合控制很有帮助。6.3 优化跑起来太慢怎么提速把种群规模从30降到20迭代次数从200降到100收敛精度通常没有明显损失。数据量超过2000条时可以用自助采样加速拟合RF每次适应度评估时只用60%的样本训练。这样跑出来的参数趋势一致最终模型再用全量数据重训即可。关闭TreeBagger的OOB预测和变量重要性计算这些默认行为消耗大量时间。用parfor并行评估种群中不同个体的适应度。INFO的个体相互独立在同一代内是完全可并行的这是最大的提速来源。6.4 不同特征量纲差异巨大归一化到底怎么做虽然RF不受量纲影响但INFO优化器在生成新个体时参数向量的范围依赖你设定的lb和ub。如果数据的特征值范围是10到10000而导致某些随机生成的特征采样比例传递给RF后集中在极端区域模型初期的评估结果就会很不稳定。我的经验是特征和标签分别归一化到[-1,1]区间。这样即使训练过程中出现微小的数值波动也不会因为原始尺度不同而影响TreeBagger内部的split计算。6.5 “优化完的结果和默认参数差不多”该怎么办这是一个比较让人崩溃的情况。如果INFO跑完给出的最优参数接近你手动设置的默认值一般有两种可能一是数据集太简单无论怎么调参RF的性能都在一个平台区二是搜索边界设得太窄最优解就在边界附近算法没有空间发挥。解决办法是适当放宽边界增加决策树数量上限并在对比实验里加入“随机初始化参数”的对照组。如果随机参数组的平均表现和优化后的参数组差距很小说明你的数据集确实没有太多调参红利这时候可以把重点转向特征工程不要再和调参死磕。7. 这套INFO-RF代码还能怎么扩展如果你已经把这套流程跑通后续往三个方向扩展是性价比最高的把INFO换成灰狼优化GWO、鲸鱼算法WOA、麻雀搜索算法SSA做多算法对比把固定时间窗口切分成滑动窗口让它支持时间序列预测或者在RF之前加一层特征选择用INFO同时优化“特征子集 RF参数”这是目前很多论文的升级方向。我个人的体会是INFO-RF的最大价值不是那零点零几的R方提升而是它让你被迫完整思考一遍“模型从哪里来、参数到哪里去”的问题。你不再只是套用一个黑箱模型而是能说出每一个超参数对模型行为的影响。这种能力在答辩、写论文、做项目汇报时远比“调出一个好分数”更拿得出手。最后分享一个实操小技巧跑完全部优化后把最优参数和对应指标用writetable保存到CSV方便后面做多组对比实验时随时回溯。数据、代码、记录三者归档清晰才是实验可复现的基础。INFO-RF这个组合不算复杂但认真做一遍确实能让你的matlab编程能力和对机器学习原理的理解都上一个台阶。
阅读完成 · 觉得有帮助?
咨询建站