ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

RVM多输入多输出回归:稀疏贝叶斯原理与MATLAB实战

RVM多输入多输出回归:稀疏贝叶斯原理与MATLAB实战 简介基于相关向量机RVM的多输入多输出回归分析MATLAB实现面向本科及以上需要处理小样本、非线性多目标回归问题的学生、研究者和工程师。相关向量机具备稀疏性好、泛化能力强且可输出概率预测的特点适用于能源、环境、经济等领域的多变量预测。资源内含完整模型代码、配套数据与注释主程序与RBF核函数模块分离便于理解RVM回归建模、多输出结果组织与数据预处理完整流程也能方便地迁移到其他数据集。压缩包共4个文件以m源码为主另有xlsx数据表和asv自动备份整体仅153KB轻量易用可直接在MATLAB中运行。目前已有88人学习下载。作者提供了运行答疑与定制化修改支持遇到问题可快速获得帮助整体适合直接复用或作为课程设计、毕业设计、项目预研的参考实现。1. RVM多输入多输出回归稀疏贝叶斯模型凭什么一次预测多个目标拿到一批样本每个样本带着十几个输入变量却要同时预测三四个输出指标这是多输入多输出回归分析最常见的场景。多数人的第一反应是拆成几个独立的单输出回归但输出之间的相关性、偏小的样本量往往让结果很不稳定。基于相关向量机RVM的多输入多输出回归用一套稀疏贝叶斯框架把多个输出放进同一个模型训练预测自带概率区间训练后只留少数相关向量。这里就说清楚RVM和SVM差在哪、多输出扩展有哪几条路、MATLAB代码怎么组织、核宽度和收敛阈值怎么设以及几个高频翻车点。适合谁看手头有多输入多输出回归任务、想做稀疏贝叶斯模型的工程师和研究生已经在跑RVM但效果不稳定、怀疑参数没设对的人。2. 从单输出到多输出RVM的稀疏贝叶斯原理与三条建模路线2.1 RVM和SVM的本质区别稀疏性是先验逼出来的不是约束求出来的在讲多输出之前先把单输出的底子说清楚。相关向量机Relevance Vector Machine, RVM是 Tipping 在 2001 年提出的稀疏贝叶斯模型和 SVM 在形式上都像对训练样本加权求和但两者的稀疏性来源完全不同。SVM 靠凸优化里的约束把大部分样本权重压成零剩下的支持向量待在边界上RVM 则是给每个权重 w_i 指定一个独立的先验精度 α_i通过最大化边际似然证据把绝大多数 α_i 推向无穷大对应权重趋近于零只有少数 α_i 保持有限值的样本被保留下来这些样本叫相关向量。这个区别带来三个实际好处。第一RVM 的稀疏率通常比 SVM 高一个量级几千个训练样本最后可能只留下几十个相关向量预测阶段的计算量小很多。第二RVM 输出后验分布的均值同时能给出预测方差回归分析里要置信区间时这是原生能力SVM 回归还得套 bootstrap 才能得到区间。第三RVM 没有 SVM 那套惩罚系数 C 和损失函数里的 epsilon需要调的连续参数基本只有核宽度一个代价是训练变成迭代重估过程type-II 最大似然没有 SVM 那种一次性求解的确定性。提示RVM 的稀疏性在数值上表现为 α_i 增大到某个阈值以上工程实现普遍用α_i 超过 1e3 或 1e8 就剪枝的方式处理不要等它真正变成 inf否则矩阵求逆迟早出问题。2.2 多输入多输出回归的三条建模路线独立、联合与输出核融合多输入多输出回归分析的数据形态是 X(N×D) 和 Y(N×M)N 是样本数D 是输入维度M 是输出维度。常见做法有三条路线。路线 A逐输出独立训练。每个输出列 Y(:,m) 单独跑一个 RVM得到 M 个模型。优点是实现最简单、输出之间互不干扰任何单输出 RVM 代码都能直接用缺点是没利用输出之间的相关性样本量小的时候每个模型都在重复估计同一套核矩阵浪费信息。路线 B联合多输出 RVM。所有输出共享同一组权重先验精度 α也就是共享同一组相关向量和核基函数但每个输出保留自己的权重向量。训练时把 M 个输出的似然乘在一起证据最大化里 γ 项对所有输出是同一个值α 的更新变成分子分母各自对输出求和。这是标题里基于 RVM 的多输入多输出回归分析最常见、也最值得复现的实现代码复杂度只比单输出高一点却能换来更稳的稀疏结构。路线 C多输出核扩展。用矩阵值核函数把输出空间的协方差也建模进去常见于多输出高斯过程。理论上最强但实现复杂、参数成倍增加工程上除非输出相关性非常强否则性价比不如路线 B。路线相关向量是否共享实现复杂度适合场景逐输出独立 RVM不共享最低输出相关性弱、输出个数少联合多输出 RVM共享同一组中输出相关、样本量有限多输出核 / 多任务 GP建模输出协方差高输出维度低且强相关怎么选我一般先做一件事算一下 Y 的相关系数矩阵 corrcoef(Y)。如果大部分输出对的相关系数绝对值超过 0.3优先试路线 B如果输出之间几乎独立路线 A 反而更好。2.3 证据最大化在做什么RVM训练的每一轮迭代逻辑RVM 的模型写成 t Φw εΦ 是核矩阵w 是权重ε 是高斯噪声。每个权重 w_i 配一个先验 N(0, α_i^{-1})噪声精度记为 β。给定了超参数权重的后验分布是解析的高斯分布均值和协方差分别是mu beta * Sigma * Phi * tSigma inv(A beta * Phi * Phi)A diag(alpha)式子摆出来不是为了推导而是为了说明训练在做什么每一步迭代都是一场拔河——α_i 想把权重拉向零数据似然想把权重拉向拟合值。γ_i 1 - α_i * Sigma_ii 表示第 i 个权重里被数据有效确定的程度所以 α_i 的更新公式是alpha_i_new γ_i / mu_i²当 mu_i 很小权重趋近零时 α_i 变大下一轮这个基函数的作用被削弱直到被剪掉当 mu_i 有真实信号时 α_i 保持有限。多输出联合训练时同样的公式对所有输出求和分子是 M 个输出的 γ 之和分母是 M 个输出权重平方之和。某个输出单独看像是噪声的基函数只要其他输出一致认为它有用就会被保留。这段内容决定了后面调参的方向所有参数调整本质上都在影响这场拔河的速度和终点——核宽度决定基函数之间的重叠程度β 的初始值决定噪声这把秤的刻度收敛阈值决定什么时候算拔完。3. 用MATLAB跑通RVM多输入多输出回归最小示例代码与数据组织3.1 数据集组织X(N×D) 与 Y(N×M) 的约定、随机划分与归一化现在搜 RVM 多输出回归最常见的交付形态就是 MATLAB 实现的 rvm 多输出回归模型配完整代码和实测数据数据文件通常是一个 .mat里面直接放 X 和 Y 两个变量。先确认变量尺寸再动手load(mimo_data.mat); % 约定X 是 N×D 输入Y 是 N×M 输出 whos X Y % 看尺寸确认行列方向拿到数据后的第一件事不是建模而是划分和归一化。划分用随机索引归一化用 z-score关键坑是训练集和测试集必须共用同一组统计量用训练集算 muX、sx测试集直接用同一组减均值除标准差绝不能用全体数据的统计量——那叫数据泄漏会把测试误差虚报得很低。输出归一化同样重要原因在下一章讲RVM 的噪声精度 β 是全局标量输出量纲差一个数量级小量纲输出在证据里基本被忽略。rng(2024); % 固定随机种子保证结果可复现 idx randperm(N); nTrain round(0.7 * N); trIdx idx(1:nTrain); teIdx idx(nTrain1:end); Xtr0 X(trIdx, :); Ytr0 Y(trIdx, :); % 原始量纲的训练/测试副本 Xte0 X(teIdx, :); Yte0 Y(teIdx, :); [Xtr, muX, sx] zscore(Xtr0); % 训练集统计量 Xte (Xte0 - muX) ./ sx; % 测试集用同一组统计量 [Ytr, muY, sy] zscore(Ytr0);zscore 默认按列标准化正好逐特征、逐输出处理。muX、sx、muY、sy 四个统计量必须留着最后预测结果要用 sy 和 muY 乘加回原始量纲。如果数据是 CSV 而不是 mat读法也一样只是开头换成 readmatrix(X.csv)。3.2 单输出RVM训练函数逐行讲清迭代代码和参数含义先写单输出版本多输出联合版本是它的直接推广把单输出每行看懂后面改动只有三处。function model rvm_train_gauss(X, t, width, maxIter, tol) % RVM单输出回归训练高斯核 % 输入X 归一化后的训练输入 N×Dt 归一化后的训练输出 N×1 % width 高斯核宽度maxIter 最大迭代次数tol 收敛阈值 [N, D] size(X); % 向量化计算两两欧氏距离不依赖 pdist2 工具箱 sq sum(X.^2, 2); DD sqrt(max(sq sq - 2 * (X * X), 0)); Phi exp(-DD.^2 / (2 * width^2)); Phi [Phi, ones(N, 1)]; % 最后一列为偏置基函数恒为1 alpha 1e-3 * ones(N 1, 1); % 权重先验精度初始取小值弱先验 beta 1 / var(t); % 噪声精度用输出方差取倒数 for iter 1:maxIter A diag(alpha); Sigma (A beta * (Phi * Phi)) \ eye(N 1); % 后验协方差 mu beta * Sigma * Phi * t; % 后验均值 gamma 1 - alpha .* diag(Sigma); % 每个权重的有效自由度 alphaNew gamma ./ (mu.^2 eps); % 证据最大化的alpha更新 betaNew (N - sum(gamma)) / (sum((t - Phi * mu).^2) eps); if max(abs(alphaNew - alpha)) tol abs(betaNew - beta) tol alpha alphaNew; beta betaNew; break; end alpha alphaNew; beta betaNew; end % 用最终超参数再解一次后验保证权重对应最新的alpha Sigma (diag(alpha) beta * (Phi * Phi)) \ eye(N 1); mu beta * Sigma * Phi * t; rvIdx find(alpha 1e3); % 精度小于阈值权重方差有限相关向量 dataIdx rvIdx(rvIdx N); % 拆出数据样本索引偏置索引是 N1 model.w mu(rvIdx); % 权重顺序与rvIdx严格一致 model.dataIdx dataIdx; model.biasKeep any(rvIdx N 1); model.Xrv X(dataIdx, :); model.width width; model.beta beta; end逻辑说明Phi 是 N×(N1) 的核矩阵每一列对应以某个训练样本为中心的基函数在全体样本上的取值最后一列是偏置。alpha 与列一一对应剪枝本质就是把某些列的 alpha 推到阈值以上让它们不再影响结果。Sigma 那一行用反斜杠解线性方程组而不是 inv数值稳定性更好diag(Sigma) 是迭代里唯一必须拿到完整协方差的地方代价是 O(N³)这正是 RVM 不适合上万样本的原因。参数含义width 是高斯核宽度控制基函数作用半径maxIter 一般给 500tol 给 1e-3alpha 初始 1e-3 表示先验方差 1000基本是无信息先验beta 初始用 1/var(t)把噪声刻度校准到数据方差。对应预测函数function yp rvm_predict_gauss(model, Xnew) % 用训练得到的相关向量对新输入预测 sq sum(Xnew.^2, 2); sqr sum(model.Xrv.^2, 2); DD sqrt(max(sq sqr - 2 * (Xnew * model.Xrv), 0)); K exp(-DD.^2 / (2 * model.width^2)); if model.biasKeep K [K, ones(size(Xnew, 1), 1)]; % 偏置被保留才拼这一列 end yp K * model.w; end权重顺序和训练时 rvIdx 的顺序严格一致先数据基函数后偏置。如果偏置被剪掉biasKeep 为 false就不拼这一列。任何顺序错位都会让结果完全乱掉这是自己改代码时最容易翻车的地方。3.3 多输出联合训练主脚本共享相关向量的实现与两种模式对比联合版本的核心改动只有三处Sigma 不依赖输出所有输出共用gamma 不用每个输出重新算alpha 更新变成对所有输出的分子分母求和。function model rvm_train_mimo(X, Y, width, maxIter, tol) % 多输入多输出RVM联合训练所有输出共享同一组alpha和相关向量 % 输入X N×DY N×M都已归一化其余参数同单输出 [N, D] size(X); M size(Y, 2); sq sum(X.^2, 2); DD sqrt(max(sq sq - 2 * (X * X), 0)); Phi exp(-DD.^2 / (2 * width^2)); Phi [Phi, ones(N, 1)]; K N 1; alpha 1e-3 * ones(K, 1); beta 1 / mean(var(Y)); % 多输出时用所有输出方差的均值 for iter 1:maxIter Sigma (diag(alpha) beta * (Phi * Phi)) \ eye(K); Gamma 1 - alpha .* diag(Sigma); % K×1所有输出共享 muM beta * Sigma * Phi * Y; % K×M每列一个输出 alphaNew (M * Gamma) ./ (sum(muM.^2, 2) eps); resid Y - Phi * muM; betaNew N * M / (sum(resid(:).^2) eps); if max(abs(alphaNew - alpha)) tol abs(betaNew - beta) tol alpha alphaNew; beta betaNew; break; end alpha alphaNew; beta betaNew; end % 用最终超参数重解一次后验 Sigma (diag(alpha) beta * (Phi * Phi)) \ eye(K); muM beta * Sigma * Phi * Y; rvIdx find(alpha 1e3); model.W mu(rvIdx, :); % Krv×M每列一个输出 model.dataIdx rvIdx(rvIdx N); model.biasKeep any(rvIdx N 1); model.Xrv X(model.dataIdx, :); model.width width; model.beta beta; end逻辑说明muM 的每一列是某个输出在共享基函数上的权重所以模型里存的是 Krv×M 的权重矩阵。beta 更新时残差要摊到 N 和 M 的所有元素上分子是 N*M。alpha 更新的分母 sum(muM.^2, 2) 把所有输出的权重平方加总相关向量是全部输出投票选出来的而不是某一个输出单独说了算。主脚本把两种模式都跑一遍做对比这份示例代码可以直接抄width 1.0; maxIter 500; tol 1e-3; % 方式A逐输出独立训练得到M个模型 modelsA cell(M, 1); for m 1:M modelsA{m} rvm_train_gauss(Xtr, Ytr(:, m), width, maxIter, tol); end YpA zeros(size(Yte)); for m 1:M YpA(:, m) rvm_predict_gauss(modelsA{m}, Xte); end % 方式B联合训练一个模型同时预测所有输出 modelB rvm_train_mimo(Xtr, Ytr, width, maxIter, tol); YpB rvm_predict_mimo(modelB, Xte);3.4 预测与反归一化回归结果怎么回到原始量纲归一化空间里的误差没有业务含义最后一定要还原。反归一化用的 sy、muY 是训练时保存的输出统计量测试输出的原始值 Yte0 也要留着用于对比。预测和反归一化做完回归分析结果才算闭环。YpA_orig YpA .* sy muY; YpB_orig YpB .* sy muY; rmseA sqrt(mean((YpA_orig - Yte0).^2, 1)); % 每个输出一个RMSE rmseB sqrt(mean((YpB_orig - Yte0).^2, 1));还有一件事容易被忽略反归一化只对输出做输入 Xte 永远保持在标准化空间里。如果拿原始量纲的 X 直接喂给 modelB 预测核距离全部错位结果一眼就能看出来——预测值全在同一个量级附近毫无区分度。4. 核宽度、收敛阈值与初始噪声RVM多输出回归的必调参数4.1 核宽度 σ用距离中位数初始化再用网格搜索定标RVM 的核宽度是唯一一个对结果有决定性影响的连续参数同时控制精度和稀疏率。宽度大基函数平滑任意两个样本的核值都很接近模型容易把所有基函数都剪掉最后只剩常数项宽度小基函数尖锐每个样本只在自身附近有响应模型能拟合很复杂的曲面但相关向量数量会暴涨且容易过拟合。这个权衡方向和 SVM 一致但 RVM 反应更剧烈因为剪枝机制会把太像的基函数成批干掉。我一般不用盲试先用训练样本两两欧氏距离的中位数做起点再在 log 尺度上做网格搜索% 用训练集距离中位数初始化宽度避免手填量级完全不对 sq sum(Xtr.^2, 2); DD sqrt(max(sq sq - 2 * (Xtr * Xtr), 0)); dvals DD(tril(true(Ntr), -1)); % 取严格下三角去掉对角线的0 width0 median(dvals); widths width0 * [0.3, 0.5, 1, 2, 5]; % 网格在log尺度上对称取为什么用中位数不用均值样本间欧氏距离分布右偏个别离群点会把均值拉大好几倍中位数对离群点不敏感作为尺度起点更稳。网格取 0.3 到 5 倍中位数覆盖了过拟合到全剪掉两个极端之间的大部分区间。配合第 6 章的交叉检验每个宽度跑一遍选平均误差最小的那个。注意宽度网格要基于训练集距离算不要用全体数据和归一化一个道理。4.2 迭代次数与收敛阈值什么时候该停怎么看收敛曲线RVM 的迭代是证据边际似然单调上升的过程不存在越迭代越差的过拟合问题所以判停条件就是超参数不再明显变化。maxIter 给 500 通常足够见过需要 1000 次的是宽度偏大导致剪枝过程拖沓tol 给 1e-3 和 1e-4 结果几乎没有差别但 1e-6 会让很多样本白跑几百轮。这里的收敛看的是 alpha 和 beta 的相对变化不是损失函数下降因为证据最大化不是梯度下降没有学习率。迭代过程中的健康检查比最终结果更重要nActive zeros(maxIter, 1); for iter 1:maxIter % ... 迭代主体代码 ... nActive(iter) sum(alpha 1e3); if nActive(iter) 0 warning(第%d轮所有基函数被剪枝检查核宽度和beta初值, iter); break; end end如果迭代到一半活跃基函数数量突然掉到零后面再怎么跑都是常数预测不如直接停下来诊断。正常情况是前几十轮数量快速下降然后进入平台期缓慢减少最后几十轮基本不动。看到这种曲线就可以放心用 tol 判停了。4.3 初始 alpha 与 beta先验精度和噪声刻度的第一印象初始 alpha 取 1e-3 是常见做法意思是权重先验方差 1000几乎不给任何收缩让数据说了算。如果初始 alpha 取 1 或更大某些弱信号基函数在第一轮就被压死后面没有机会翻身。初始 beta 用输出方差的倒数单输出是 1/var(t)多输出联合是 1/mean(var(Y))。把噪声尺度校准到和输出同一个量级如果直接用 1 或 1e-3证据最大化前几轮会把几乎所有 alpha 推向错误方向最后收敛到一个奇怪的稀疏解。多输出联合训练还有一个隐藏要求Y 的各列必须先归一化。beta 是全局标量第一个输出方差 1000、第二个输出方差 1 时证据会被第一个输出主导第二个输出的预测基本退化成均值。z-score 之后各输出方差都是 1beta 初始就是 1迭代处于均衡的刻度上。4.4 RVM多输出回归必调参数速查表参数推荐起点作用典型翻车现象width训练集两两距离中位数基函数平滑度与稀疏率过大零相关向量过小过拟合maxIter500迭代上限太小未收敛就停tol1e-3超参数变化判停太小白跑几百轮alpha 初始1e-3权重先验精度太大弱信号被提前剪掉beta 初始1/mean(var(Y))噪声精度刻度乱给稀疏解畸形剪枝阈值1e3alpha 多大算无穷大阈值过小误删弱相关向量这张表可以直接贴到代码注释里。我的习惯是先把 beta 初始化、归一化这两步做对再去调宽度——宽度网格搜索能找出问题但 beta 和归一化错了网格搜索救不回来。5. 避坑指南RVM多输出回归的5个高频问题与排查5.1 现象1一个相关向量都没留下预测退化成常数现象训练后 rvIdx 为空或只剩偏置项模型对测试集的预测输出是一个恒定值RMSE 和直接拿均值预测差不多。原因最常见是核宽度过大所有基函数太平滑任意两个样本的核值都接近证据最大化认为一个基函数就够表达全部信息其余全部剪掉。其次是数据没归一化就喂进去某些特征数值范围大到几十万欧氏距离的平方项溢出核值全部趋近于零所有基函数失去作用。第三种是 beta 初值给得离谱比如直接给 1噪声被估计得过大模型认为数据全是噪声。解决先用第 4 章的中位数初始化宽度不要手填确认 X 和 Y 都做了 z-scorebeta 初始改成 1/var(t)。按这个顺序排查大多数情况下第二步就能看见相关向量数量恢复到几十个。5.2 现象2训练集拟合很好测试集一塌糊涂现象训练集 R² 有 0.9 以上测试集 R² 掉到 0.3 以下而且相关向量数量非常多占训练样本的三成以上。原因核宽度太小是最直接的原因基函数只在样本自身附近有响应模型记住了每个训练点。另一个常见原因是归一化统计量泄漏muX、sx 如果用全体数据算测试集的信息已经进过模型训练误差虚低测试误差反而正常偏高看起来就像过拟合。解决把宽度网格往中位数的 0.5 倍和 1 倍方向多试几个值检查归一化代码确保 muX、sx 只来自训练集。还有个容易忽视的点独立训练多输出时M 个模型各自过拟合的概率更高因为每个模型只有 N 个样本却要拟合 M 份参数空间这时候联合训练通常能明显改善测试误差。5.3 现象3联合训练反而不如逐个输出独立训练现象同一份数据把每个输出单独训练 RVM测试 RMSE 比联合训练还小联合训练的优势完全没体现出来。原因联合训练的前提是输出之间确实存在相关性相关向量是投票选出来的。如果输出之间基本独立相关系数绝对值小于 0.3强行共享稀疏模式等于给每个输出套了一个不属于它的基函数集合拟合能力被浪费。另一种情况是 Y 没归一化就联合训练大方差输出主导了 beta 和 alpha 的更新小方差输出被牺牲。解决先跑 corrcoef(Y) 看输出相关矩阵。相关性弱就用独立模式别迷信联合一定更好。相关性中等又想联合先把 Y 归一化再训练然后在原始量纲下比较两者的 RMSE用真实业务误差做决定不要只看归一化空间里的数字。5.4 现象4量纲小的输出被全局噪声精度牺牲掉现象M 个输出里方差大的输出预测得很好方差小的输出预测曲线基本是一条水平线和均值没区别。原因RVM 的噪声精度 beta 是全局标量只反映整体噪声水平。当各输出量纲相差几个数量级时方差大的输出在证据里占绝对主导方差小的输出信噪比被压低对应权重被 alpha 剪掉。这是多输出模型的经典问题和用哪个核函数无关。解决输出标准化z-score 或归一化到 [0,1]之后再训练让每个输出的方差都缩放到 1beta 初始取 1/mean(var(Y))。评估时用反归一化后的原始量纲 RMSE 或 MAPE 逐输出报告才能看出标准化是否真的解决了问题。5.5 现象5核矩阵奇异或训练慢得没法做网格搜索现象跑到 Sigma 那一步报矩阵接近奇异或者 N 到两三千之后单次训练要好几分钟网格搜索根本没法做。原因Phi*Phi 的规模是 (N1)×(N1)求逆是 O(N³)两三千样本已经明显吃力。数据里有重复样本或近似重复样本时核矩阵列线性相关剪枝前的 alpha 全是小值矩阵条件数很差。另一个隐藏原因是迭代里没有做剪枝收缩被剪掉的基函数如果还留在 Phi 里矩阵会越来越接近奇异。解决每轮迭代把 alpha 超过阈值的列从 Phi 中删掉再算 Sigma这是标准 RVM 实现都会做的剪枝收缩能同时缓解奇异和加速。样本量大时随机抽样一部分训练样本作为候选基函数中心比如 500 个把 Phi 从 N×N 降到 N×500稀疏率和精度损失通常可控。Sigma 那行用反斜杠解线性方程而不是 inv也能避免一部分数值问题。注意剪枝收缩要放在迭代循环内部第一步就把已经死掉的基函数剔除否则后几轮迭代还在为无意义的列浪费求逆时间。6. 用交叉检验和残差分析验收RVM多输出模型一个能直接照抄的流程模型训练完不能只看训练误差我现在的固定流程是五折交叉检验选宽度、残差分析看结构、和基线模型对比看值不值得用。五折交叉检验不用统计工具箱手动划分folds 5; cvIdx mod(randperm(Ntr), folds) 1; for k 1:folds trIdx cvIdx ~ k; teIdx cvIdx k; model rvm_train_mimo(Xtr(trIdx,:), Ytr(trIdx,:), width, maxIter, tol); Yp rvm_predict_mimo(model, Xtr(teIdx,:)); Yp Yp .* sy muY; % 还原到原始量纲 rmseFold(k,:) sqrt(mean((Yp - Ytr0(teIdx,:)).^2, 1)); end meanRMSE mean(rmseFold, 1);宽度网格的每个值跑一遍取各输出平均 RMSE 最小的 width。注意交叉检验里归一化统计量要在每折的训练部分重新算偷懒用全局统计量会让选出来的宽度偏小、过拟合。残差分析看两件事残差对预测值的散点有没有喇叭形有则说明噪声不是均匀的模型置信区间不可信残差对每个输入特征的散点有没有残留曲线有则说明还有未建模的非线性关系可以加交互项或换核。最后算一下稀疏率相关向量数量除以训练样本数低于 5% 说明模型足够简单可以部署到实时场景。如果业务需要置信区间RVM 的预测方差也可以用公式 sigma²(x) 1/beta phi(x) * Sigma * phi(x) 直接算出来这是它比 SVR 值钱的地方。最后拿线性回归和 SVR 在同一份测试集上对比。RVM 值不值得做的判断标准很实在样本量几百到一两千、需要概率预测或置信区间、输出之间有相关性这三点占两样就值得样本上万、纯追求极致精度不如直接上神经网络。我现在的习惯是拿到一张多输入多输出的回归任务先写一个最小脚本把数据读进来算相关矩阵和距离中位数再决定独立还是联合训练最后用交叉检验定宽度——这套流程跑下来标题里说的代码完整、数据齐全才能真正变成自己手里的预测能力。希望帮到你。本文还有配套的精品资源点击获取
返回列表