☰
CRITIC赋权法MATLAB实现:原理、代码与工程实践
2026/10/26 11:29:35 网站建设 项目流程

简介:这份资源面向多属性决策分析的学习者与科研人员,提供在Matlab环境下实现CRITIC赋权法的完整代码,用于客观确定各属性权重并对方案综合打分,适合具备Matlab基础、需要处理评价与选优问题的中初级用户。压缩包共1个文件,为单个m脚本,体积约586B,代码结构涵盖数据预处理、属性归一化、一致性、相关性与强度指标计算、权重求解及对象打分等环节,并配有子函数划分,便于按模块阅读与替换实际数据。目前已有1658人学习下载,说明其在同类方法实现中具有一定参考价值。读者可据此快速搭建可运行的赋权流程,理解CRITIC准则的计算逻辑,并在此基础上扩展可视化或与其他决策方法组合使用。

1. 从一张“权重表”说起:CRITIC 赋权法在 MATLAB 里到底解决什么问题

做综合评价的人大多踩过同一个坑:手上有七八个指标,领导要一张权重表,拍脑袋定权重显得不专业,用熵权法又发现某些指标明明高度相关却被重复计权。CRITIC 赋权法就是冲着这个痛点来的——它同时看两件事,一是指标自身的对比强度(标准差),二是指标之间的冲突性(相关系数),把“波动大且和别人不重复”的指标权重抬上去。MATLAB 实现这套逻辑特别顺手,矩阵运算一行顶别人十行,corrcoef、std直接调用,几十行代码就能跑出一套可复现的权重结果。这份资源适合正在做评价类课题、论文复现或工程选型打分的人,拿过去改改指标矩阵就能用。

2. 项目结构与技术选型:为什么用 MATLAB 而不是 Python

2.1 目录与文件组织

这类赋权法实现通常不会做成庞大工程,核心就是一个主脚本加若干函数文件,常见组织方式如下:

critic_weight/ ├── main_critic.m % 主入口:读数据、调函数、输出权重 ├── critic_weight.m % CRITIC 核心计算函数 ├── normalize_data.m % 指标正向化与归一化 ├── data_sample.xlsx % 示例指标矩阵(行=样本,列=指标) └── result_weight.mat % 运行后保存的权重结果

主脚本负责流程编排,critic_weight.m只做纯计算,normalize_data.m单独处理量纲问题。这种拆法的好处是:换一批数据只改main_critic.m里的读取路径,核心算法一行不用动;想对比熵权法,再挂一个entropy_weight.m即可。我一般会把正向化逻辑也塞进normalize_data.m,因为效益型、成本型、区间型指标的预处理方式不同,混在主脚本里很快就会乱。

2.2 技术选型:MATLAB 的优势与边界

选 MATLAB 做 CRITIC 不是情怀,是实打实的效率考量。CRITIC 的核心是相关系数矩阵和标准差向量,MATLAB 的corrcoef返回对称矩阵,std(X,0,1)按列求样本标准差,一行到位;换成 Python 得注意numpy.corrcoef的默认行为、pandas的std(ddof=1)差异,新手容易在自由度上翻车。另外 MATLAB 的表格数据类型读 Excel 很稳,readtable自动识别表头,省掉一堆列名映射代码。

边界也要说清楚:MATLAB 不适合做大规模部署或 Web 服务,如果权重结果要嵌进线上系统,通常是把 MATLAB 算好的权重导出成 JSON 或 CSV,再由后端读取。所以这份资源的定位是“离线计算工具”,不是“在线服务”。常见做法是跑完main_critic.m后用writematrix把权重落盘,后续系统只消费结果。

2.3 数据输入约定

指标矩阵的约定必须提前定死,否则后面全是血泪经验。约定如下:

项目约定说明
矩阵形状行=样本,列=指标与readtable默认方向一致
缺失值不允许 NaN需在预处理阶段插补或剔除
指标方向统一转为效益型成本型取倒数或负向化
量纲归一化到 [0,1]避免标准差被大量纲指标主导

这个约定看起来琐碎,但它决定了后面所有公式能不能直接套。尤其是“统一转为效益型”这一步,很多人跳过,结果成本型指标(比如能耗、成本)权重算出来是正的,方向却反了,结论直接翻车。

3. 核心算法拆解:CRITIC 三步计算与 MATLAB 实现

3.1 第一步:指标正向化与归一化

