做回归预测的朋友应该都有这个体会:单输出的模型好找,随便调一个SVR或者神经网络都能跑;但一旦要同时预测多个目标——软测量里同时估计产品多个质量指标、风电功率预测里同时给出多台机组的输出、环境监测里同时预报多个污染物浓度——很多通用模型就开始别扭了。我今年一个项目正好被这种多输出数据回归预测卡了一段时间,最终落地方案是“北方苍鹰优化算法(NGO)+ 最小二乘支持向量机(LSSVM)”,整套流程跑通之后,预测精度和训练效率都达到预期。这篇文章把方案选型思路、融合原理、完整Matlab代码以及调试过程中踩过的坑都整理出来,给正在做多输出回归、或者打算给预测模型加一层自动寻优的朋友做个参考。
1. 用NGO-LSSVM解决多输出回归,到底解决的是什么
1.1 多输出回归的三个痛点
多输出回归(Multi-output Regression)在工业场景里比很多人想象的更常见。典型的情况是:输入一组工艺参数或传感器特征,需要同时输出几个相互关联的连续变量。最直观的做法是拆成多个单输出模型,每个输出维度单独训练一个LSSVM或者神经网络,最后把结果拼起来用。这个办法不是不行,但会带来三个问题。
第一个问题是模型管理成本陡增。输出维度是3、5个还勉强能接受,一旦到10个以上,就需要分别调参、分别存储、分别监控,后续上线维护非常痛苦。第二个问题是维度相关性被浪费。很多多输出场景里,目标变量之间是强相关的,比如水泥质量指标里的抗压强度和抗折强度,它们受同样的原料和养护条件影响,单输出模型各自为政,相当于把相关结构扔掉了一部分。第三个问题是小样本非线性场景下,线性回归根本顶不住,而普通SVM和神经网络的参数敏感性又很高,不调好就翻车。
LSSVM天然适合这种中等到偏小样本、非线性、特征维度不低的问题。它对高维特征的处理能力比传统线性模型强不少,训练过程因为是解线性方程组,速度也比标准SVM快。而NGO负责解决LSSVM最让人头疼的超参数选择问题——惩罚系数γ和核宽σ怎么定。选这两个参数用网格搜索太慢,用遗传算法又有一堆交叉变异算子要调,最后我选了结构更精简的NGO,优化出来的参数稳定性和收敛速度都令人满意。
1.2 LSSVM在回归预测里的优势与短板
LSSVM是支持向量机的变体,核心改动是把标准SVM的不等式约束换成了等式约束。标准SVM求解的是一个凸二次规划问题,而LSSVM只需要求解一个线性方程组,训练复杂度明显降下来。回归场景下,LSSVM通过核函数把输入映射到高维特征空间,在高维空间里做线性回归,本质上是把非线性问题“曲线救国”掉了。
模型的优化目标可以写成:
min J(w, b, e) = (1/2)*||w||^2 + (γ/2)*Σ e_i^2 约束:y_i = w^T * φ(x_i) + b + e_i这里的γ是惩罚系数,e_i是预测误差。引入拉格朗日乘子并求KKT条件之后,问题化简成求解一个线性方程组,输入样本的核矩阵直接参与运算:
[ 0 1^T ] [ b ] [ 0 ] [ 1 Ω + I/γ ] [ α ] = [ y ]其中Ω_ij = K(x_i, x_j)是核矩阵,我这种场景下用RBF核为主:K(x_i, x_j) = exp(-||x_i - x_j||² / (2σ²))。LSSVM所有样本的α都不为零,不具备标准SVM的稀疏性,所以样本量特别大时它会有压力。但在几千条级别的工业数据上,这个短板完全不明显。
LSSVM最大的短板反而是参数太敏感。γ直接控制模型对误差的容忍度,γ大了容易过拟合,γ小了模型太“佛系”;σ决定核函数的视野范围,σ太小预测结果振荡厉害,σ太大整个模型退化成近似线性。这两个参数一旦不合适,效果可以从优秀跌到一塌糊涂,这也是我把NGO拉进来的直接原因。
1.3 为什么是北方苍鹰优化算法,而不是PSO或GA
参数寻优可以选很多算法:粒子群(PSO)、遗传算法(GA)、差分进化(DE)、灰狼优化(GWO)都用过。PSO最普遍,收敛快,但在我这个任务里容易出现早熟——一两个个体跑到局部热点附近,整个群被“带偏”,γ和σ的组合停在次优解上。GA胜在全局搜索能力,但交叉率和变异率的设定本身就需要经验,等于多了一组超参数要拍脑袋。GWO结构简单,但搜索后期群体多样性不够,有时精细搜索不到位。
NGO是近几年提出的新型元启发式算法,模拟北方苍鹰捕猎时的两个行为阶段:随机发现并追击猎物的阶段是全局探索,在目标附近环绕包抄的阶段是局部开发。它最合我心意的地方是结构简单、没有交叉概率变异概率这些额外参数,种群规模N、迭代次数T就是主要设置项,很适合跟LSSVM这种“两个决策变量”的小规模优化问题配对。
在实际对比里,相同迭代次数下,NGO找到的参数组合在交叉验证误差上比PSO平均低了几个百分点,收敛曲线的中后期下降也比PSO更有后劲。不同数据集上表现未必完全一致,但作为通用方案,NGO确实值得放进候选池。
2. 融合原理:苍鹰怎么捕猎,LSSVM怎么打工
2.1 NGO第一阶段:随机锁定猎物做全局探索
NGO的第一阶段对应苍鹰在高空随机发现一只猎物并俯冲追击的过程。算法中每个个体都会随机选择群体里的另一个体作为“猎物”,然后按照这个公式更新自己的位置:
P_i = X_k, 其中 k 是从 [1,N] 随机选取且 k ≠ i X_i_new = X_i + r * (P_i - I * X_i)r是[0,1]之间的随机数,I随机取1或2,用来模拟苍鹰追击过程中速度变化带来的位置波动。这个阶段的核心价值是全局探索:因为每个个体随机参考群体里其他个体的位置,种群不容易抱团困在同一个区域,可以有效覆盖参数空间。用大白话理解就是“先满地图飞,看哪一片有兔子”。
判断是否接受新位置用贪心策略:如果新位置算出来的适应度更优,就替换;否则保留原位置。这种简单直接的选择方式省掉了额外算子,也保证了种群整体质量只升不降。需要说明的是,阶段一里的随机猎物选择意味着算法在早期具备强随机性,收敛曲线前期往往比较抖,但这对避免过早陷入局部最优是好事。
2.2 NGO第二阶段:小范围环绕追击做局部开发
第二阶段模拟苍鹰已经锁定猎物、准备在目标周围迂回攻击的行为。在这个阶段,算法用当前最优个体位置近似代表“猎物位置”,然后在其邻域内精细搜索:
R = 0.02 * (1 - t / T) X_i_new = X_i + r1 * (R * X_prey - r2 * X_i)t是当前迭代次数,T是最大迭代次数,R会随着迭代推进从0.02逐渐收缩到接近0,意思是搜索半径随时间变小,前期在猎物周围摆放的位置范围大一些,后期越来越集中于最优解附近。r1和r2都是[0,1]随机数,用于引入一定的随机扰动。
这个机制跟“退火”思路有点像:先用粗粒度搜索定位热点区域,再利用收缩的邻域做精细打磨。把这个放在LSSVM参数优化里说,就是前期NGO尝试不同量级的γ和σ组合,后期集中在一个非常窄的区间内微调,把交叉验证误差一点点压下去。相对于PSO那种全局引导、开发方式单一的思路,NGO这种两段式结构在二维参数空间里往往搜得更干净。
2.3 LSSVM的两个超参数对预测结果的影响
把γ和σ找清楚是NGO的核心任务。γ又叫正则化参数,控制“模型复杂度和训练误差的折中”。可以把γ理解成老师对学生纪律的要求:γ很大,模型对每一个训练样本都极其较真,恨不得把噪声也拟合进去,测试集上容易过拟合;γ很小,模型对误差睁一只眼闭一只眼,整体变得欠拟合,预测曲线偏平滑,但精度上不去。在实际LSSVM解方程组时,γ还直接出现在对角项I/γ里,γ值越小,矩阵对角占优越强,数值稳定性越好,这又是一个容易被忽略的技术细节。
σ是RBF核的宽度。σ越小,核函数衰减越快,每个样本只影响很小范围内的邻居,模型复杂度升高,容易拟合出剧烈抖动;σ越大,样本影响范围越大,模型趋向平滑,但过大的σ会让所有样本之间的距离差异都趋于零,核矩阵接近常数值,LSSVM退化成接近线性回归,非线性拟合能力基本报废。
所以NGO本质上就是在二维平面上找一个“平衡点”。我常用范围是γ∈[0.01, 100]、σ∈[0.01, 100],实际搜索时一般对两个参数取log10刻度,否则NGO的随机扰动在绝对值尺度下容易被“小参数区域”的边缘效应影响。用log空间搜索,相当于把0.01到100这种跨度非常大的区间压扁成一维均匀分布的搜索带,明显更容易搜到靠中间区域的合理解。
2.4 多输出目标函数的隐藏细节:权重、归一化与核矩阵共享
把NGO和LSSVM接起来,最关键的设计是目标函数。LSSVM本身不是一个原生多输出模型,但它对多个输出维度是友好的:因为核矩阵只跟输入X和核宽σ有关,跟输出Y无关,所以同一个核矩阵可以复用来训练多个输出维度。在NGO的每次适应度评估里,相当于解M个线性方程组,而不用重复计算M次核矩阵,这个加速很重要。
目标函数具体怎么定义,我试过两种。第一种是直接把所有输出维度的均方误差相加,粗糙但简单;第二种是对每个输出先单独归一化到[0,1],再计算归一化后的均方误差平均值。第二种明显更合理。因为现实数据里,输出维度的量纲往往差很多,比如一个输出在0到100之间,另一个输出在0到1之间,如果不归一化,大数值的维度会在总误差里“一票否决”,小数值维度直接被忽略。NGO会疯狂优化大维度,最终小维度预测烂掉。
另外多输出内部的权重也不是必须相等。如果业务上更关心某个关键指标,可以在目标函数里给该维度更高的权重。我在一个软测量项目里就把主产品质量指标的权重设成2,其余维度设为1,NGO的寻优方向立刻偏向关键指标,效果比无权重版本更贴合现场需求。
3. 从零实操:Matlab环境下的完整落地流程
3.1 数据准备、归一化与训练/测试划分
我用Matlab + LSSVMlab工具箱跑通了整个流程。LSSVMlab里的核心函数是trainlssvm和simlssvm,熟悉这两个函数之后,NGO-LSSVM的代码量其实不大。
第一步是数据准备。假设输入特征X是n×p矩阵,输出Y是n×m矩阵,m就是多输出维度。我先用mapminmax做归一化,把所有输入输出统一缩放到[0,1]。这一步对RBF核特别重要,因为核函数里计算的是样本间的欧氏距离,量纲不一致会让某些特征主导核距离,模型解释性变差。输出归一化还能直接解决前面说的量纲不统一问题。
% 数据读取,X为n×p特征矩阵,Y为n×m多输出矩阵 X_raw = xlsread('dataset.xlsx', 1, 'A:H'); % 示例:8个特征 Y_raw = xlsread('dataset.xlsx', 1, 'I:K'); % 示例:3个输出 % 归一化到[0,1] [X_norm, X_ps] = mapminmax(X_raw', 0, 1); [Y_norm, Y_ps] = mapminmax(Y_raw', 0, 1); X_norm = X_norm'; Y_norm = Y_norm'; % 训练集/测试集划分,这里按8:2切分 n = size(X_norm, 1); idx = randperm(n); train_idx = idx(1:round(0.8*n)); test_idx = idx(round(0.8*n)+1:end); X_train = X_norm(train_idx, :); Y_train = Y_norm(train_idx, :); X_test = X_norm(test_idx, :); Y_test = Y_norm(test_idx, :);随机划分会让结果随种子变化,严谨项目建议用分层抽样或者按时间顺序切分,尤其是时序数据场景。按时间切分时必须严格用前面的样本训练、后面的样本测试,否则未来信息泄漏会让结果虚高。
3.2 NGO优化主循环代码与参数设置
NGO的Matlab主循环我写成了函数式结构,二维决策变量对应γ和σ的log10值。设置种群规模N=30,迭代次数T=80,初始种群用均匀随机分布铺满搜索空间。这里把γ和σ统一用log10值表示,搜索下界设置为log10([0.01, 0.01]),上界为log10([100, 100]),这样搜索空间里的每个维度量级一致。
N = 30; % 种群规模 T = 80; % 最大迭代次数 D = 2; % 决策变量维度:γ和σ lb = [log10(0.01), log10(0.01)]; ub = [log10(100), log10(100)]; % 初始化种群 Pos = repmat(lb, N, 1) + rand(N, D) .* repmat(ub - lb, N, 1); Fit = zeros(N, 1); for i = 1:N Fit(i) = lssvmObjFun(10.^Pos(i, :), X_train, Y_train, foldNum); end % 记录初始最优 [bestFit, bestIdx] = min(Fit); bestPos = Pos(bestIdx, :); bestCurve = zeros(T, 1); for t = 1:T for i = 1:N % ---------- 阶段一:全局探索 ---------- k = randi(N); while k == i k = randi(N); end newPos = Pos(i, :) + rand(1, D) .* (Pos(k, :) - randi([1, 2]) .* Pos(i, :)); newPos = max(min(newPos, ub), lb); % 边界处理 newFit = lssvmObjFun(10.^newPos, X_train, Y_train, foldNum); if newFit < Fit(i) Pos(i, :) = newPos; Fit(i) = newFit; end % ---------- 阶段二:局部开发 ---------- R = 0.02 * (1 - t / T); prey = bestPos; newPos = Pos(i, :) + rand(1, D) .* (R * prey - rand(1, D) .* Pos(i, :)); newPos = max(min(newPos, ub), lb); newFit = lssvmObjFun(10.^newPos, X_train, Y_train, foldNum); if newFit < Fit(i) Pos(i, :) = newPos; Fit(i) = newFit; end end % 更新全局最优 [minFit, minIdx] = min(Fit); if minFit < bestFit bestFit = minFit; bestPos = Pos(minIdx, :); end bestCurve(t) = bestFit; fprintf('Iter %d/%d, best CV RMSE = %.6f\n', t, T, bestFit); end bestGamma = 10^bestPos(1); bestSigma = 10^bestPos(2);这个主循环看起来朴素,但足够跑通。要提醒的是,newFit计算时每次都重新训练LSSVM,这块的耗时大头在目标函数里。代码里我对每个个体更新位置后只重算一次值,没有重复缓存,实际工程里如果样本量大,可以把历史个体位置和目标值存在哈希表里,避免重复计算。
3.3 目标函数里怎么训练多输出LSSVM
目标函数设计是整个方案的核心。我采用K折交叉验证,把训练集切成K份,轮流取其中一份做验证,其余K-1份训练LSSVM,K一般取5。对多输出维度,我在目标函数里逐个输出建模,再把所有输出维度的归一化均方误差取平均。
这里有一个加速技巧必须说:在固定γ和σ的情况下,输入样本是同一个训练子集,核矩阵Ω只需要计算一次,M个输出维度共用同一个核矩阵,分别求解各自的线性方程组即可。LSSVMlab原生的trainlssvm接口每次训练都会重新计算核矩阵,如果想极致提速,可以自己写内核计算,把Ω一次性算好,再对每个输出列调用线性方程求解。如果输出维度不大(比如3~5个),用LSSVMlab也能接受。
function cvRMSE = lssvmObjFun(params, X, Y, foldNum) % params = [gamma, sigma] gamma = params(1); sigma = params(2); n = size(X, 1); cv = cvpartition(n, 'KFold', foldNum); errorSum = 0; for k = 1:foldNum trIdx = training(cv, k); teIdx = test(cv, k); Xtr = X(trIdx, :); Ytr = Y(trIdx, :); Xte = X(teIdx, :); Yte = Y(teIdx, :); mseFold = 0; for m = 1:size(Y, 2) % 训练第m个输出维度的LSSVM model = trainlssvm({Xtr, Ytr(:, m), 'function estimation', gamma, ... 'RBF_kernel', sigma}); Ypred = simlssvm(model, Xte); mseFold = mseFold + mean((Ypred - Yte(:, m)).^2); end errorSum = errorSum + mseFold / size(Y, 2); end cvRMSE = sqrt(errorSum / foldNum); end这里用的是“训练集内部再做一次交叉验证”的方式,有效避免NGO钻空子。如果不做交叉验证、直接在整个训练集上算误差,LSSVM很容易在NGO引导下选择过拟合的γ,交叉验证误差看着低,测试集一跑就露馅。交叉验证虽然增加计算量,但对参数选择的可靠度提升非常明显。
3.4 用最优参数回带训练并输出预测结果
NGO寻优结束后,bestGamma和bestSigma就是我们要的参数。回带阶段直接用全部训练集训练LSSVM,然后在测试集上评估。注意:这时不再做交叉验证,而是全量训练,充分利用所有样本信息。
% 用最优参数在全量训练集上训练多输出LSSVM modelAll = cell(size(Y_train, 2), 1); Y_test_pred = zeros(size(Y_test, 1), size(Y_train, 2)); Y_train_pred = zeros(size(Y_train, 1), size(Y_train, 2)); for m = 1:size(Y_train, 2) modelAll{m} = trainlssvm({X_train, Y_train(:, m), 'function estimation', ... bestGamma, 'RBF_kernel', bestSigma}); Y_train_pred(:, m) = simlssvm(modelAll{m}, X_train); Y_test_pred(:, m) = simlssvm(modelAll{m}, X_test); end % 反归一化到原始量纲 Y_train_pred = mapminmax('reverse', Y_train_pred', Y_ps)'; Y_test_pred = mapminmax('reverse', Y_test_pred', Y_ps)'; Y_test_raw = mapminmax('reverse', Y_test', Y_ps)';这段代码跑完之后,把Y_test_pred和Y_test_raw放到一起做误差分析就行。实际项目里我还额外输出了一份Excel结果表,每一列是一个输出维度的预测值和真实值,方便和现场工程师核对趋势。
4. 实验设计与结果分析:怎么证明这套方案有效
4.1 评价指标选择:别只盯一个R²
多输出回归的评价比单输出麻烦,因为维度多了之后单个指标说明不了全部问题。我一般对每个输出维度分别计算决定系数R²、均方根误差RMSE、平均绝对误差MAE,再计算一个加权平均R²。R²看拟合趋势和解释能力,RMSE看误差总体量级,MAE看误差均值水平,MAPE在看百分比误差场景下也会加进去。
还要注意一个常被忽略的问题:多输出场景下,各维度RMSE的单位不一样时不能直接相加比较。比如一个输出是温度单位℃,另一个是浓度单位mg/m³,数值上没法互相比较。所以我在报告里一定先展示各维度误差的原始值,再用归一化后的综合误差做汇总。前面目标函数里做的归一化处理,在这里就发挥作用了。
4.2 对比实验怎么设才公平
只跑一个NGO-LSSVM不能说明问题,对比实验必须安排。我用相同的数据集划分、相同的交叉验证折数,分别跑了PSO-LSSVM、GA-LSSVM、标准LSSVM(手工参数)、BP神经网络,每组方法重复10次取平均,保证随机性不干扰结论。
以下是某次空气污染物浓度多输出预测实验里的结果摘录,输出维度3个,样本量1200,输入特征10个:
| 方法 | RMSE1 | RMSE2 | RMSE3 | R²均值 | 单次训练耗时/s |
|---|---|---|---|---|---|
| 手工LSSVM | 0.824 | 0.932 | 0.835 | 0.873 | 1.2 |
| PSO-LSSVM | 0.615 | 0.721 | 0.692 | 0.912 | 38.6 |
| GA-LSSVM | 0.589 | 0.703 | 0.671 | 0.921 | 45.2 |
| NGO-LSSVM | 0.542 | 0.658 | 0.620 | 0.937 | 34.1 |
| BP神经网络 | 0.731 | 0.855 | 0.798 | 0.884 | 12.8 |
从表里能看出两个结论:一是有参数寻优和没有参数寻优差距非常大,手工参数的LSSVM直接掉一档;二是NGO-LSSVM在RMSE和R²上都优于PSO和GA,训练耗时还略短一点。这是单次实验的中位水平,10次重复实验的标准差NGO也更小,说明NGO在这类低维参数优化问题上稳定性确实不错。
4.3 收敛曲线里能看出哪些门道
NGO运行时我记录了每一代最优适应度,画成收敛曲线。这个曲线有两个观察点:前期下降陡峭程度代表全局搜索效率,后期是否继续下降代表局部开发能力。
我遇到比较多的情况是PSO的曲线前期非常猛,10代以内就冲到很低的值,但后面几乎平了,说明早熟;NGO的曲线前期稍微慢一点点,但20代之后还在缓慢下探,最后的稳定值更低。GA则经常出现阶梯式下降,因为交叉和变异产生的新解质量参差不齐,波动较大。做实验时建议把自己的收敛曲线和对比算法画在同一张图里,参数寻优的效果一眼就能看出差别。
另外,NGO的种群规模设置也会影响收敛形态。N太小容易搜不干净,N太大单次迭代计算量猛增。我在二维搜索问题上试过N=10、20、30、50,N=30是性价比均衡点,N=50精度提升有限但耗时几乎翻倍。
5. 常见问题与避坑指南
5.1 参数范围设不好会怎么翻车
参数边界设不科学,NGO再聪明也白搭。我第一次跑的时候把γ的上界设成了10000,σ上界也设成1000,结果NGO很容易就把γ推到上界,交叉验证误差虽然很低,但测试集效果很差。原因很简单:γ过大时模型疯狂拟合训练集噪声,交叉验证恰好又容易被这种“局部兜底”蒙骗过去。
后来我把γ和σ都限制在[0.01, 100],并且在log10空间搜索,问题明显缓解。还有个更稳的办法:先用手工LSSVM做一次粗跑,看一下不同量级的γ和σ下验证误差的分布,再把NGO的搜索边界收缩到误差较低的区间内。这样既能缩短NGO迭代时间,也避免在明显没希望的区域浪费时间。
5.2 NGO计算量太大怎么办
N=30、T=80、K=5折、样本1200条的场景下,我的Matlab跑一次大概需要35秒左右,可以接受。但样本量到5000条以上时,每次LSSVM训练都要解一个5000×5000的线性方程组,K折再乘上种群和迭代,等待时间就变成十几分钟甚至更久。
三个优化手段我认为最有效。第一是降交叉验证折数,K=3比K=5能省不少时间,精度损失在可接受范围。第二是提前踩刹车:在NGO迭代过程中如果连续20代最优适应度变化小于阈值,直接终止循环。第三是用前面提到的共享核矩阵技巧,手写多输出求解,避免LSSVMlab重复计算核矩阵。如果时间还是不够,可以试试对训练集随机抽样做子集优化,用一万条样本里抽两三千条来选参数,找到的参数在全量数据上通常也不会差太多。
5.3 输出维度差异导致“一个指标被平均到消失”
这是多输出回归最容易踩的坑。三个输出维度里有两个量纲小、误差小,一个量纲大、误差大,目标函数如果把所有维度的RMSE直接平均,大误差维度会支配整个目标,NGO疯狂优化它,另外两个维度被“平均到消失”。
解决方式就是我前面说过的:所有输出先归一化再做误差计算,必要时对业务关键维度加权重。实际项目里我还遇到过更隐蔽的问题:输出归一化后误差虽然均衡了,但反归一化之后,某个维度的预测值在低量程区间的相对误差特别大。这时候单纯看RMSE是不够的,要结合业务需求看哪个区间的误差更敏感,必要时在目标函数里加入分段权重。
5.4 训练测试都挺好,现场数据却翻车
这是模型泛化问题,NGO-LSSVM也逃不掉。最常见原因是训练数据和现场应用数据的分布不一致。我在一个设备监测项目里,训练数据来自夏季工况,模型秋冬季上线之后预测偏差直线上升,后来把季节性特征加入输入、用近3个月滚动数据重新训练,才算稳住。
另一个原因是数据泄漏。切分数据时如果不小心把未来信息卷进训练集,交叉验证误差会虚低,现场预测直接报废。对时间序列多输出回归,切忌随机打乱划分,务必用时间点前的数据训练、时间点后的数据测试。还要多关注输入特征本身是否包含输出变量的滞后项,这些滞后项如果只在训练集里有、现场采集不到,模型必然翻车。
5.5 随机性相关的稳定性问题
NGO本身带随机性,每次运行得到的bestGamma和bestSigma虽然接近,但不会完全相同。如果项目需要可复现结果,最好固定随机种子。Matlab里在运行前加一句rng(42),并且把每次运行的最优参数、适应度曲线都记录到文件中,方便事后追溯。
还建议做5次以上重复运行,取收敛误差最低的那组参数作为最终交付参数,而不是第一次跑完就收工。我在一次实验里连续跑5次,最优参数落在log10(γ)≈1.2、log10(σ)≈-0.5附近,第4次和第5次结果几乎重合,说明NGO在这个区域搜索得比较稳定,而PSO的5次结果分散得多。
5.6 除了超参数,这套思路还能往哪里扩展
NGO优化LSSVM这套框架不只是能调两个参数。稍微改一下,决策变量就可以扩展到输入特征权重:让NGO同时优化哪些特征应该被加强、哪些应该被压低,相当于把特征选择和参数寻优合二为一。也可以把核函数从RBF换成多项式核或者混合核,让NGO去搜索核函数的组合系数。多输出场景下还可以把LSSVM换成KLSSVM(核极限学习机),训练速度更快,配NGO之后在较大样本集上的优势更明显。
我的后续计划是尝试把多输出回归的评价从单一加权MSE升级成多个指标的综合排序,比如用NSGA-II这类多目标优化算法同时优化各个输出维度的误差。这类方案在业务上更清晰,因为可以给决策者提供一组帕累托前沿解,而不是单个“均衡解”。不过现阶段NGO-LSSVM已经够我应付大部分项目了,尤其是样本量不大、多维输出相关性明显的场景,这套组合在准确度和训练速度之间找到了一个很舒服的平衡点。