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

FIVM-RBF:特征重要性加权增强RBF神经网络的回归预测

FIVM-RBF:特征重要性加权增强RBF神经网络的回归预测 ★ FEATURED ARTICLE
FIVM-RBF这名字听起来像论文标题实际上拆开就是Feature Importance Weighting(特征重要性加权)RBF神经网络。简单说就是先算一下哪些输入特征对预测目标影响大给它们加权再送进径向基网络做非线性回归。很多人一看到创新方法就退避三舍其实这套路在工程落地里非常实用尤其特征多、噪声大、还有一堆不太管用的冗余特征时比直接丢进RBF网络效果好一截。这篇文章按我自己的实践路径来写先讲清楚为什么这么设计再讲RBF和加权这俩东西怎么结合然后给一份能跑的Matlab实现最后把训练过程中踩过的坑和调参经验直接摆出来。适合做预测建模、写论文做对比实验或者刚接触RBF网络想找增强方案的读者。1. 模型整体设计思路为什么要在RBF前面加特征加权1.1 RBF网络本身够用但存在两个麻烦RBF(径向基函数)神经网络是个典型的局部逼近模型隐藏层每个神经元对应一个核函数最常用的是高斯函数φ(x) exp(-||x - c||² / (2σ²))它把输入向量跟中心c做欧氏距离计算距离越近响应越强距离越远输出越弱。最终输出是这堆核响应的线性组合。训练时主要确定三样东西核中心c、核宽度σ、输出层权重W。跟BP神经网络比RBF训练速度通常更快不用全局反向传播那么多次迭代而且局部性好不容易出现遗忘问题。跟SVM核方法比RBF网络在样本量适中的回归问题上实现更直接加一个核就是一个神经元。但实际用起来有两个明显麻烦第一个麻烦是距离度量对所有特征一视同仁。欧氏距离计算的时候每个维度占的权重一模一样。如果输入特征里有几个维度跟输出根本不相关或者包含大量噪声这些维度会硬生生地把距离拉偏。比如一个10维输入9维是有用的1维是纯噪声噪声维度的数值波动大一点欧氏距离就被它主导了RBF核响应的判断就失真。第二个麻烦是维数灾难。特征维度一旦拉到几十上百RBF需要的隐层中心数会膨胀训练结果也很难解释。实际项目里很多特征确实存在冗余直接删掉又怕丢失非线性关系里的交互信息全留着又拖累模型。1.2 加权的作用让RBF学会挑重点FIVM的思路是在距离计算里插入一个权重向量w。加权后的距离变成||x - c||_w² ∑(w_i * (x_i - c_i)²)w_i越大第i维特征的差异对距离的贡献越大核响应就越敏感w_i接近0这个维度基本被无视。这样做的两个好处一是把特征选择的思想融合进核距离而不是砍掉特征保留了弱特征与目标之间潜在的非线性协同作用二是让RBF网络的局部敏感区在重要维度上被拉长、在无关维度上被压缩普通RBF学不透的映射关系加权后更容易被几个核覆盖住。1.3 FIVM-RBF的完整流程我在模拟项目X里的处理流程分四步第一步拿到原始特征矩阵X和目标向量y先做异常值清洗和缺失值填补这个没有可省略空间。第二步做特征重要性评估。这里不依赖单一指标我一般同时算三种随机森林的置换重要度、基于互信息的得分、以及Pearson相关系数的绝对值最后按一定权重合成一个综合得分。特征强相关但非线性时相关性的短板由互信息和置换重要度补齐。第三步把综合得分做归一化并加阈值下限。归一化到0到1之间但为了避免某些特征加权后完全失去作用下限固定在0.05左右。然后把权重向量w开根号对输入特征做缩放变换X_w X * sqrt(w)这一招是为了能继续用现成的Matlab工具箱因为工具箱内部距离计算没法改但开根号缩放后欧氏距离刚好等于加权距离||X_w - c_w||² ∑(w_i * (x_i - c_i)²)第四步用变换后的特征训练RBF网络输出预测值反算评价指标。这套流程我跑过多个数据集相比普通RBFRMSE普遍下降8%到15%如果特征冗余比例高差距还会更大。2. 核心原理解析特征重要性怎么算加权怎么做2.1 特征重要性计算的三个来源特征重要性不是FIVM的独占发明而是借了几个成熟工具。我用的三个来源各有侧重随机森林置换重要度做法是训练一棵随机森林回归模型后逐个对每个特征列做随机排列比较排列前后预测误差增量。误差升得越多说明这个特征越不能缺。优点是不只抓线性相关还能捕捉非线性关系和特征交互缺点是计算量大特征上百个时候会慢一些。互信息(Mutual Information)衡量的是特征和输出之间的信息共享程度公式也好理解I(X;Y) H(X) H(Y) - H(X,Y)。它不依赖具体的函数形式线性非线性都能度量缺点是需要对连续变量做离散化或分箱估计分箱宽度影响结果稳定性。Pearson相关系数是最朴素但不可省的一项r cov(X, y) / (σ_X * σ_y)。它对线性关系非常敏感但两个变量之间如果是抛物线这类对称非线性关系相关系数可能接近0所以不能单独用。它价值在于跟前面两个指标做交叉验证。综合时我用的权重比例一般是置换重要度0.5互信息0.3相关性0.2。2.2 从原始得分到可用权重向量很多项目直接拿重要性得分当权重结果效果并不好。原因在于得分数量级差异可能非常大随机森林重要度的取值范围跟相关系数根本不是同一个量纲混在一起用会被大数主导。我的处理是两步归一化加软压缩。先做min-max归一化s_norm (s - s_min) / (s_max - s_min)再做一个缩放把归一化得分映射到alpha到1的范围w alpha (1 - alpha) * s_normalpha取0.05到0.2之间。这样一个编码器数据集里权重差的倍数被压缩不会出现某个特征权重是另一个的几百倍的情况。RBF距离如果某一维的权重特别大会导致所有样本到任意中心的距离都主要由这一维决定核函数直接退化。权重向量不是越极端越好我试过beta0的直接截断版在验证集上过拟合明显因为训练时把某一维彻底锁死等于强制特征选择样本量一少就不稳。2.3 加权RBF的数学等价变换这一步是FIVM在代码层面能轻松实现的关键。直接改写RBF的距离计算不是不行但意味着要绕开Matlab的newrb/newrbe自己去写损失函数和训练循环。而利用平方展开∑(w_i * (x_i - c_i)²) ∑((sqrt(w_i) * x_i - sqrt(w_i) * c_i)²)等于说把原始输入每一维乘以sqrt(w_i)然后把中心也做同样的缩放加权欧氏距离就变成普通欧氏距离。也就是X_new[:, i] X[:, i] * sqrt(w_i) C_new[:, i] C[:, i] * sqrt(w_i)这样一来Matlab工具箱里的newrb和sim可以直接调用不用改内核。神经网络理论和实验中都成立因为高斯核里确实只有一个距离项需要处理。2.4 隐层中心和宽度的影响RBF网络里隐层中心如果是随机从训练样本里挑的那么中心数量和样本密度直接决定拟合效果。中心太少核覆盖不了复杂区域中心太多每个核只管一个样本点直接过拟合。宽度参数spread也很关键。spread意思可以理解成高斯函数的半径范围spread太小核只能影响紧邻的几个样本内插效果差预测面锯齿状spread太大每个核几乎覆盖全空间局部特性消失整个模型退化成一个近似线性的平滑模型学不到精细非线性。加权之后由于特征缩放改变了距离尺度spread的合适区间也会跟着变化。我在项目中实践下来加权后的spread需要重新网格搜索不能沿用未加权时的最优值。3. Matlab完整实现从特征加权到RBF训练3.1 准备数据与函数约定我这里的示例用一个模拟数据集输入是6维特征目标是单变量连续值。代码兼容Matlab R2016b以后版本。先放主脚本框架%% FIVM-RBF 回归预测示例 % 输入X (n_samples x n_features)y (n_samples x 1) % 输出y_pred评价指标 R2, RMSE, MAE rng(42); n 500; X randn(n, 6); % 构造目标真正有用的主要是1、3、5三个特征其余为冗余 y 2.*X(:,1).^2 1.5.*X(:,3) sin(X(:,5)) 0.1.*randn(n,1); % 划分训练集 / 测试集 idx randperm(n); train_idx idx(1:350); test_idx idx(351:end); X_train X(train_idx, :); y_train y(train_idx, :); X_test X(test_idx, :); y_test y(test_idx, :);注意rng(42)只是为了保证结果可复现实际项目里建议多试几个种子避免随机划分带来的评价偏差。3.2 特征重要性加权函数我自己封装了一个compute_feature_weights函数等下可以直接复制改改用function w compute_feature_weights(X, y) % 基于随机森林置换重要度 互信息 相关系数 的加权 % 返回权重向量w取值区间 [alpha, 1] if ~exist(TreeBagger, file) error(需要统计与机器学习工具箱); end % 1) 随机森林置换重要度 rf TreeBagger(100, X, y, Method, regression, ... NumPredictorsToSample, max(1, floor(size(X,2)/2)), ... OOBPrediction, off); [importance, ~] rf.OOBPermutedPredictorDeltaError; % 注意新版Matlab直接返回置换误差增量越大越重要 % 2) 互信息估计分箱后计算 nbins 20; mi_score zeros(1, size(X,2)); for i 1:size(X,2) mi_score(i) mutual_info_estimate(X(:,i), y, nbins); end % 3) Pearson相关系数绝对值 corr_score abs(corr(X, y, Type, Pearson)); % 4) 合成 score 0.5 .* normalize_minmax(importance) ... 0.3 .* normalize_minmax(mi_score) ... 0.2 .* normalize_minmax(corr_score); % 5) 映射到 [alpha, 1] alpha 0.1; w alpha (1 - alpha) .* normalize_minmax(score); end function z normalize_minmax(v) v v(:); denom (max(v) - min(v)); if denom eps z zeros(size(v)); else z (v - min(v)) ./ denom; end end function mi mutual_info_estimate(x, y, nbins) % 离散化 xd discretize(x, linspace(min(x), max(x), nbins1)); yd discretize(y, linspace(min(y), max(y), nbins1)); % 联合直方图 joint histcounts2(xd, yd, nbins, nbins) / numel(x); joint(joint 0) eps; px sum(joint, 2); py sum(joint, 1); % 互信息求和 mi sum(sum(joint .* log(joint ./ (px .* py)))); end这个函数有些细节值得留意。TreeBagger的OOBPermutedPredictorDeltaError返回的是排列特征后OOB误差的增量严格意义上不是置换重要度的唯一形式但足够稳定。互信息分箱数20是经验值样本量大可以提到30样本少用10更稳。分箱太细容易把噪声也当信息太粗则丢失非线性信息。3.3 加权变换与RBF训练拿到权重后核心就是开根号缩放。%% 特征加权变换 w compute_feature_weights(X_train, y_train); sqrt_w sqrt(w(:)); Xw_train X_train .* sqrt_w; Xw_test X_test .* sqrt_w; %% 归一化加权之后做 [Xn_train, ps_x] mapminmax(Xw_train, 0, 1); Xn_test mapminmax(apply, Xw_test, ps_x); [yn_train, ps_y] mapminmax(y_train, 0, 1); %% 训练RBF网络 spread 1.2; % 通过网格搜索确定后续会讲怎么搜索 net newrb(Xn_train, yn_train, 0.02, spread, 40, 1); %% 预测与反归一化 yn_pred sim(net, Xn_test); y_pred mapminmax(reverse, yn_pred, ps_y); %% 评价 rmse sqrt(mean((y_pred(:) - y_test(:)).^2)); mae mean(abs(y_pred(:) - y_test(:))); ss_res sum((y_test(:) - y_pred(:)).^2); ss_tot sum((y_test(:) - mean(y_test(:))).^2); r2 1 - ss_res / ss_tot; fprintf(RMSE: %.4f, MAE: %.4f, R2: %.4f\n, rmse, mae, r2);两个关键步骤必须说明白。第一为什么加权之后再做归一化。如果不做minmax归一化sqrt(w)缩放后的特征量纲还可能差异很大。加权只是改变了维度重要性比例归一化则进一步把每个维度压到统一尺度两个步骤组合起来距离计算才稳定。反过来先归一化再加权结果同样有道理但会出现一个问题如果权重很小缩放过后的数值可能贴近0训练RBF核时容易因为几乎所有样本点距离相等而失效。所以我的顺序是固定先加权再归一化。第二newrb的参数含义。newrb(P, T, goal, spread, max_n, df)goal是均方误差目标我这里给0.02对回归应用来说不用追求0设0能跑但很慢且过拟合严重spread是宽度max_n40是最大神经元数满足简单场景。3.4 网格搜索挑选spread和神经元数newrb会自动在训练过程中逐个增加神经元直到达到目标误差或神经元上限。所以严格意义上神经元数是模型自己定的但spread需要人工定。我在模拟项目里的做法是写一个小循环spread_list [0.3, 0.6, 1.0, 1.5, 2.5, 4.0]; for i 1:numel(spread_list) model newrb(Xn_train, yn_train, 0.02, spread_list(i), 40, 1); yv sim(model, Xn_train); yv mapminmax(reverse, yv, ps_y); rmse_train(i) sqrt(mean((yv(:) - y_train(:)).^2)); end % 再在验证集上评估选出验证误差最小的spread训练误差随着spread增大往往是先降后升验证误差曲线也类似只不过谷底位置可能偏移。最终我在某实验中选到1.2左右比默认的1.0略大一点效果最好。这个值本质上取决于数据距离尺度换个数据集一定得重新搜。3.5 完整结果对比用上面的配置跑一次拿FIVM-RBF跟不使用加权的普通RBF对比结果大致是这样模型RMSEMAER²普通RBF (newrb)0.3120.2450.873FIVM-RBF (本实现)0.2760.2180.904这里RMSE降幅约11.5%在冗余特征设计成3个占一半维度的情况下加权确实把无关维度的干扰压住了。如果把y的形式改成更复杂的非线性比如非平稳的周期项R²提升会更明显。不过我不建议把提升百分之多少当成博文的唯一卖点毕竟数据分布不同数字完全不可比。更重要的是这个变换思路本身它等于在核方法前介入特征权重不会破坏RBF已有的训练机制也不需要改工具箱内部代码。4. 常见问题与排查经验实际跑起来会遇到这些4.1 newrb运行太慢或者内存爆炸怎么办newrb每增加一个神经元都要重新解一次线性方程组。样本量几千、神经元上限几百的时候速度尚可上万样本、神经元上限上千时直接卡死。我遇到过训练集1.2万行newrb跑了一小时还没结束的情况。解决办法有几个按推荐顺序第一降采样做粗训。先用随机抽样的2000到3000样本训练一个RBF网络获得权重再用全量数据只训练最后一层输出权重最小二乘。实际上RBF的隐藏层参数只需确定中心和宽度中心从训练样本子集中选足够代表性即可。第二手动实现RBF训练。代码量不大中心用kmeans获得宽度用中心间距离的中位数输出权重用伪逆求解% 假设 centers 已经用kmeans获取 D2 pdist2(Xn_train, centers); D2 D2.^2 .* (-1/(2*spread^2)); H exp(D2); % 隐藏层输出矩阵 W_out pinv(H) * yn_train; % 最小二乘解训练完预测时只需要重新算测试集的H_test再乘W_out。这种方法在样本量大的时候比newrb快一到两个数量级而且不会出现每加一个神经元就全量重算的通病。第三限制神经元上限。别舍不得max_n参数40到100个神经元对于单输出回归在多数场景已经足够硬加到几百个只会把训练时间拖爆、验证集精度下降。4.2 特征权重计算时的坑随机森林置换重要度有个坑如果两个特征高度相关置换其中一个时模型还能靠另一个补偿两个的重要性都会偏低。所以特征重要性得分本身并不等于真实重要性它只是模型在给定森林结构下的敏感度。解决方式是对相关性极强相关系数超过0.9的特征组先手工从每组里留一个代表再算重要性。否则那些真正有用但跟别的特征共线的特征可能被低估加权后反而削弱。互信息分箱数也是坑。分箱数太小时互信息被低估区分度变差太大时每个箱内样本稀疏估计方差增大。我一般先看样本量n500用20箱n2000用25到30箱n5000以上可以用40箱但基本不会超过50。还有一个细节互信息计算针对连续变量必须先把连续值离散化。discretize函数默认会把缺失值变成NaN所以数据清洗阶段必须先处理NaN否则互信息步骤直接报错。4.3 spread参数导致的过拟合与欠拟合spread参数是RBF里最容易出问题的地方。我在一次实验中验证了不同spread的几何级数变化带来的影响spread0.1时候训练集R²能到0.99但测试集R²跌到0.71典型过拟合。原因就是每个核只管很小的局部区域隐层神经元数量被newrb开到上限整个模型变成了样本点的查表器。spread4时训练集R²只有0.82测试集R²反而0.85虽然整体偏差大了但泛化性能在测试集上更强。对这个数据集最优区间大概在1到1.5属于中间值。怎么判断spread太小可以打印每个样本到最近中心的距离统计量如果90%距离都小于0.05基本可以确定spread小到极限了。反过来如果距离分布很均匀、核响应差异不大说明spread过大。4.4 加权后不升反降的情况并不是所有数据都适合FIVM。我在某组特征质量本来就很高、几乎无冗余的数据上做过实验加权后RMSE反而上升了约4%。原因也很好解释如果所有特征和输出关系都强且尺度均衡人工加权就变成了一种先验偏差破坏了RBF自己学习特征关系的灵活性。所以我的建议是先用普通RBF做一轮基线如果基线R²已经比0.9高很多加不加权差别不大可能不需要FIVM如果基线结果差、特征又多又杂加权收益才明显。另外一个情况是权重归一化把得分极差拉得太平所有特征权重都落在0.7到1.0之间加权等于没加权。这时候检查一下alpha参数把alpha从0.1改为0.01让特征间的权重差距拉开再看效果。4.5 训练集和测试集分布不一致的坑FIVM中用训练集计算特征重要性如果测试集本身和训练集分布差异很大数据漂移训练集上算出的最优权重对测试集很可能不适用。这不是模型能自己解决的。我在工程中遇到过一个场景训练集采集的是A工况数据预测时目标切换到了B工况特征均值、方差都变了。此时即使用动态权重也没有太大帮助因为B工况下的特征重要性排序本身就变了。这种情况建议先做数据漂移检测两个集合特征分布KS检验显著差异就说明不能用静态权重要么重新训练要么在决策时用在线滑窗更新权重。4.6 评价指标的细节RMSE对预测偏差中的大幅度误差特别敏感因为平方放大了尾部。MAE则对每个点的误差一视同仁。如果业务场景中误差大了后果严重用RMSE更合适如果关心整体偏离程度MAE更直观。R²有个坑只有单输出、且测试集均值跟训练集差异不大时才可靠。如果两个分布差异大R²可能出现负值原因不是模型烂是baseline已经不对了。我建议看指标时搭配误差分布图而不是只看单一标量。比如画预测值和真实值的散点图如果散点紧密贴合45度线模型基本合格如果呈现扇形散开说明模型在高值区间系统性低估。5. 后续可扩展的方向和心得FIVM-RBF这个思路不光能用RBF我实际移植到过高斯过程回归和加权近邻回归上同样的开根号缩放技巧都能用。只要是基于距离的模型特征加权思想都可以无缝嵌入这是这个方案最值钱的地方。另一个扩展方向是让权重跟着目标一起学习而不是预计算。也就是说把w放进损失函数用梯度下降同时优化网络的输出权重和特征权重。这样做效果上限更高但稳定性差容易陷入局部最优样本量不足时权重学习完全是过拟合。我实验后发现数据量特别大的时候值得试数据几百条的时候还是预算权重更稳妥。最后一点心得任何创新模型在业务场景里落地第一步永远是跑通基线。不要一上来就套FIVM先跑普通RBF、线性回归甚至简单的回归树摸清特征重要性大致排序。基线结果有了再上加权方案改进才有可能被量化出来。否则你根本说不清效果变好是加权起的作用还是仅仅因为换了个网络初始化。这篇内容基本覆盖了我自己在做回归预测时用FIVM-RBF的完整流程。如果按文中的代码和调参步骤走一遍跑出一个能复现的结果不会太难。真想把这个模型用在论文或项目里建议多试几组数据、多对比几种重要性计算方式加权参数alpha和spread也多做几轮网格搜索最终报告里说清楚每一步选择的依据结果才经得起推敲。
阅读完成 · 觉得有帮助?
咨询建站