资讯动态

MRMR与ReliefF特征选择:从高维表中挑出真正有用的特征

发布时间:2026/10/4 23:27:33 来源:尧图企业网站定制
简介一份面向MATLAB学习者和机器学习初学者的特征选择算法实现包聚焦MRMR最大相关最小冗余与ReliefF两种主流筛选方法用于在高维数据中剔除冗余特征、提升模型精度可作为课程设计、论文实验或竞赛项目的参考代码。压缩包共21个文件约101KB包含m脚本、mexa64/mexw64编译接口、cpp源码及dll动态库等m脚本可直接运行和修改mex相关文件负责底层加速cpp与dll便于功能扩展与移植。已有265人学习下载适合需要快速对比两种算法效果并动手实践的人群。两套算法流程区分清晰对照MRMR的互信息计算与ReliefF的近邻加权思想可理解特征评分、权重更新与最终筛选的完整步骤也能在此基础上替换自有数据集并观测验证效果是掌握特征选择原理与MATLAB工程实现的实用素材。1. MRMR和relieff从高维表里挑出真正有用的那几个特征实验室里最常遇到的场景不是算法不会跑而是手里那张表太宽了两百个样本八百列特征标签就一列。直接丢进分类器过拟合到怀疑人生。特征选择就是干这个的而MRMR和relieff是我在这个场景下最常用的两个方法。MRMR全称最小冗余最大相关性思想很直白选出来的特征既要跟标签关系密切彼此之间又不能太像relieff则换了个角度通过样本的近邻关系给每个特征算权重。两个方法思路完全不同但可以跑同一份数据互相印证。这篇文章就把这两个方法从原理讲到参数再讲到你在自己数据上会踩的坑照着做基本能跑通。2. MRMR特征选择先看相关性再砍冗余2.1 为什么“相关性强”还不够必须同时看冗余先说最朴素的方案算一下每个特征和标签的相关系数从大到小排序取前K个。这个做法的问题在于如果数据里有二十个特征其实来自同一个传感器、表达高度同步它们全排在前面取前十个就等于只选了一个信息源。你以为是十个特征在投票其实是一个特征复制了十份。MRMR把这件事拆成两个目标。第一个是最大相关性衡量候选特征和标签之间的关系强度常用的是互信息而不是简单相关系数因为互信息能捕捉非线性关系。第二个是最小冗余衡量候选特征和已选特征集合之间的重叠度如果新特征和集合里的特征高度相关那它对集合提供的新信息就有限。两个目标合起来就是每选一个新特征时让“与标签的相关性”减去“与已选集合的冗余度”这个差值最大。这跟选人有类比不是选个人能力最强的几个而是选一个团队——每个人都要能干但技能不能全重叠。实际执行时MRMR是排序算法每一步选当前最优不回头重新调整所以是贪心搜索。常见做法是每轮从候选集中挑出得分最高的把它加入已选集合然后更新剩余特征的冗余惩罚项。这个过程的复杂度可控几百个特征很快。2.2 MATLAB 里跑 MRMR自带函数与手写实现新版本 MATLAB 直接提供了官方实现fscmrmr它是针对分类任务的评分函数。如果你用的是 R2021b 之后的版本直接调用是最省事的方案% X 是 n×p 矩阵n 为样本数p 为特征数 % Y 是 n×1 分类标签必须是 categorical 或数值型分类值 [idx, scores] fscmrmr(X, Y); % idx 是特征下标按重要性从高到低排列 % scores 是对应的重要性评分和 idx 一一对应 topN 10; selectedIdx idx(1:topN);在动手前一定要把标签转成 categorical否则有些版本会报标签类型错误。fscmrmr返回的idx已经是排好序的特征编号不是权重向量所以不需要再对scores做一次排序。这个函数内部会对连续特征做离散化处理因此你给它的原始特征可以是连续值不用自己提前分箱。如果遇到老版本 MATLAB常见做法是找第三方实现的mrmr_mid或mrmr_mrmr逻辑同样是互信息加冗余惩罚只是需要自己维护特征索引。手写路径也不复杂核心逻辑适合理解算法内部发生了什么% 手写 MRMR 简化版用互信息近似做特征排序 function selected mrmr_simple(X, Y, k) nFeat size(X, 2); selected []; candidates 1:nFeat; % 预计算每个特征与标签的互信息 for i 1:k scores zeros(length(candidates), 1); for j 1:length(candidates) f candidates(j); % 相关项候选特征与标签的互信息 rel mutualinfo(X(:, f), Y); % 冗余项与已选特征的互信息均值 red 0; for s 1:length(selected) red red mutualinfo(X(:, f), X(:, selected(s))); end red red / max(1, length(selected)); scores(j) rel - red; end [~, bestIdx] max(scores); selected(end1) candidates(bestIdx); %#okAGROW candidates(bestIdx) []; end end这段代码的性能不怎么样但逻辑忠实反映了 MRMR 的核心公式。互信息函数需要你自己实现常见做法是把特征离散化成几个区间然后统计联合分布。fscmrmr和你手写结果的排序不一定一致因为官方实现内部有更精细的分箱策略和冗余惩罚系数但前几个特征通常高度重合。2.3 MRMR 的输出怎么读选几个特征才不亏读fscmrmr的结果最容易犯的错误是把scores当置信度。scores只用于特征之间的相对比较绝对值没有物理意义。你在论文里看到有人写“MRMR 重要性得分是 0.42”这个数字本身不说明任何事。决定选几个特征我一般看排序分数的“断崖”。把scores画成折线图前几个分数下降很快后面变成平缓的尾巴拐点之前就是值得保留的特征数。另一个更可靠的做法是带上分类器做前向验证取 Top5、Top10、Top20 分别训练同一个模型看验证集精度什么时候开始下跌或停滞。那个点就是最佳特征数。% 画出得分曲线观察拐点 figure; plot(scores, -o); xlabel(特征排名); ylabel(MRMR 得分); title(MRMR 得分衰减曲线); grid on;如果曲线从头到尾都平缓没有明显拐点说明特征和标签的关系很弱MRMR 排不出有区分度的顺序。这时候别硬选先回去看看标签有没有问题或者特征本身是否噪声占主导。3. ReliefF用邻居关系给特征投票3.1 ReliefF 的想法同类相近异类相远relieff 的思路和 MRMR 完全不同它不需要计算互信息而是基于一个直觉好的特征应该让同类样本靠得近让异类样本离得远。算法随机挑一个样本找到它的 k 个同类近邻和 k 个异类近邻然后逐个特征检查如果该特征把同类样本拉远了就扣分如果它把异类样本推远了就加分。反复迭代很多轮每个特征得到一个权重。这个算法对特征间的交互不敏感它关注的是每个特征单独的判别能力。所以它的典型用途是作为预筛选器——先跑 relieff 把上千个特征压缩到几十个再丢给 MRMR 或直接训练模型。在 MATLAB 里调用只需要一行% X 是 n×p 特征矩阵Y 是标签 % k 是近邻个数默认取 10 [weights, idx] relieff(X, Y, 10);weights是每个特征的权重idx是按权重降序排列的特征下标。正权重说明该特征在一定程度上能把类别分开负权重说明它更像噪声。但要注意relieff 权重的大小受特征尺度影响很大如果特征 A 的取值范围是 0 到 100特征 B 是 0 到 1欧氏距离会被 A 主导导致 A 拿到虚高的权重。所以跑之前务必做标准化这是资深用户和新手之间最常见的差别。3.2 回归和分类的差别不一定只用于监督分类很多人以为 relieff 只能做分类实际它同样支持回归标签。MATLAB 里只要把 Y 传成连续数值向量relieff会自动走回归分支近邻的定义改为“目标值接近的样本”。回归场景下它的迭代逻辑略有变化同类近邻变成了“同响应值近邻”异类近邻变成了“响应值相差大的近邻”。% 回归场景示例 Y_cont X(:,1) * 2 X(:,2) * 0.5 randn(size(X,1), 1) * 0.1; [weights_reg, idx_reg] relieff(X, Y_cont, 5);这里k我改成了 5因为回归场景下近邻的作用更局部化小的 k 值更能捕捉局部模式。k的调整思路是样本量大有冗余k 可以设大一些样本量小或者类别不均衡k 设小一点通常 5 到 15 之间调。这算是一点经验不算严格定理。另外relieff的权重更新不是简单累加而是对每个特征独立计算“同类近邻距离增量”和“异类近邻距离增量”然后做归一化。所以不同特征在同一套数据里的权重可以直接比较大小这和 MRMR 只是排序分数的逻辑不一样。你可以放心地说“特征 3 的 relieff 权重比特征 17 高”这是有意义的比较。跑完多看几个近邻样本确认权重不是被个别离群点带偏的。离群点对 relieff 的影响是个真实的坑后面避坑章节会展开。3.3 权重排序的现实含义面试官排名不等于能力排名relieff 给每个特征一个权重但权重排序本质是被“邻居距离”定义的。如果某个特征只在个别样本上有判别力它的权重可能排名不错但在大多数样本上不发挥作用。这种特征在交叉验证里表现不稳定跑一次一个样。所以我拿到weights后不会立刻按权重从大到小取 TopN而是把权重为负的特征先剔除再在正权重特征里做一次稳定性检查。稳定性检查的方法很简单把数据随机分成三份对每份单独跑relieff取排名前 20 的特征看三份之间重合率。重合率超过一半说明这些特征是稳定信号重合率不到三分之一说明排序靠运气就算权重再高也不可信。这是个脏活但能帮你省下后面模型调参的大量时间。% 三折稳定性检查 topN 20; idx_sets zeros(3, topN); for fold 1:3 % 取其中一份子集跑 relieff subset fold:3:size(X, 1); w relieff(X(subset,:), Y(subset), 10); [~, idx_sort] sort(w, descend); idx_sets(fold, :) idx_sort(1:topN); end % 统计每个特征出现的次数 overlap histcounts(idx_sets(:), 1:size(X,2)1); stableIdx find(overlap 2); % 至少在两折中出现注意这段代码里subset fold:3:size(X, 1)是按顺序采样不是随机采样如果你的数据本身有序这里要用randperm切。我只是用来说明稳定性检查的思路不是可以直接搬的脚本。实际中我会把 X 和 Y 都shuffle一遍再切分。4. 落地跑通解压、数据预处理、最小测试脚本4.1 解压 rar 包之后做什么拿到matlab MRMR和relieff特征选择方法.rar这类压缩包解压后的典型结构一般包含一个或多个.m脚本、一个示例数据集、一份说明文档。第一步不是打开脚本而是先确认文件里的数据格式和你自己的数据是否匹配。常见的数据文件是.mat或.xlsx后缀能直接看出。用who命令查看.mat文件里的变量名确认有哪些变量、维度是多少避免加载后才发现变量名对不上。% 加载 .mat 文件后查看内部变量 load(demo_data.mat); who % 输出示例X Y feature_names解压环节有个小坑某些 rar 文件是伪加密或者包内文件名含中文用系统的“解压到当前文件夹”可能在解压中途报错。我一般用 7-Zip 或 WinRAR 的“修复压缩文件”选项重新解压一次多数情况下能正常出全部文件。如果修复也救不了问题大概率不在压缩文件本身而是下载过程中文件损坏重新下载比找解密工具靠谱得多。4.2 一份可以照着跑的最小测试脚本不管压缩包里给的是什么代码我拿到手第一件事永远是先跑通一个最小例子确认函数接口长什么样。下面这份脚本可以直接复制运行用的是随机生成的数据不需要外部文件% 最小测试脚本MRMR 与 relieff 对比 rng(7); % 固定随机种子保证可复现 % 生成 200 个样本、100 个特征的模拟数据 nSample 200; nFeature 100; X randn(nSample, nFeature); % 构造标签前 8 个特征与标签有关其余是噪声 y_score 2*X(:,1) - 1.5*X(:,2) 0.8*X(:,3) .* X(:,4) 0.3*X(:,5); y double(y_score median(y_score)); % 二分类 y categorical(y); % --- MRMR --- [idx_mrmr, scores_mrmr] fscmrmr(X, y); topMRMR10 idx_mrmr(1:10); % --- ReliefF --- [weights_rf, idx_rf] relieff(X, y, 10); topRF10 idx_rf(1:10); % --- 对比两个方法选出的特征重叠 --- overlap intersect(topMRMR10, topRF10); fprintf(MRMR Top10: %s\n, mat2str(topMRMR10)); fprintf(ReliefF Top10: %s\n, mat2str(topRF10)); fprintf(两个方法重叠特征%d/10\n, length(overlap));这段代码在 R2021b 之后的版本上可以直接运行。fscmrmr要求标签是categorical或数值型我这里显式转成了categorical避免因为默认 double 类型触发内部逻辑差异。relieff的第三个参数是近邻数k我选 10因为 200 个样本下 10 个近邻不至于太少也不会覆盖到太远的样本。重叠特征数一般会在 6 到 8 之间说明两个方法筛选的信号方向基本一致。4.3 数据和代码的预处理顺序不能颠倒直接拿原始数据跑特征选择是新手最常见的翻车姿势。特征选择算法本身不关心量纲但 relieff 用欧氏距离量纲大的特征就是会拿高分。MRMR 的互信息计算虽然不受量纲影响但如果数据里缺失值一堆互信息估计会直接出问题。所以预处理顺序要固定成先补缺失值再做标准化或归一化最后才能跑特征选择。补缺失值用fillmissing默认方法是对数值矩阵按列用中位数补全分类特征用missing转成categorical再处理。标准化用zscore就够它会逐列减去均值除以标准差。注意一个细节标准化应该在整个数据集上做还是在训练集上做特征选择阶段一般是在全量数据上做因为特征选择是探索性步骤不是建模步骤。但如果你后面要接模型训练标准化的参数必须在训练集上拟合然后应用到测试集不能直接对整个 X 调zscore否则会引入数据泄漏。这个区别值得记牢。% 统一预处理流程 X_raw fillmissing(X_raw, median); % 先补缺失 X_scaled zscore(X_raw); % 再标准化 % 之后才进入 fscmrmr / relieff如果你的数据是表格类型记得先table2array转成数值矩阵再走上面的流程。表格中如果混有字符串列zscore会直接报错这是另一个常见的报错点。5. MRMR 和 relieff 的避坑清单5 个高频问题5.1 现象一relieff 结果每次跑都不一样明明数据没变relieff跑两次前几个特征的权重排序变了。原因是函数内部有随机采样过程每次抽取的“锚点样本”不同权重结果是带随机性的。这个不算 bug但很多刚上手的人会怀疑自己数据出了问题。解决办法是把随机种子固定在脚本开头rng(0)或任意别的常数。如果固定了种子还是每次不一样检查是不是脚本里其他地方调用了rand、randn等函数扰动了随机数流。另一个做法是把relieff多跑几轮取平均权重比如跑 20 次取均值能显著提高排序稳定性。5.2 现象二fscmrmr 报错说标签类型不对标签是数值向量直接传给fscmrmr报错信息提示标签必须是分类变量。这个在旧版本里偶尔出现新版兼容性好一些但最稳妥的做法是显式转换y categorical(y)。注意转换后类别的顺序可能跟你预期的不一样如果有二分类且类别顺序对结果有影响的地方先reordercats指定顺序。另一个隐蔽问题标签类别严重不均衡时fscmrmr的互信息估计会偏向多数类。如果正负样本比例超过 5:1常见做法是先对多数类降采样或者用fscmrmr之前做一次类别加权修正——简单方式是把多数类样本随机去掉一部分再跑排序保住少数类的判别信息。5.3 现象三特征标准化之后relieff 权重全变成负的标准化后的数据跑 relieff所有特征的权重都小于零有人会怀疑是不是标准化做错了。这其实是正常信号这个数据集的每一个特征单独看都不足以把类别分开——它们需要组合起来才有效。relieff 只考虑特征的独立判别力对纯交互型特征天然不友好。这种情况说明你不该用 relieff 做最终特征选择应当换成 MRMR 或者用树模型的特征重要性。这不是方法选错而是数据形态和算法假设不匹配。5.4 现象四解压 rar 时提示密码错误但资源页没写密码这个坑和算法本身无关但确实卡住了不少人。很多打包者给 rar 加了密码但描述里没写清或者用了伪加密——伪加密的意思是文件其实没加密只是标记位被设置WinRAR 会误报需要密码。遇到这种情况先用 7-Zip 打开如果 7-Zip 能直接看到文件列表并解压说明是伪加密用 7-Zip 恢复正常解压即可。如果 7-Zip 也提示密码那就真加密了只能回到下载页面找密码说明。5.5 现象五MRMR 的结果在交叉验证里精度反而比全特征差选出的特征变少了分类器精度却比用全部特征时还低。这不一定是你选错了特征更可能是两个问题之一一是你选的 TopN 太少有效信息被删掉了二是你只用了特征选择结果做一次排序没有和分类器配合起来做前向选择。正确做法是把“特征选择 分类器”当成一个整体用验证集精度作为选 N 的依据而不是只看算法打分。特征选择给的是候选清单不是最终结论这个认知能帮你省掉后面一堆调参的冤枉路。6. 把方法用在自己的数据上如何选型、如何验证、怎么收尾6.1 两个算法怎么选看你关心什么样本几百、特征几千想快速压缩到一个可管理的数量级先把 relieff 跑一遍按权重取正的部分再做后续分析。特征之间有明显的功能分组比如多个特征来自同一传感器或同一主题希望挑出来的特征彼此不冗余MRMR 是更稳的选择。分类任务用fscmrmr回归任务自己写简化版 MRMR 或者用relieff的回归分支两条路都通。不要把两个方法当互斥选项交叉使用能看到更全面的信号。6.2 特征选择结果要验证不要直接进模型还当万事大吉我的验证流程固定三步第一把两个方法的 TopN 重叠率作为第一层过滤指标重叠率低的特征排序不可靠第二用选出的特征集合和全特征集合分别跑同一个模型比较验证集表现特征选择至少不应该掉太多精度否则说明你删掉了必要的信息第三对最终特征集合做一次业务侧确认——也就是让熟悉数据的人看一眼这些特征在现实里是否解释得通。如果算法选出的特征在业务上完全没法解释往往不是算法错了而是数据噪声或标签质量问题。这个验证做完才算真的跑完一轮特征选择。6.3 一个值得养成的结束习惯我自己做完特征选择不会着急写结论。先把两个方法的排序结果保存成.mat连同特征名一起存一份方便后面回溯。命名规范是20240620_项目名_mrmr_rf_selected.mat带日期的文件在项目后期救过我很多次。特征选择是一次性探索但它决定后面所有建模工作的走向过程留痕比结果本身更重要。这样一轮跑下来MRMR 和 relieff 就不再是压缩包里的两个黑匣子而是你工具箱里两个思路清晰、知道边界在哪的工具。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