MRMR与ReliefF特征选择:MATLAB实现与MEX编译实战

发布时间:2026/9/15 22:33:49

MRMR与ReliefF特征选择:MATLAB实现与MEX编译实战 简介面向机器学习与数据挖掘场景的MATLAB特征选择工具包提供MRMR最大相关最小冗余与ReliefF基于近邻的实例权重评估两种经典算法适用于高维数据降维、分类或回归模型预处理等任务满足学习者和研究人员的需要。压缩包共21个文件除.m核心脚本与函数外还包含C源文件、头文件以及面向Windows、Linux、macOS等平台预编译的mexa64、mexw64、mexglx、mexmac动态链接库和dll整体仅101KB部署轻量。已有264人学习下载非常适合毕业设计、竞赛和实际项目中快速嵌入特征筛选流程。借助核心M脚本与底层编译模块可掌握互信息计算、并行加速和交叉验证封装思路通过源码实现理解MRMR与ReliefF的算法细节便于二次开发或学术研究。此外压缩包保留了C与MATLAB两套实现并附有编译辅助脚本可针对自定义数据重新生成可执行文件兼顾运行效率与灵活性。1. 特征选择先用 MRMR 还是 ReliefF从一个 128 维特征集说起做滚动轴承故障诊断时我一度把时域、频域、小波包里能算的特征全堆出来总共 128 维直接丢给 SVM十折交叉验证只有 82%。换用 MRMR 选 30 维准确率到 91%再跑一遍 ReliefF排名虽然和 MRMR 不同但两套方法同时排在前面的特征恰好对应了故障特征频率。这个反差让我意识到MRMR 和 ReliefF 不是二选一的替代关系而是互相验证的关系。这套资源里正好是这两类算法的 MATLAB 实现fs_sup_mrmr基于互信息做最大相关最小冗余fs_sup_relieff用近邻距离计算特征权值。包里还带了一批 MEX 编译文件和辅助脚本适合做毕业设计、数据竞赛、论文算法对比以及想在 MATLAB 里真正把特征选择落到可复现代码上的人。2. MRMR 的互信息计算与 fsMRMR 脚本拆解MRMR 在特征选择里属于过滤式方法不依赖具体分类器。它同时优化两个目标特征与类别标签之间的相关性尽量大特征与已选特征之间的冗余度尽量小。实现时相关性用互信息Mutual Information衡量冗余度也用特征间的互信息衡量。这样处理的好处是能捕捉非线性关系而皮尔逊相关系数只能看到线性相关。2.1 最大相关最小冗余为什么落在互信息上互信息定义为联合分布与边缘分布乘积之间的 KL 散度对离散变量可以直接用概率表估算。对连续变量需要先离散化或者用核密度估计。MRMR 常见的目标函数有两种MID 形式是“相关项减冗余项”MIQ 形式是“相关项除冗余项”。fsMRMR.m大概率实现的是 MID因为 MATLAB 中做互信息差分比做除法更直观而且对特征评分的稳定性更好。还有一点容易被忽略MRMR 是增量式选择每一步从候选特征里挑一个使目标函数最大的特征加入已选集合。所以fsMRMR返回的特征顺序就是特征的重要性顺序第一个是最重要的越往后越边缘。这和relieff返回的权值向量意义不同后面会单独说。2.2 fsMRMR.m 的常见调用方式与参数含义我一般会这样组织调用代码% 数据 XN 个样本D 个特征标签 yN x 1 的分类标签 addpath(./fs_sup_mrmr); k 30; % 期望选出的特征数量 [fea_idx, score] fsMRMR(X, y, k); % 用选出的特征重训分类器 X_selected X(:, fea_idx); mdl fitcsvm(X_selected, y, KFold, 5); acc 1 - kfoldLoss(mdl); fprintf(MRMR 选 %d 维特征5 折交叉验证准确率 %.2f%%\n, ... length(fea_idx), acc * 100);需要注意几个参数细节。k是最终特征数不是近邻数它决定循环迭代几次。fea_idx是排序后的特征下标score是每一步的评分可以画成下降曲线来判断“再加特征收益是否变平”。数据必须清洗干净互信息估算遇到 NaN 或 Inf 会直接报错。如果特征是连续值可以先做等宽离散化常见做法是把每个特征映射到 510 个区间这样estpab.cpp算联合概率时更稳。资源里的fsMRMR_info.m和fsMRMR_parson.m是另外两个入口fsMRMR_info可能返回更详细的信息论中间结果比如相关项和冗余项各自的值fsMRMR_parson用了parfor适合特征维度高、样本量大的情况但要先启动parpool否则并行版本不会比串行版本快。2.3 estmutualinfo 与 estpab互信息到底怎么算出来的这套代码的核心不是 MRMR 的选特征逻辑而是底下那层互信息估算函数。文件清单里能看到一组用 C 写的源码和对应的编译产物下面是它们的分工文件作用miinclude.h公共头文件包含数组操作和概率表结构定义estpab.cpp从样本数据估计联合概率表 p(x, y)estmutualinfo.cpp基于概率表计算互信息 I(x; y)mutualinfo.m对上层暴露的 MATLAB 封装函数estmutualinfo.mexa64Linux 64 位下的预编译 MEX 二进制estmutualinfo.mexw64Windows 64 位下的预编译 MEX 二进制estmutualinfo.mexglxLinux 32 位老版本下的二进制estmutualinfo.mexmacmacOS 下的二进制estpab.dll等Windows 下的动态库或旧格式 MEX 扩展纯 MATLAB 写互信息也能跑但双循环算联合概率会很慢尤其当特征数到几百、每步 MRMR 都要重新估算一次。C 版的好处是直接把概率表算在当前平台的 MEX 里调用开销小。.mexa64、.mexw64这类后缀不是随便命名的mex说明这是 MATLAB MEX 扩展a64代表 Linux 64 位w64代表 Windows 64 位。如果你在新的 MATLAB 版本上运行时报“无效 MEX 文件”基本就是预编译二进制和当前版本 ABI 不匹配解决办法后面单独说。3. ReliefF 的权值更新逻辑与 fsReliefF 验证脚本ReliefF 是从 Relief 算法扩展来的原理比 MRMR 更直观。它不依赖概率模型而是随机抽取样本找同类近邻和异类近邻通过比较特征在这些近邻上的取值差异来更新权值。理解这个概念后fsReliefF.m的输出就很好解释了。3.1 近邻距离与特征权值的关系对每个被抽中的样本 R算法找到它的 k 个同类最近邻和 k 个异类最近邻。对某个特征 f如果 R 与同类近邻的差异小说明这个特征能把同类聚在一起权值增加如果 R 与异类近邻的差异反而很小说明这个特征对区分类别没有贡献权值降低。循环多个随机样本后权值就是该特征区分能力的累计评价。ReliefF 可以处理多分类问题因为它把“异类”按每个类别分别找最近邻最后按类别占比加权。特征可以是连续值也可以是离散值差异度量不同连续值用差的绝对值除以整个特征的范围做归一化离散值用 0/1 是否相同。这带来一个实际要求连续特征最好先做标准化。否则量纲大的特征即使区分能力一般算出来的差异也很大权值会被系统性抬高。我一般在调用前对 X 做zscore或者用mapminmax归一化到 [0,1]。3.2 fsReliefF.m 的调用示例addpath(./fs_sup_relieff); % 近邻数量 k 是调节估计稳定性的参数不是最终特征数 k 10; [weight, fea_idx] fsReliefF(X, y, k); % 按权值从大到小排序取前 40 个特征 [weight_sorted, idx_sorted] sort(weight, descend); selected idx_sorted(1:40); % 看一眼权值分布是否衰减明显 figure; bar(weight(idx_sorted(1:40))); xlabel(特征编号); ylabel(ReliefF 权值);weight是每个特征的权值正数表示有用负数或接近 0 表示可能无关。fea_idx常见情况是已经排好序的特征下标具体以这个压缩包内.m文件的函数注释为准。近邻k一般设置在 5 到 20 之间太小估计方差大太大近邻跨越类别边界边界附近的特征权值会被削弱。小数据集上可以先扫一遍k 5:5:20看权值排序在哪个区间趋于稳定再选一个计算代价低的k。3.3 fsReliefF_cv_sv.m把特征选择放进交叉验证文件名字里的cv指交叉验证sv更像是和 SVM 或特征子集验证相关的脚本。判断一个过滤式特征选择方法是否可信最容易犯的错误是先在全体数据上筛特征再在筛选后的数据上做交叉验证。这种做法会把标签信息泄露到特征选择过程里导致论文里的准确率虚高。正确流程应该把特征选择嵌入每一折的训练部分。参考这个资源的思路可以写成下面这样rng(42); cvp cvpartition(y, KFold, 5); for i 1:cvp.NumTestSets trIdx cvp.training(i); teIdx cvp.test(i); % 只在训练集上进行 ReliefF [~, rank] fsReliefF(X(trIdx, :), y(trIdx), 10); % 取前 30 个在训练折和测试折上分别提取特征 top30 rank(1:30); Xtr X(trIdx, top30); Xte X(teIdx, top30); % 训练和测试后续模型 mdl fitcecoc(Xtr, y(trIdx)); pred predict(mdl, Xte); acc(i) mean(pred y(teIdx)); end fprintf(ReliefF 5 折 CV 平均准确率 %.2f%%\n, mean(acc) * 100);这样得到的结果才真正反映特征选择对模型的贡献。MRMR 也要用同样的思路处理不要把fsMRMR放在循环外。对熟练用户来说fsReliefF_cv_sv.m可以直接改造成一个模板把中间的分类器替换成fitcensemble或者fitcnb就能复用到新的数据集上。4. MEX 文件、makeosmex 与跨 MATLAB 版本的重编译拿到matlab MRMR和relieff特征选择方法.rar之后大多数人会卡在同一件事上解压后跑脚本报错看不懂。问题几乎都出在 MEX 文件。MRMR 包里的原生代码是用 C 写的MATLAB 不可能跨平台、跨版本通用地执行预编译二进制所以需要重新编译。4.1 为什么 MRMR 包不全是 m 文件互信息的计算需要两层循环累加概率写成 MATLAB 循环效率太低。原包作者提供的是经过 C 实现再编译出的 MEX 文件比如estmutualinfo.mexa64、estmutualinfo.mexw64。这些文件本质上是动态库MATLAB 可以通过接口直接调用速度比纯 m 代码快一个数量级。但 MEX 文件和你当前 MATLAB 版本的 API 是绑定的。老版本 R2018a 的 MEX 文件搬到 R2023b 上极大概率失效。.mexglx对应 Linux 32 位老版本现在根本不常见.mexmac对应旧版 macOS 架构。如果你的机器是 Windows 10 或 11 的 64 位 MATLAB最可靠的做法不是尝试加载.dll或.mexw64而是用包内源码重编。4.2 用 makeosmex 重新编译本机 MEX先确认 MATLAB 已经配置好 C 编译器cd(fs_sup_mrmr); % 查看当前 MATLAB 可用的 C/C 编译器 mex -setup Cmex -setup会列出系统里已被 MATLAB 识别的编译器。Windows 上通常是 MinGW-w64 或 Microsoft Visual StudioLinux 上是 gmacOS 上是 Xcode Command Line Tools。没有可用编译器时要先安装对应工具链这也是很多报错的根源。编译器就绪后手动编译两个核心模块cd(fs_sup_mrmr); % 先生成联合概率表函数 mex estpab.cpp % 再生成互信息函数 mex estmutualinfo.cpp如果包内自带makeosmex.m直接用makeosmex这条脚本的作用是循环把目录下的.cpp和.h关系理清按正确依赖顺序编译出一组当前平台对应的.mexw64或.mexa64文件。编译成功后目录里会出现和当前 MATLAB 版本匹配的新 MEX 文件。4.3 常见运行报错与排查思路下面是我在实际运行中遇到过的几类报错基本覆盖了大多数情况报错信息可能原因处理方式Invalid MEX file ...预编译 MEX 与当前 MATLAB 版本 ABI 不兼容删除旧 MEX重新编译当前版本无法找到指定模块/libstdc缺失Linux 下 C 运行库路径不对安装 g重跑makeosmexUndefined function estmutualinfo编译产物没在当前工作路径检查addpath是否指向fs_sup_mrmrmex: error: no supported compilerMATLAB 没识别编译器mex -setup手动配置编译器这里补充一个判断技巧可以先检查包内是否已经有当前平台可用的 MEX 文件。如果你的 MATLAB 是 Windows 64 位就找.mexw64是 Linux 64 位就找.mexa64。文件存在且没报“无效”说明还不需要重编。如果报错指向某个具体函数就在该函数名上右键“Open Selection”看它是否是 MEX 函数。不要一上来就怀疑算法代码特征选择算法本身的数学逻辑通常没有问题。5. 把 MRMR 和 ReliefF 的排名拧成一张最终特征表单独跑通两个算法只是第一步实际项目中更常见的需求是“我只想保留 30 个特征但 MRMR 和 ReliefF 给的前 30 不一样到底听谁的”一个简单的做法是取交集但交集往往不足 30 个而丢弃的独有特征里也可能藏着重要信息。工程上我更推荐用平均秩融合。5.1 平均秩融合的具体实现平均秩的思路是把每个算法给出的排序结果转成排名序号再对两个排名取平均。比如 MRMR 排第 1 的特征记 1 分排第 5 记 5 分ReliefF 对同一特征也给出一个排名。平均秩越小说明该特征两个算法都认可。D size(X, 2); fea_idx_mrmr fsMRMR(X, y, D); % 按重要性从高到低的特征下标 [~, fea_idx_rf] fsReliefF(X, y, 10); % 同上ReliefF 的排序结果 rank_mrmr zeros(D, 1); rank_rf zeros(D, 1); rank_mrmr(fea_idx_mrmr) 1:D; rank_rf(fea_idx_rf) 1:D; avg_rank (rank_mrmr rank_rf) / 2; [~, final_order] sort(avg_rank); final_feat final_order(1:30);注意这里有一个容易弄反的点fsMRMR返回的fea_idx_mrmr是“第 1 个元素是最好特征”的顺序数组而不是“特征 1 的排名”。所以要把顺序数组变成排名向量需要反向赋值rank_mrmr(fea_idx_mrmr) 1:D。fsReliefF返回的fea_idx_rf如果已经是排序后的下标转换方式相同。5.2 用网格搜索确定保留数量平均秩确定的是特征优先级保留多少还需要验证。我一般会在final_order的前 10、20、30、50、80 这几个档位上分别训练同一个分类器画出特征数量和准确率曲线。现在 MATLAB 的fitcensemble和fitcecoc都支持KFold参数可以写一个循环来扫klist [10 20 30 50 80]; for j 1:length(klist) k klist(j); acc(j) mean(crossval((Xtrain, ytrain, Xtest, ytest) ... test_acc(Xtrain, ytrain, Xtest, ytest), ... X(:, final_order(1:k)), y, KFold, 5)); end这里的test_acc是自定义函数内部放一个fitcsvm或fitcecoc。如果只想自动搜索也可以把特征数量当作一个超参数交给bayesopt或优化工具箱里的贝叶斯优化函数去搜。注意这类方法很容易过拟合特征数上限别超过样本数的三分之一。最后一步是检查融合前后的实际收益。拿融合后的前 30 个特征和单一算法给的前 30 个特征分别训练模型如果融合后的交叉验证准确率不低于两者中的较差者就说明两个算法的互补信息确实起作用了。这样一张平均排名特征表可以直接用于后续的深度学习输入、故障诊断模型或者竞赛特征工程而不需要在论文里解释“为什么只采用单一算法”。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/9/15 22:33:49

