ARTICLE DETAIL

资讯详情

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

MATLAB综合评价方法实现:AHP、TOPSIS、熵权法等七种算法代码解析

MATLAB综合评价方法实现:AHP、TOPSIS、熵权法等七种算法代码解析 简介面向数据分析、管理科学与工程、系统工程等领域的师生和研究者这套MATLAB代码包系统实现了七类经典综合评价方法层次分析法AHP、模糊综合评判、可拓学综合评价、数据包络分析DEA、TOPSIS分析法、熵权法以及人工神经网络分析覆盖从确定性指标到不确定信息场景的完整评价链路。压缩包共85个文件其中41个.m源码为主干21个.asv自动保存文件便于版本回溯14个.xls提供示例数据表另有.mat数据文件、.p加密脚本、.doc说明文档和.txt记录整体仅93KB便于快速下载与运行。目前已有451人学习浏览。从内容预览看代码涉及判断矩阵一致性检验、模糊推理、可拓变换、DEA效率测算、TOPSIS排序与熵权计算等关键环节并配有江苏、上海物流预测等案例脚本附带了灰色模型、回归预测、遗传算法等辅助工具读者可以直接运行作为算法模板也可对照源码理解内部实现或修改数据应用于多准则决策、效率评价、风险评估等课题适合课程设计、论文实证和数学建模备赛。1. 综合评价方法为什么在 MATLAB 里落地最顺把层次分析法、模糊综合评判、TOPSIS、熵权法这几种方法放到同一台设备上跑真正的瓶颈不是算法推导而是矩阵方向。评价对象放行、指标放列还是一个对象占一行、一个指标占一列两种约定写出来的 MATLAB 代码几乎无法互相通用。更麻烦的是指标方向成本型指标越大越差效益型指标越小越差二者混在一个矩阵里直接算欧氏距离会把排序结果整个反转。综合评价方法在工程实践里也常被当成“加权重评分脚本”但实际项目一旦遇到十几列指标、几十个评价对象层次分析法的判断矩阵会膨胀到填不动熵权法会把方差大的噪声当成高信息量人工神经网络又需要足够的标签样本。用 AI 代码助手搭骨架很容易但矩阵方向、指标类型这些隐含约定还得人定。这篇文章把这七种方法的最小可运行 MATLAB 实现按套路过一遍直接贴脚本、给参数、说坑。2. 层次分析法与熵权法在 MATLAB 中的权重计算权重是综合评价方法的入口。层次分析法从专家判断出发熵权法从数据分布出发两者算出的权重含义完全不同混用前必须先确定你要表达的是“业务上哪个指标重要”还是“数据里哪个指标区分度大”。大多数项目最终采用组合权重先用 AHP 约束主观方向再用熵权法修正客观波动。2.1 层次分析法 AHP 的 MATLAB 实现判断矩阵与一致性检验层次分析法的核心是把两两比较的判断矩阵变成权重向量MATLAB 中稳定做法是求最大特征值与对应特征向量再归一化。判断矩阵由 19 标度构成例如四个评价指标时构建一个 4×4 矩阵A [1 1/3 1/5 1/7; 3 1 1/3 1/5; 5 3 1 1/3; 7 5 3 1]; [V, D] eig(A); [~, idx] max(real(diag(D))); w abs(real(V(:, idx))); w w / sum(w); lambda_max real(D(idx, idx)); n size(A, 1); CI (lambda_max - n) / (n - 1); RI [0, 0, 0.58, 0.90, 1.12, 1.24, 1.32, 1.41, 1.45, 1.49]; CR CI / RI(n);代码逻辑分四步eig(A)求出全部特征值和特征向量max(real(diag(D)))定位最大特征值下标取对应列特征向量作为初始权重归一化让权重和为 1。一致性比率CR CI / RI(n)是必须看的验收指标CR小于 0.1 才认为判断矩阵的矛盾在可接受范围。RI数组前两个值是 0因为 1 阶、2 阶判断矩阵天然一致不需要检验。实际项目里如果CR超限常见做法是返回让填表人把明显矛盾的两两比较项改掉而不是在代码里强行修正。另一个容易踩的坑是eig对非对称矩阵可能返回复数特征向量所以取了real()再做abs()避免虚部污染权重。2.2 熵权法在 MATLAB 中的客观权重计算熵权法的思路是某个指标取值越分散信息熵越小权重越大。这决定了它不能直接用原始数据必须先做标准化否则量纲会把熵值带偏。写成 MATLAB 函数function w entropy_weight(X) [n, m] size(X); X_min min(X, [], 1); X_max max(X, [], 1); X_std (X - X_min) ./ (X_max - X_min 1e-12); X_std(X_std 0) 1e-12; P X_std ./ sum(X_std, 1); e -1 / log(n) * sum(P .* log(P), 1); d 1 - e; w d / sum(d); endmin(X, [], 1)的第二个参数是空矩阵第三个参数1表示按列取最小值这是 MATLAB 新手最容易写错的地方。X_std加1e-12是为了避免零值导致log(0)报 NaN把零替换成极小正数熵值计算结果误差在可以忽略的范围。熵权法的特点是“数据敏感”同一个指标只要样本里出现一个极端值极差标准化后其他样本的数值会被压到接近零权重也相应变化。所以使用熵权法前先画箱线图看离群点必要时做分位数截断。2.3 主观客观组合权重的合成方式AHP 和熵权法单独用都有缺陷专家打分在指标多时不可靠熵权法对业务含义无感知。常见解决方式是乘法合成归一化w_sub [0.40; 0.30; 0.20; 0.10]; % AHP 结果 w_obj entropy_weight(X); % 熵权法结果 w_combo w_sub .* w_obj; w_combo w_combo / sum(w_combo);w_sub .* w_obj是逐元素乘法不是矩阵乘法方向必须保持一致。合成后的权重如果某个分量接近零说明业务上重要的指标在数据里几乎不变这时需要回到业务侧确认指标是否选错而不是直接把权重清零。另一种做法是线性加权alpha * w_sub (1-alpha) * w_objalpha 取 0.6 左右适合想保留更多主观倾向的场景。3. TOPSIS 与模糊综合评判在 MATLAB 中的排序实现权重算完后进入评价阶段。TOPSIS 适合给出连续排名模糊综合评判适合输出等级结论。两者的共同点是都需要一个已经方向统一的指标矩阵区别在于 TOPSIS 直接使用数据距离模糊综合评判先构造隶属度再合成。3.1 TOPSIS 分析法的 MATLAB 完整代码与参数设置TOPSIS 的原理是找正理想解和负理想解再计算各评价对象与两者的距离。这个方法的优势是不需要构造隶属函数缺点是标准化方式直接影响排名。先看方向处理指标类型方向变换方式效益型越大越好保留原始值成本型越小越好max(X) - X中间型越接近某值越好1 - abs(X - best) / max(abs(X - best))实际项目里成本型指标常见的错误是直接取倒数。倒数变换会改变数据分布max(X) - X保持线性关系不会放大接近零的数值。TOPSIS 的 MATLAB 实现如下function score topsis_score(X, W, types) [n, m] size(X); X_dir zeros(n, m); for j 1:m switch lower(types{j}) case max X_dir(:, j) X(:, j); case min X_dir(:, j) max(X(:, j)) - X(:, j); case mid b (max(X(:, j)) min(X(:, j))) / 2; X_dir(:, j) 1 - abs(X(:, j) - b) / max(abs(X(:, j) - b)); end end X_norm X_dir ./ sqrt(sum(X_dir.^2, 1)); V X_norm .* W; V_plus max(V, [], 1); V_minus min(V, [], 1); d_plus sqrt(sum((V - V_plus).^2, 2)); d_minus sqrt(sum((V - V_minus).^2, 2)); score d_minus ./ (d_plus d_minus); endW是列向量X_norm .* W在 MATLAB R2016b 之后会隐式扩展老版本则需要repmat(W, n, 1)。types元胞数组的长度必须与m一致这也是最常见的运行时报错来源指标 17 个类型只填了 16 个。d_plus和d_minus用sum(..., 2)按行求和得到每个评价对象到理想解的二维距离。TOPSIS 的score范围在 0 到 1 之间越接近 1 排名越靠前但它不是概率不能直接解读为“优于此评价对象 80%”。3.2 模糊综合评判的 MATLAB 实现隶属度矩阵与合成算子模糊综合评判首先要有一个从因素集到评语集的隶属度矩阵R。比如评语集是“优、良、中、差”四个等级三个评价指标R(i, j)表示第 i 个指标隶属于第 j 个等级的程度。合成时权重向量来自 AHP 或熵权法w [0.4, 0.3, 0.3]; R [0.6, 0.3, 0.1, 0; 0.2, 0.5, 0.2, 0.1; 0.1, 0.4, 0.3, 0.2]; B w * R; [max_degree, grade] max(B);w * R是加权平均算子保留所有隶属度信息适合指标之间相互补偿的场景。如果要求严格比如安全评价中某一项不合格直接降级改用“取小取大”算子B_strict max(min(w, R), [], 1);min(w, R)先把每个权重和对应行做逐元素比较取较小值再对列取最大值。这个算子的缺点是只保留极大值丢失中间信息结果偏保守。两类算子输出的B总和不为 1max拿到的等级只表示相对隶属度最高不表示概率。3.3 两种评价方法的选型对照对比点TOPSIS模糊综合评判输出形式连续分数与排名离散等级对数据量要求评价对象越多越稳定依赖隶属度矩阵构造权重来源任意权重向量任意权重向量信息保留程度完整使用数据隶属函数会截断信息适用场景供应商排序、方案比选安全等级、质量评级实践中两者的结果经常不一致原因在于 TOPSIS 对极端值敏感模糊综合评判对隶属函数敏感。遇到结果冲突先检查是否有离群指标再看评语集划分是否合理而不是直接怀疑代码。4. 数据包络分析、可拓学与人工神经网络评价的 MATLAB 扩展TOPSIS 和模糊综合评判都要求知道指标权重但有些场景我们不想主观定权重比如评价一组银行的经营效率这时数据包络分析DEA更合适。可拓学则是处理“矛盾问题”的评价框架人工神经网络适合已有历史评分数据、想学习打分规律的场景。4.1 数据包络分析法 DEA 的 MATLAB 实现linprog 求解 CCR 模型DEA 把每个评价对象当成决策单元用投入产出数据计算技术效率不需要人为设定权重。CCR 模型的对偶形式是一个线性规划用linprog求解。假设投入矩阵X的每一列是一个决策单元每一行是一种投入指标产出矩阵Y同理X [20, 25, 18; 6, 8, 5]; Y [30, 32, 22; 25, 20, 18]; nDMU size(X, 2); theta zeros(nDMU, 1); lb [zeros(nDMU, 1); 0]; % lambda 0, theta 0 f [zeros(nDMU, 1); 1]; % 目标最小化 theta for k 1:nDMU A_ineq1 [X, -X(:, k)]; b_ineq1 zeros(size(X, 1), 1); A_ineq2 [-Y, zeros(size(Y, 1), 1)]; b_ineq2 -Y(:, k); A [A_ineq1; A_ineq2]; b [b_ineq1; b_ineq2]; [z, ~] linprog(f, A, b, [], [], lb, []); theta(k) z(end); endlinprog(f, A, b)求解的是f*x在A*x b约束下的最小值。第一个约束组X * lambda theta * X(:, k)表示被评价单元的投入组合不能超过当前决策单元的投入第二个约束组-Y * lambda -Y(:, k)即Y * lambda Y(:, k)要求产出组合不低于它。theta(k)等于 1 表示 DEA 有效小于 1 表示存在投入冗余。DEA 对数据方向极其敏感投入必须越小越好产出必须越大越好代码里没有任何位置体现权重偏好。另一个坑是决策单元数量太少时几乎全部有效一般要求决策单元数不低于投入产出指标数之和的两倍。4.2 可拓学评价方法在 MATLAB 中的物元模型实现可拓学综合评价的核心是物元与关联函数。它先把每个等级的量值范围定义为经典域把所有可能取值定义为节域再计算实测数据对各经典域的关联度关联度最大的等级就是评价结果。先定义关联函数需要的“距”rho (v, interval) abs(v - (interval(1) interval(2)) / 2) ... - (interval(2) - interval(1)) / 2; v 5.2; classic [2, 6]; % 等级“中”的经典域 section [0, 10]; % 节域 K rho(v, classic) / (rho(v, section) - rho(v, classic));当v落在经典域内时rho(v, classic)为负值K 为正落在经典域外则 K 为负。多等级评价时需要循环计算每个等级的关联度levels {[0, 4], [4, 7], [7, 10]}; K_all zeros(1, 3); for i 1:3 K_all(i) rho(v, levels{i}) / (rho(v, [0, 10]) - rho(v, levels{i})); end [~, grade] max(K_all);可拓学评价的难点不在代码而在经典域和节域的划分必须和业务口径一致不同专家划分的两个区间会让同一批数据的评价等级完全不同。实现时不要做任何归一化关联度计算对原始量纲是自适应的但前提是经典域和实测值使用同一单位。4.3 人工神经网络分析法在 MATLAB 中的评分模型神经网络评价法和其他方法的根本差异它需要标签。标准做法是把已有历史样本当作训练集用指标做输入、专家给出的综合评分做输出训练一个回归网络再用它预测新样本。MATLAB 中feedforwardnet是最直接的前馈网络rng(42); X rand(120, 8); % 120 个样本8 个指标 y sum(X(:, 1:4), 2) randn(120, 1) * 0.1; % 综合评分 net feedforwardnet([8, 4]); net train(net, X, y); y_pred net(X);feedforwardnet([8, 4])表示隐藏层有两个神经元数分别是 8 和 4。train函数要求输入矩阵行是特征维度所以这里转置成8×120。需要说明的是feedforwardnet在 R2023b 仍然可用但新代码推荐用trainNetwork搭配fullyConnectedLayer只是对综合评价这种小样本场景来说前馈网络已经足够。神经网络评价的典型误区是样本量只有几十条也强行训练结果在训练集上拟合得很好新样本上一塌糊涂。综合评价项目里样本少于 100 时优先考虑用神经网络做交叉验证而不是直接上线。4.4 综合评价方法选型速查方法最优场景主要输入主要坑点AHP指标少、专家明确判断矩阵CR 不通过时不能硬算熵权法数据区分度优先标准化指标矩阵离群点放大权重TOPSIS连续排名比选指标矩阵 权重指标方向漏写模糊综合评判输出等级结论权重 隶属度矩阵算子选择影响结果DEA多投入产出效率投入矩阵 产出矩阵DMU 数量不足时失准可拓学等级界定明确经典域 节域 实测值区间划分主观性ANN有历史标签样本指标矩阵 评分样本少时过拟合5. 在 MATLAB 里统一封装评价方法并验证排名前面的函数全部单独使用时每个方法都要重复做方向规整和数据导入项目一多就乱。我的做法是固定一个 mouth 规则评价对象放行指标放列所有函数统一接收这个方向的矩阵里层再做方向变换。CSV 导入用readmatrixT readmatrix(evaluate_input.csv); % 行对象列指标 types {max, min, max, max}; w entropy_weight(T); score topsis_score(T, w, types); [~, rank] sort(score, descend);写一个小封装函数evaluate_all.m内部依次调用topsis_score、模糊综合评判和 DEA输出一个汇总表方便对比排名走势。这样做的价值在于同一份数据经过三个不同原理的方法计算后如果 TOPSIS 排名和 DEA 排名差异很大问题大概率出在指标选择或数据预处理上而不是某个函数写错了。可视化用barh看离散程度也很直观。数据导入阶段有个隐蔽问题CSV 里偶尔混入非数值单元格readmatrix会报错或读成 NaN。导入后先执行any(isnan(T), all)检查有 NaN 就把对应行单独挑出来处理。另外MATLAB 的feedforwardnet和linprog分别依赖 Deep Learning Toolbox 和 Optimization ToolboxR2023b 默认安装器通常不会装齐全运行到对应函数时才发现 undefined function 是正常现象检查工具箱列表比重新装整个 MATLAB 更高效。还有一个加分技巧把权重向量w和评价分数score同时写出到results.mat下次复核时不需要重新跑一遍全部算法。.mat文件用-v7.3选项保存可以避免变量维度变大后文件尺寸异常膨胀。新项目直接复制evaluate_all.m先让业务方把每个指标方向填进types跑完再看排名而不是先纠结用什么方法。本文还有配套的精品资源点击获取
返回列表