CRITIC 对量纲敏感,必须先归一化。效益型指标用极差法,成本型指标先取负再极差,区间型指标单独处理。核心代码如下:

function Xn = normalize_data(X, types) % X: 原始指标矩阵,行=样本,列=指标 % types: 指标类型向量,1=效益型,-1=成本型,0=区间型 [n, m] = size(X); Xn = zeros(n, m); for j = 1:m col = X(:, j); if types(j) == 1 % 效益型:越大越好 Xn(:, j) = (col - min(col)) / (max(col) - min(col) + eps); elseif types(j) == -1 % 成本型:越小越好,先取负再极差 neg = -col; Xn(:, j) = (neg - min(neg)) / (max(neg) - min(neg) + eps); else % 区间型:落在 [a,b] 内最优,此处简化为距区间中心越近越好 a = min(col); b = max(col); center = (a + b) / 2; dist = abs(col - center); Xn(:, j) = 1 - dist / (max(dist) + eps); end end end

逻辑说明:eps是防止分母为零的保险丝,极差为 0 说明该指标所有样本取值相同,这种指标本身没有区分度,归一化后整列为 0,后续标准差也是 0,权重自然为 0,符合直觉。参数types必须和列顺序严格对应,我见过有人把成本型标成效益型,跑出来的权重表看着正常,结论却完全相反——这种错误不会报错,只会静默出错,最坑。

3.2 第二步:计算对比强度与冲突性

CRITIC 的两个核心量:对比强度用标准差sigma_j表示,冲突性用sum(1 - r_ij)表示,其中r_ij是指标 i 和 j 的相关系数。代码如下:

function [C, sigma, R] = critic_core(Xn) % Xn: 归一化后的指标矩阵 [n, m] = size(Xn); % 对比强度:按列求样本标准差(自由度 n-1) sigma = std(Xn, 0, 1); % 相关系数矩阵 R = corrcoef(Xn); % 冲突性:每个指标与其他指标相关系数补数之和 conflict = zeros(1, m); for j = 1:m conflict(j) = sum(1 - R(j, :)); end % 信息量 C_j = sigma_j * conflict_j C = sigma .* conflict; end

逻辑说明:std(Xn, 0, 1)第二个参数 0 表示按样本标准差(除以 n-1),第三个参数 1 表示按列计算,这两个参数写错是高频翻车点。corrcoef返回 m×m 对称矩阵,对角线为 1,所以1 - R(j,:)中 j 自身那项为 0,不影响求和。conflict越大说明该指标和其他指标越不相关,信息越独立,权重应该越高。参数层面,如果某两个指标完全线性相关,R对应位置为 1,冲突性贡献为 0,这正是 CRITIC 想去重的场景。

3.3 第三步:归一化权重并输出

信息量C算出来后,权重就是C归一化:

function w = critic_weight(X, types) % 完整流程封装:输入原始矩阵,输出权重向量 Xn = normalize_data(X, types); [C, sigma, R] = critic_core(Xn); w = C / sum(C); % 打印中间结果,方便排查 fprintf('对比强度 sigma: %s\n', mat2str(sigma, 4)); fprintf('信息量 C: %s\n', mat2str(C, 4)); fprintf('权重 w: %s\n', mat2str(w, 4)); end

逻辑说明:sum(C)是所有指标信息量之和,归一化后权重和为 1。打印中间结果是排查利器——如果某个指标权重异常高,先看它的sigma是不是被量纲放大了,再看conflict是不是因为和其他指标都不相关而被抬高。参数types从主脚本传入,示例数据里如果全是效益型指标,直接传ones(1, m)即可。

3.4 主脚本串联

% main_critic.m data = readmatrix('data_sample.xlsx'); % 读入指标矩阵 types = [1, 1, -1, 1, -1]; % 按列标注指标类型 w = critic_weight(data, types); % 计算权重 writematrix(w, 'result_weight.csv'); % 落盘供后续系统消费

readmatrix比xlsread更现代,返回纯数值矩阵,省去单元格解析。writematrix输出 CSV,后端语言都能直接读。这套流程跑通后,换数据只需改文件路径和types向量,算法层零改动。

4. 跑起来与避坑:从示例数据到自己的指标矩阵

4.1 环境准备与首次运行