对话状态跟踪(DST)在AI应用中的场景自适应优化实践

1. 对话状态跟踪在AI原生应用中的核心价值在智能对话系统的实际开发中,对话状态跟踪(DST)就像交通管制中心的雷达系统,需要实时捕捉和解析用户意图的"飞行轨迹"。去年我们团队为某金融客服系统升级对话模块时,发现传统固定规则的DS…

2026/9/15 22:33:49

Qt散点图实现全解析:从QPainter到QCustomPlot的选型与实践

简介:面向Qt数据可视化学习者的轻量级C源码包,提供散点图完整实现,解决在Qt图形视图框架中自定义二维散点图的展示问题。示例围绕场景、视图与图形项三类核心组件展开,演示数据点如何映射到坐标、如何通过重写绘制方法定制点的颜色…

2026/9/15 23:14:03

基于S7-300 PLC与MCGS组态的热电厂输煤控制系统设计与调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/15 23:14:03

SCALE-Sim脉动阵列仿真深度评测:ARM硬件级建模与版本边界分析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/15 23:14:03

信号继电器供应商怎么选?从参数到验证的实用性价比指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/15 23:14:03

SpringMVC @RequestMapping核心原理与参数绑定实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/15 23:09:02

SpringBoot电商系统毕业设计全攻略:从架构设计到答辩实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/15 4:54:30

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/15 0:01:16

