多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

PSO-SVR回归拟合实战:粒子群优化SVR参数与Python实现

PSO-SVR回归拟合实战:粒子群优化SVR参数与Python实现 简介面向机器学习初学者与研究人员的PSO-SVR回归拟合资源将粒子群优化算法与支持向量机结合用于自动搜索SVR的惩罚因子C与核参数γ解决传统网格搜索效率低、易陷入局部最优的问题。压缩包共64个文件含MATLAB、Python、Java、C等多语言源码以及libsvm-3.31工具链、测试数据集heart_scale和说明文档整体仅941KB便于快速下载部署。目前已有218人学习适合在实验或课程设计中用作参照。资源不仅提供PSO-SVR主程序与对比SVR的代码还包含SVM的编译配置、可执行程序及跨平台支持文件读者可基于自带数据直接运行观察参数优化过程并理解回归拟合差异。1. PSO-SVR回归拟合为什么比普通SVR值得做先搞懂参数寻优的黑匣子同样的数据、同样的核函数SVR的回归拟合效果可以差出一个量级。我见过不少刚接触支持向量回归的人把训练集R²跑到0.95以上就以为完事了换到测试集上直接掉到0.7以下。问题的根源不在SVR算法本身而在C、epsilon、gamma这三个参数怎么选。手动调参本质上是在连续参数空间里靠经验和运气去试网格搜索虽然暴力但维度一高就爆炸而且C、epsilon、gamma各自的数量级差别很大用固定步长很容易跳过最优区域。PSO-SVR就是把粒子群算法和SVR捏在一起做的事用粒子群算法PSO在参数空间里自动搜索SVR的最优参数组合再做回归拟合最后和默认参数的SVR做对比。粒子群算法原理并不复杂核心就是让一群粒子在参数空间里飞行每个粒子记住自己找到过的最好位置同时参考群体目前发现的最好位置不断往更有希望的区域靠拢。相比网格搜索它在连续参数空间里收敛更快相比贝叶斯优化实现思路更直白没有那么多概率模型的数学包袱。这套方案特别适合已经有回归预测任务、手头有训练数据、但不满足于SVR默认参数效果的从业者——比如做电力负荷预测、气象数据拟合、工业过程软测量这类工作的人。你不需要懂太深的优化理论把粒子群算法原理弄通再把SVR的参数边界设对就能得到一个精度明显提升的回归模型。文章后面会给出完整的Python实现每一步都能直接抄。2. 粒子群算法原理与SVR参数空间的匹配PSO凭什么能在C、epsilon、gamma里找到更好的组合2.1 PSO-SVR的核心逻辑粒子、速度与gbest怎么在SVR参数空间中运动粒子群算法原理可以拆成三个关键概念粒子位置、粒子速度、群体最优解。放到PSO-SVR这个具体场景里一粒粒子就是一个候选的SVR参数组合。比如某个粒子的位置向量是[C8.5, epsilon0.02, gamma0.35]这就代表当前这一代里有一组待评估的参数配置。粒子在参数空间里飞行每到一个新位置就用这组参数训练一个SVR并计算预测误差这个误差值就是适应度。速度更新是粒子群优化算法的心脏。每轮迭代每个粒子按下面这个公式更新自己的速度[ v_{i1} w \cdot v_i c_1 \cdot r_1 \cdot (pbest_i - x_i) c_2 \cdot r_2 \cdot (gbest_i - x_i) ]通俗解释w是惯性权重控制粒子沿原方向继续飞的倾向c1是认知系数让粒子往回飞向自己历史上表现最好的位置pbestc2是社会系数把粒子拉向整个群体目前发现的最优位置gbest。r1和r2是0到1之间的随机数用来增加探索的随机性。位置更新就简单了[ x_{i1} x_i v_{i1} ]在PSO-SVR里每一轮迭代都要做“用当前位置的参数组合训练SVR并算适应度”这个步骤所以总训练时长大概是“迭代次数 × 粒子数量 × 单次SVR训练耗时”。这也是为什么后面要控制种群规模和迭代次数不然跑起来会非常久。2.2 SVR三个参数C、epsilon、gamma对回归拟合的影响为什么手动调参容易翻车在讲PSO怎么搜索之前得先把SVR的三个关键参数说透因为参数边界设不对粒子群算法原理再正确也白搭。C是惩罚系数控制模型对训练误差的容忍度。C越大模型越倾向于把每个训练点都拟合到位容易过拟合测试集上的回归拟合误差反而变大C越小模型越平滑但可能欠拟合训练集和测试集都表现平庸。epsilon是不敏感带宽度可以理解为允许预测值和真实值之间存在多大的误差而不受惩罚。epsilon越小拟合精度要求越高支持向量越多模型越复杂epsilon越大拟合越粗糙模型越简单。gamma是RBF核函数的参数控制单个训练样本的影响半径。gamma越大影响半径越小模型越容易震荡gamma越小影响半径越大决策边界越平滑。三个参数的量级完全不一样C通常从0.1到几百都有意义epsilon一般在0.001到1之间gamma在0.001到10之间都值得试。网格搜索如果想在这个三维空间里每个维度取20个点那就是8000次SVR训练数据量稍大就吃不消。而手动调参更玄学——你先试C1、gamma0.1看效果不好再改C10这本质上是在三维空间里瞎逛大概率落在局部最优附近。PSO-SVR就是把这个“瞎逛”变成有方向性的搜索每个粒子根据pbest和gbest修正自己的飞行方向相当于一群人在山地里找最低点互相喊话哪里有更低的地方比一个人闭着眼乱走高效得多。2.3 PSO的适应度函数设计用交叉验证误差还是RMSE适应度函数决定了粒子群算法在朝什么方向搜索。最朴素的想法是用训练集训练SVR然后在训练集上算一遍RMSE作为适应度。这样做出来的参数一定会让训练误差很小但泛化能力可能很差。正确做法是给每个粒子的参数组合做K折交叉验证把每一折的预测误差加起来取平均作为最终适应度。以5折交叉验证为例流程是把这组参数对应的SVR在折1到折4上训练在折5上预测算误差再换到另一组四折训练、一折预测重复5次把5次误差求和或取平均。这个平均值就是该粒子当前位置的适应度。粒子群优化算法本质上是在“最小化这个交叉验证误差”的目标下搜索参数空间。还有个常见问题适应度函数用MAE还是RMSE我一般用RMSE因为RMSE对大误差更敏感能逼着粒子群避开那些在某些样本上严重翻车的参数。如果你的数据里有明显的离群点而且你希望模型不要被离群点带偏那用MAE做适应度更稳。这点在后面的代码里会留一个开关。3. 用Python实现PSO-SVR从粒子初始化到回归拟合的完整代码与参数说明3.1 PSO类设计与关键参数种群规模、惯性权重、学习因子怎么设下面这套代码是我常用的PSO-SVR落地模板。先写一个通用的PSO类把粒子群算法原理直接代码化然后再接SVR。import numpy as np from sklearn.svm import SVR from sklearn.model_selection import cross_val_score from sklearn.preprocessing import StandardScaler from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score class PSO: def __init__(self, objective_func, dim, lb, ub, n_particles20, max_iter50, w0.8, c12.0, c22.0): self.objective_func objective_func # 适应度函数输入参数向量返回误差值 self.dim dim # 待优化参数个数SVR这里就是3 self.lb np.array(lb) # 参数下界 self.ub np.array(ub) # 参数上界 self.n_particles n_particles # 粒子数量 self.max_iter max_iter # 最大迭代代数 self.w w # 惯性权重 self.c1 c1 # 认知系数 self.c2 c2 # 社会系数 # 初始化粒子位置和速度 self.X np.random.uniform(lb, ub, (n_particles, dim)) self.V np.random.uniform(-(ub - lb) * 0.1, (ub - lb) * 0.1, (n_particles, dim)) self.pbest self.X.copy() self.pbest_score np.full(n_particles, np.inf) self.gbest self.X[0].copy() self.gbest_score np.inf self.convergence_curve [] # 记录每轮最优适应度用来画收敛曲线 def update(self): for i in range(self.n_particles): # 计算当前粒子位置的适应度 score self.objective_func(self.X[i]) # 更新个体最优 if score self.pbest_score[i]: self.pbest_score[i] score self.pbest[i] self.X[i].copy() # 更新全局最优 if score self.gbest_score: self.gbest_score score self.gbest self.X[i].copy() # 更新速度和位置 r1 np.random.rand(self.n_particles, self.dim) r2 np.random.rand(self.n_particles, self.dim) cognitive self.c1 * r1 * (self.pbest - self.X) social self.c2 * r2 * (self.gbest - self.X) self.V self.w * self.V cognitive social self.X self.X self.V # 边界处理粒子飞出边界时拉回来同时把速度置小避免反复震荡 self.X np.clip(self.X, self.lb, self.ub) self.V np.clip(self.V, -(self.ub - self.lb) * 0.2, (self.ub - self.lb) * 0.2) self.convergence_curve.append(self.gbest_score) def optimize(self): for _ in range(self.max_iter): self.update() return self.gbest, self.gbest_score逻辑说明这里把PSO写成独立类objective_func是外部传入的“用参数组合训练SVR并返回误差”的函数。这样PSO部分不依赖具体模型以后想换成PSO优化随机森林或者XGBoost的超参数直接换objective_func就行。速度更新那一行把认知和社会两个方向分开写比起公式连成一坨更容易看出每个系数控制的是什么。参数说明粒子数量n_particles一般取10到30。数据量不大、SVR训练快的场景取20比较合适数据量大就降到10否则每轮迭代的SVR训练次数太多。max_iter取30到80迭代太多收益很小因为粒子群通常在20代内就已经收敛得差不多了。w惯性权重取0.8是常见起步值也可以在迭代过程中从0.9线性衰减到0.4让前期多探索、后期多收敛。c1和c2取2.0是粒子群算法原理里最经典的配置意思是粒子往个体最优和全局最优方向飞行的加速度相当如果你想更偏向全局搜索把c2微微调大到2.2。3.2 SVR训练与五折交叉验证的接入方式避免过拟合的细节接下来写objective_func。这里有两个容易翻车的细节第一不能直接用原始数据训练必须先归一化第二必须用交叉验证误差而不是训练集误差做适应度。def make_objective(X_train, y_train, X_test, y_test, cv_folds5): def objective(params): C, epsilon, gamma params model SVR(CC, epsilonepsilon, gammagamma, kernelrbf) # 负号是因为cross_val_score返回的是得分得分越高越好这里取负转成误差 scores cross_val_score(model, X_train, y_train, cvcv_folds, scoringneg_mean_squared_error) rmse np.sqrt(-scores.mean()) return rmse return objective逻辑说明闭包函数objective接收一个参数向量拆成C、epsilon、gamma三个值构造SVR模型然后做5折交叉验证。scoringneg_mean_squared_error会让sklearn返回负数MSE所以先取负再开方变成RMSE。这个RMSE就是粒子群算法要最小化的目标。参数说明cv_folds取5是默认值数据量在几百到几千条时5折的方差和耗时比较均衡。如果你的数据只有几十条建议改成3折否则每折训练数据太少交叉验证误差的抖动会让粒子群算法误判方向。如果你更关心测试集上的MAE而不是RMSE把scoring改成neg_mean_absolute_error这样粒子群会专门去降低平均绝对误差。还有一个经常被忽略的点交叉验证内部不会替你归一化。如果先在外面做了StandardScaler再进交叉验证那每一折训练集都“看到了”全量数据的均值和方差会造成轻微的数据泄漏。严格做法是在每一折内部单独做归一化但sklearn的cross_val_score不支持这种写法。我一般折中如果训练集样本量足够且分布稳定先做归一化再交叉验证问题不大如果数据分布有明显漂移就用Pipeline包一层。from sklearn.pipeline import Pipeline def make_objective_pipeline(X_train, y_train, cv_folds5): def objective(params): C, epsilon, gamma params pipeline Pipeline([ (scaler, StandardScaler()), (svr, SVR(CC, epsilonepsilon, gammagamma, kernelrbf)) ]) scores cross_val_score(pipeline, X_train, y_train, cvcv_folds, scoringneg_mean_squared_error) return np.sqrt(-scores.mean()) return objective这个版本把归一化放进Pipeline里每一折交叉验证都会在训练折上拟合并转换规避了数据泄漏问题。代价是交叉验证的耗时比先归一化再验证多一点点但对于回归拟合这个场景完全可以接受。3.3 数据归一化与划分训练集、验证集、预测集怎么切PSO-SVR落地时的数据划分和普通模型训练不太一样需要同时兼顾三块数据粒子群寻优用的数据、最终重训模型时验证效果的数据、以及用来做最终对比测试的数据。from sklearn.model_selection import train_test_split # 假设你已经有了X和yX是特征矩阵y是目标值 X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.2, random_state42) # 再从中切出10%做粒子群内部的验证参考可选 X_train_fit, X_val, y_train_fit, y_val train_test_split( X_train, y_train, test_size0.1, random_state42 )逻辑说明先把原始数据按8:2切成训练集和测试集。测试集在整个PSO寻优过程中绝对不能碰否则选出的参数会对测试集过拟合后面做的PSO-SVR vs SVR对比就不公平了。然后再从训练集里切出一小块做验证参考这块数据可以用来观察粒子群在寻优结束后的泛化表现。参数说明random_state固定是为了让对比实验可复现。如果你想把实验做得更严谨可以换成KFold多次重复取平均但代码会复杂不少。做回归拟合这个场景一般一次固定划分就够了重点是测试集和寻优过程隔离干净。3.4 完整对比脚本一行命令输出PSO-SVR和SVR回归拟合的指标表把上面几段拼起来就是完整的对比脚本。这里我结合sin函数加噪声生成一份示例数据方便直接跑通。实际使用时把数据加载部分换成你自己的即可。import matplotlib.pyplot as plt # 生成示例数据带噪声的sin曲线 rng np.random.RandomState(42) X np.linspace(0, 10, 300).reshape(-1, 1) y np.sin(X).ravel() rng.normal(0, 0.1, X.shape[0]) # 数据划分 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42 ) # 定义PSO搜索空间C、epsilon、gamma lb [0.1, 0.001, 0.001] ub [100, 1.0, 10.0] # 构建适应度函数 objective_func make_objective_pipeline(X_train, y_train, cv_folds5) # 运行粒子群优化 pso PSO(objective_func, dim3, lblb, ubub, n_particles20, max_iter50, w0.8, c12.0, c22.0) best_params, best_score pso.optimize() best_C, best_epsilon, best_gamma best_params print(fPSO找到的最优参数: C{best_C:.4f}, epsilon{best_epsilon:.4f}, gamma{best_gamma:.4f}) print(f交叉验证RMSE{best_score:.4f}) # 用默认参数训练SVR作为对比 svr_default SVR(kernelrbf) svr_default.fit(X_train, y_train) y_pred_default svr_default.predict(X_test) # 用粒子群寻优后的参数重新训练SVR svr_optimized SVR(Cbest_C, epsilonbest_epsilon, gammabest_gamma, kernelrbf) svr_optimized.fit(X_train, y_train) y_pred_optimized svr_optimized.predict(X_test) # 对比指标 metrics { SVR默认参数: { RMSE: np.sqrt(mean_squared_error(y_test, y_pred_default)), MAE: mean_absolute_error(y_test, y_pred_default), R2: r2_score(y_test, y_pred_default) }, PSO-SVR: { RMSE: np.sqrt(mean_squared_error(y_test, y_pred_optimized)), MAE: mean_absolute_error(y_test, y_pred_optimized), R2: r2_score(y_test, y_pred_optimized) } } for name, m in metrics.items(): print(f{name}: RMSE{m[RMSE]:.4f}, MAE{m[MAE]:.4f}, R2{m[R2]:.4f}) # 画拟合效果对比图 plt.figure(figsize(12, 5)) plt.subplot(1, 2, 1) plt.scatter(X_test, y_test, colorgray, alpha0.6, label真实值) plt.scatter(X_test, y_pred_default, colorblue, s30, labelSVR默认参数, alpha0.7) plt.legend() plt.title(SVR默认参数回归拟合) plt.subplot(1, 2, 2) plt.scatter(X_test, y_test, colorgray, alpha0.6, label真实值) plt.scatter(X_test, y_pred_optimized, colorred, s30, labelPSO-SVR, alpha0.7) plt.legend() plt.title(PSO-SVR回归拟合) plt.tight_layout() plt.show()逻辑说明这段脚本按“先生成数据 → 划分 → 粒子群寻优 → 重训SVR → 对比测试集指标”的顺序跑。findbest_params之后把寻优得到的参数传给SVR重新训练。注意重训的时候用的是全量训练集不是交叉验证集合因为交叉验证只是用来评估参数的最终模型要在更多数据上训练。参数说明lb和ub这个搜索边界直接影响粒子群算法能不能找到好参数。C的下界至少0.1上界100够绝大多数场景用如果数据量很大可以提到1000。epsilon下界0.001已经够了再小会让SVR逼近到噪声层面支持向量数量爆炸。gamma下界0.001、上界10.0如果特征维度特别高比如超过50维上界可能要降到1.0否则模型太震荡。4. PSO-SVR vs SVR结果对比与避坑指标怎么读、哪里容易翻车4.1 用MAE、RMSE和R²对比回归拟合效果结果表的正确打开方式寻优完成后你会拿到一行类似这样的输出模型RMSEMAER²SVR默认参数0.15320.11840.9201PSO-SVR0.08740.06520.9653在这个示例数据上粒子群优化的参数让RMSE下降了40%以上。但指标不是越小越好要结合数据本身看。RMSE对离群点敏感如果测试集里恰好有几个样本噪声很大RMSE会被拉高这时MAE更能反映模型的总体水平。R²则直观表示模型解释了目标值多少方差0.92到0.96的提升看起来不大但在真实业务里可能意味着预测误差缩小了三分之一。我先说一个经验如果PSO-SVR跑出来的RMSE只比默认SVR低3%到5%先别急着怀疑粒子群算法原理大概率是搜索边界设置得太保守。默认SVR的C1.0、gammascale在你的数据上已经处于一个不错的局部区域而你的lb和ub把这个区域附近的大部分空间都划掉了粒子根本没机会飞到更远的好位置。把C的上限拉高到500gamma上限拉到5重新跑一遍通常会有惊喜。另一个判断技巧是看默认SVR和PSO-SVR的模型复杂度差异。如果寻优后的C比默认大了一个数量级说明你的数据本身需要更高复杂度的拟合如果epsilon变得很小说明数据里的噪声比想象中低模型可以做到更高的精度。这些信息比单纯的指标数字更有业务价值。4.2 画趋势图与残差图肉眼判断比数字更直观的验证手段指标表只能告诉你“谁更好”不能告诉你“好在哪里、哪里还有问题”。我每次跑完都要画两张图预测趋势图和残差分布图。# 残差图 residual_default y_test - y_pred_default residual_optimized y_test - y_pred_optimized plt.figure(figsize(12, 4)) plt.subplot(1, 2, 1) plt.scatter(y_test, residual_default, alpha0.6, labelSVR默认) plt.axhline(y0, colorblack, linestyle--) plt.xlabel(真实值) plt.ylabel(残差) plt.legend() plt.subplot(1, 2, 2) plt.scatter(y_test, residual_optimized, alpha0.6, labelPSO-SVR) plt.axhline(y0, colorblack, linestyle--) plt.xlabel(真实值) plt.ylabel(残差) plt.legend() plt.tight_layout() plt.show()逻辑说明残差图把每个测试样本的预测误差画在纵轴上。理想情况下残差应该围绕0均匀分布不呈现任何喇叭口形状或弯曲趋势。如果PSO-SVR的残差图比默认SVR更紧密地贴在0附近说明优化确实起作用了。如果残差分布出现明显的“V形”或者“S形”说明模型在某个区间系统性偏低估或偏高估可能是特征和目标的非线性关系没被SVR完全捕捉到这时候单纯调参已经到极限了应该考虑加特征或者换核函数。参数说明如果残差图中PSO-SVR在真实值偏大的区域仍然有明显偏移可以把epsilon下界再调小一点让模型对这部分样本更敏感。但要注意epsilon过小会让支持向量数量剧增训练和预测时间上涨。4.3 避坑/常见问题粒子群算法原理理解错了跑出来的结果比SVR还差现象PSO寻优完成后测试集RMSE比默认SVR还高训练集RMSE却很低。原因适应度函数只用了训练集误差没有做交叉验证。粒子群找到一个在训练集上几乎完全拟合的参数组合通常是C巨大、gamma巨大但这个参数在测试集上严重过拟合。解决把所有粒子群评估都换成交叉验证误差代码里用make_objective_pipeline而不是直接fit之后算训练误差。现象粒子群在第2代就停住了适应度曲线几乎是一条水平线最后找到的参数和初始粒子位置差不多。原因惯性权重w设置太大或速度边界太紧。w过大会让粒子在既有方向上冲得太远跨过好区域然后又弹回来速度边界太紧则限制了粒子在单步内的探索范围导致粒子群在小范围内打转。解决把w从0.8改到0.6试试同时把速度边界的钳制范围从0.2放宽到0.5。粒子群优化算法本质上要平衡探索和收敛前期允许大步探索后期逐步收窄。现象适应度值出现inf程序直接崩了。原因粒子飞出了参数空间导致C或gamma变成NaNSVR训练报错。解决在PSO的位置更新后强制clip而且更重要的是检查lb和ub里有没有0值比如epsilon的lb如果是0粒子更新时可能取到0SVR会直接报错。经验是epsilon的lb至少要设成0.001。4.4 避坑/常见问题适应度函数选错、粒子乱飞、SVR训练过慢的排查现象粒子群跑得非常慢20个粒子50代迭代跑了半小时还没结束。原因SVR本身训练复杂度高如果训练样本超过1万条单次SVR训练就要几秒甚至十几秒乘以20×50就是几千次训练。解决先降采样到2000到3000条做粒子群寻优找到参数后再用全量数据重训SVR。另一个办法是减少粒子数量和迭代代数比如n_particles10、max_iter30虽然搜索空间覆盖差一些但胜在快速迭代试错。现象每次跑PSO-SVR结果都不一样有时候好有时候差。原因粒子群算法原理里有随机数初始化粒子位置和速度都不一样。解决固定np.random.seed()即可复现但更重要的是多跑几次看稳定性。我一般都会让脚本循环跑5次每次记录最优参数和RMSE如果5次结果的RMSE标准差超过0.01说明搜索不稳定应该增大粒子数量或者迭代代数。现象寻优后的参数总是贴着搜索边界比如gamma正好等于ub10.0。原因边界设置不合理真实最优参数可能更靠外。解决不要把边界当成“参数应该在这中间”而是“参数可能存在的区域”。出现贴边情况就把对应参数的边界向外扩一个数量级重新跑。5. 把PSO寻优过程画出来一条适应度曲线看懂收敛与早熟最后聊一个我在实际项目里非常依赖的验证技巧把粒子群的收敛曲线打出来。前面PSO类里已经有一行convergence_curve记录了每轮迭代后的全局最优适应度画出来就能看到寻优过程到底发生了什么。plt.figure(figsize(8, 4)) plt.plot(range(len(pso.convergence_curve)), pso.convergence_curve, markero) plt.xlabel(迭代代数) plt.ylabel(全局最优交叉验证RMSE) plt.title(PSO收敛曲线) plt.grid(True) plt.show()逻辑说明一条健康的收敛曲线应该是前期快速下降、后期缓慢趋于平稳。如果你看到曲线在20代以后还一直缓慢下降说明可以加大迭代次数继续挖如果曲线在2到3代就完全不动了有两种可能要么初始粒子恰好落在最优区附近要么粒子群提前收敛了。怎么区分把粒子数量增加一倍重新跑如果曲线在前期下降得更深说明之前是探索能力不足如果曲线还是原来的水平说明那个平台值就是当前参数空间里能做到的极限。看这条曲线还有一层价值它能帮你判断SVR本身的拟合能力上限在哪里。假如PSO-SVR寻优后的交叉验证RMSE依然比业务要求的误差大很多那不是参数没调好而是SVR在这个特征空间里的表达力本来就不够。这时候应该去优化训练数据、构造新特征或者考虑梯度提升树类模型而不是继续在PSO的迭代次数上较劲。说到职业习惯我现在每次跑PSO-SVR都会固定输出三样东西最优参数本身、收敛曲线图、参数在边界上的分布情况。最优参数会告诉你模型往哪个方向走收敛曲线能验证搜索过程健康参数贴边则提醒我边界没设对。这套验证逻辑帮我排查过不少翻车现场最典型的一次是某组数据噪声极大PSO把epsilon压到了0.001以下逼近噪声交叉验证RMSE看着很漂亮测试集上一塌糊涂正是靠收敛曲线和参数值才意识到该换适应度函数用MAE而不是RMSE。希望帮到你。做PSO-SVR最怕的不是粒子群算法原理理解不透而是把搜索框得太死又不看过程希望你跑通后能体会到这套组合的实用之处。本文还有配套的精品资源点击获取
返回列表