MATLAB R2019b 及以上版本即可,readmatrix和writematrix在这个版本之后才稳定。首次运行步骤:

  1. 把整个文件夹加入 MATLAB 路径(右键文件夹 → 添加到路径 → 所选文件夹)。
  2. 打开main_critic.m,确认data_sample.xlsx与脚本同目录。
  3. 按 F5 运行,命令行应输出 sigma、C、w 三行中间结果。
  4. 检查当前目录下是否生成result_weight.csv。

如果报“未定义函数或变量”,九成是路径没加对;如果报“索引超出矩阵维度”,检查types长度是否等于指标列数。这两类错误占了新手问题的八成。

4.2 换成自己的数据

替换数据时按这个顺序操作,能少走弯路:先把 Excel 整理成纯数值、无合并单元格、无表头行(或表头单独放),再用readmatrix读入;然后数一下列数,写types向量;最后跑一遍,看权重和是否接近 1(浮点误差允许 1e-6 偏差)。如果权重和明显不等于 1,说明中间有 NaN 混入,sum(C)变成了 NaN,归一化自然失效。

4.3 常见问题排查

现象一:权重全是 NaN。原因通常是原始矩阵含 NaN 或某列极差为 0 且未加eps。解决:运行前加assert(~any(isnan(data(:))), '存在缺失值'),把问题挡在入口。

现象二:某个指标权重接近 1,其他接近 0。原因多半是该指标量纲远大于其他指标,归一化没生效或types标错导致该列没走极差。解决:打印Xn每列的min和max,确认都在 [0,1] 区间。

现象三:corrcoef报警告“矩阵接近奇异”。原因是指标间存在完全线性相关,或样本数少于指标数。解决:样本数至少是指标数的 3 倍,否则相关系数估计不可靠;完全相关的指标考虑合并或剔除。

现象四:结果和论文里的权重对不上。原因通常是标准差自由度选择不同(除以 n 还是 n-1),或归一化方法不同(极差法 vs 向量归一法)。解决:对照论文公式逐项核对,std的第二个参数就是自由度开关。

提示:每次改完types或数据源,先跑一遍并肉眼检查中间输出,别直接看最终权重表。中间量对了,结果才可信。

5. 二次开发:把 CRITIC 嵌进评价流水线的几个改造点

5.1 与熵权法组合做组合赋权

单一赋权法都有偏差,CRITIC 偏重冲突性,熵权法偏重离散度,工程上常见做法是两者加权组合。改造思路:把critic_weight.m和entropy_weight.m并列调用,得到w1和w2,再用w = alpha*w1 + (1-alpha)*w2合成,alpha取 0.5 是默认起点,也可以用博弈论组合赋权求最优系数。验证方法:对比组合权重与单一权重的排序一致性,用 Spearman 相关系数衡量,corr(w1, w_combined, 'type', 'Spearman')一行就能看。

5.2 批量跑多组数据

课题里经常要对比多个年份或多个方案,手改路径太低效。把主脚本改成函数,外层套循环:

files = dir('data_*.xlsx'); W = zeros(numel(files), m); for k = 1:numel(files) data = readmatrix(files(k).name); W(k, :) = critic_weight(data, types); end writematrix(W, 'weight_matrix.csv');

这样一次跑完所有文件,权重矩阵按行对应文件,后续做趋势分析直接读。注意m要在循环外确定,且所有文件列数必须一致,否则W预分配会出错。

5.3 结果可视化与报告输出

权重表给领导看,光有数字不够。加一段横向条形图:

barh(w); set(gca, 'YTickLabel', indicator_names, 'YTick', 1:numel(w)); xlabel('权重'); title('CRITIC 赋权结果');

indicator_names从 Excel 表头读或手写元胞数组。图出来后用exportgraphics(gcf, 'weight_bar.png', 'Resolution', 300)导出高清图,直接贴进报告。这一步花不了十分钟,但能让结果的可信度上一个台阶。

5.4 一个我踩过的坑

早些年做某评价项目,数据里有个成本型指标忘了标-1,跑出来的权重表看着挺正常,排序也像模像样,结果汇报时被问“为什么能耗越高得分越高”,当场愣住。回头查才发现是types向量错位。从那以后我每次跑赋权之前,都强制先打印一张“指标名—类型—归一化后均值”的对照表,肉眼过一遍再往下算。这个习惯救过我至少三次。希望这份拆解能帮你少走一遍我走过的弯路,把 CRITIC 这套逻辑真正用进自己的评价流水线里。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询