AI英语单词APP开发:自适应学习算法与移动端优化实践

1. 项目概述 作为一名在移动应用开发领域摸爬滚打多年的老手,我最近完成了一个AI英语单词APP的开发项目。这个项目将传统单词记忆方法与现代AI技术相结合,打造了一款能够智能适应不同用户学习习惯的英语学习工具。 市面上大多数单词APP都存在一个通病&a…

2026/9/15 0:01:16

Flutter与OpenHarmony结合开发手语学习APP实战

1. 项目背景与核心价值作为一名同时接触过Flutter和OpenHarmony的开发者,最近我完成了一个基于Flutter for OpenHarmony的手语学习APP实战项目。这个项目最大的特点在于实现了跨平台框架与国产操作系统深度结合的创新实践——用Flutter开发的应用能完美运行在OpenHa…

2026/9/15 0:01:16

六个月成为机器人工程师:从ROS2到SLAM的实战路径

1. 六个月的紧迫感从哪来:先搞清楚你要成为哪种机器人工程师说实话,六个月的期限并不是一个宽松的时间线。市面上任何一本正经的机器人学教材都超过五百页,ROS2的官方文档可以翻到你怀疑人生,再加上ABB、KUKA这些工业机器人厂家动…

2026/9/15 14:22:53

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/15 21:31:11

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/15 11:42:23

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码