ARTICLE DETAIL

资讯详情

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

AHP层次分析法实战:判断矩阵、权重计算与一致性检验

AHP层次分析法实战:判断矩阵、权重计算与一致性检验 1. 层次分析法到底在解决什么问题1.1 从拍脑袋排序到有据可依的那一步做决策这件事麻烦的从来不是没有选项而是选项之间没法直接比。你要给三个供应商排个座次手里攥着价格、交期、售后、质量四张表价格最低的那家交期最长质量最好的那家报价最高售后最靠谱的那家规模最小。这时候你脑子里会自动浮现一句话综合来看……——这个综合来看就是层次分析法AHPAnalytic Hierarchy Process存在的全部理由。我在项目里最常听到的抱怨是权重怎么来的如果是领导拍的那叫行政决定如果是平均分的那叫偷懒如果是AHP算出来的你至少能拿出一张判断矩阵指着上面说清楚为什么价格占0.46而不是0.2。这就是AHP的核心价值把模糊的相对重要性转换成一组可复现、可追溯、可被别人质疑和检验的数字。它不预测未来也不算最优解它做的事只有一件把人对多个因素的主观比较量化成权重。所以别指望AHP告诉你选A一定能赚钱它只能告诉你在你们团队当前的偏好结构下A的加权得分最高。这句话听起来平淡但真正做到很多决策流程就顺了。适合谁看写过AHP作业但现在只会套公式的学生、被要求做评价体系却不知道怎么定权重的工程技术人员、做选址/选型/绩效打分/方案评审的产品和运营以及所有被权重哪来的这句话问住过的人。后面这些内容是我自己反复用了七八年、也踩过不少坑之后整理出来的和教材上讲的重点不太一样尤其是第三、第五部分建议慢慢看。1.2 三层骨架目标层、准则层、方案层AHP最直观的形象是一棵树标准的教科书说法是三层目标层Goal最上面那一个节点全篇只允许有一个比如选择最佳供应商、评估三套技术方案、确定城市配送中心选址。准则层Criteria中间那层通常3到9个是评价的维度比如价格、质量、交期、服务。准则层可以再往下分层子准则形成四层甚至五层结构。方案层Alternatives最下面那层就是你要排序的候选对象。很多人做AHP翻车问题不在数学而在这一层骨架搭歪了。我见过最离谱的一个案例有人把价格便宜和成本可控同时放在准则层这两个指标在语义上高度重叠结果是判断矩阵怎么调都过不了一致性检验因为你在反复比较同一件事。还有一个常见病是把方案A和是否选择方案A混进准则层逻辑上直接打架。我的经验是搭骨架时问自己三个问题准则之间是不是互斥且不完全重叠准则能不能用一句人话说清楚它的高低含义准则层数量是不是超过了9个超过就该考虑分层这三个问题都过了后面的数学几乎是水到渠成的事。如果准则层超过9个还硬塞在一层人的判断能力会急剧下降一致性检验的通过率会低得让你怀疑人生。1.3 适用边界哪些场景别硬套AHPAHP不是万能钥匙我强烈建议在下面几种情况下换个工具第一种准则之间存在强因果链。比如技术先进性会直接影响维护成本这两个因素不是平行的用AHP当成平级准则比较就失真了。这种情况应该考虑DEMATEL或网络层次分析法ANP。第二种有大量客观定量数据且量纲统一。如果你手上就是一张纯净的数值表用熵权法、CRITIC法或者TOPSIS客观赋权可能更省事AHP的逐对比较反而是在把已有信息重新主观化一遍。第三种决策者根本说不清偏好。AHP依赖专家判断如果被问的人对准则重要性完全没有概念那填出来的矩阵就是噪音算出来的权重看着漂亮实质是随机数。这时候要么换更懂的人要么先做一轮背景调研。第四种候选方案超过十几个。方案层两两比较的次数是 n(n-1)/210个方案就是45次比较20个方案是190次填表的人会崩溃而且后面必然大面积不一致。方案多的时候通常的做法是先用AHP定准则权重再用TOPSIS、灰色关联或简单加权去给方案打分排序。提示AHP最值钱的产出不是那个最终排名而是判断矩阵本身。它把我们团队认为什么重要这件事白纸黑字记下来了下一次复盘时你可以拿出来对照看看当初的偏好是不是合理。这一点比权重数字有用得多。2. 判断矩阵才是AHP的真正命门2.1 1-9标度的真实语义所有人学AHP第一课都是1-9标度法但真正把它用对的人不多。先看标准定义标度 a(ij)含义1因素i与因素j相比同等重要3因素i比因素j稍微重要5因素i比因素j明显重要7因素i比因素j强烈重要9因素i比因素j极端重要2, 4, 6, 8上述相邻判断的中间值倒数若i对j的标度为a(ij)则j对i的标度为1/a(ij)关键在于这句话标度描述的是重要性的比值不是排名的序号。标度等于3意思是i的重要性大约是j的3倍而不是i排第3位。为什么上限是9心理学上的解释是人对同时比较的对象有效分辨区间大致在7±2个等级超过这个范围判断会明显失准。这也是为什么准则层别超过9个。实操中最容易出问题的是中间值2、4、6、8。我的建议是除非你真的能感知出两个整数之间的差异否则不要用偶数标度。新手为了显得精确动不动就填4、6结果整张矩阵的一致性一塌糊涂。真正稳定的做法是用1、3、5、7、9这几个强锚点偶数留作迫不得已时的微调。还有一点必须提醒标度9是个非常重的承诺。我见过有人对价格和售后填了9意思是价格的重要性是售后的9倍。后来让他复核他自己都笑了——那只是因为他上一个项目的价格超支被骂过。标度一旦到了7以上我都会让填表的人再确认一次因为这种极端判断对最终权重的影响非常大。2.2 逐对比较应该怎么问才有意义给专家发一张空矩阵让他填是最糟糕的做法。经验是先做排序再做标度。具体流程是这样先让决策者把准则按重要性从高到低排个队这个动作比两两比较容易得多。排完之后从最高和次高之间开始填标度逐段往下推。举例来说如果排序是 价格 质量 交期 服务那就先问价格相对质量是稍微重要3还是明显重要5再问质量相对交期依次类推。这样做的另一个好处是你实际上只需要填上三角其余由倒数自动生成判断次数从 n² 降到 n(n-1)/2。四个准则只需要6次比较五个准则10次工作量可控。提问的语言也要设计。不要问这两个哪个重要而是问如果我们要牺牲一个你更愿意牺牲哪个愿意牺牲多少。前一个问题容易被都很重要糊弄过去后一个问题逼出真实的取舍。我在给企业做咨询时固定用一句问法假设现在只能保一个指标达到最优另一个必须退到及格线你怎么选这句话把场景从抽象的重要性拉回到具体的资源分配上答出来的数字比空想稳定得多。注意同一个人在不同时间填同一张矩阵结果往往不一致这是正常的。别追求永远一致的专家追求的是判断逻辑能够被你追问清楚的专家。追问的时候记录下来这份记录比矩阵更值钱。2.3 判断矩阵的三条硬约束一个合法的判断矩阵必须同时满足这三条第一条正互反性。所有元素大于0且 a(ij) × a(ji) 1主对角线恒为1。这条是硬性要求代码里必须校验我见过不少论文里的矩阵连这条都不满足那就是纯编的。第二条传递性一致性。如果认为A比B重要3倍B比C重要2倍那么A比C就应该接近6倍。完全一致在现实中几乎不可能达到因为人的判断有噪声所以AHP不要求完全一致而是用一致性比率CR来度量偏差有多大。第三条维度控制。同一层元素数量通常控制在9个以内。这一条经常被当成建议而不是约束但它的后果非常实在超过9个一致性的通过率会断崖式下跌你会花大量时间在调矩阵上而调出来的矩阵已经不是你真实想法了。我在代码里会做完整的合法性校验正数检查、互反检查、对角检查、维度检查。看起来是小事但能帮你省掉后面一大堆莫名其妙的报错。2.4 指标方向的预处理很多人会漏判断矩阵本身不区分指标方向它只比较重要性。但你在构造准则层时如果混进了逆向指标比如故障率成本排放量就必须在方案打分阶段处理方向问题否则会得出故障率越高越好这种荒谬结论。标准做法是在综合评分阶段统一方向。常用手段有两种。一种是对逆向指标取倒数或做极大值归一化处理让它转成正向另一种是干脆保持原值在加权求和时用负号。我倾向第一种因为它让整个评价体系的方向一致后面解释结果时不容易绕晕。顺便提一个延伸问题如果准则之间有正向和逆向而你又想让权重都是正的那就必须在打分环节而不是权重环节处理方向。这一点想清楚了很多权重算出来是负的怎么办的困惑就自然消失了。3. 权重计算与一致性检验的手算全过程3.1 算术平均法和积法手算全过程这是最适合手算、也是考试最常考的方法。步骤就三步列归一化、按行求和、再除以n。我用一个四准则的判断矩阵来完整走一遍。假设四个准则是价格C1、质量C2、交期C3、服务C4。C1 C2 C3 C4 C1 1 2 3 4 C2 1/2 1 2 3 C3 1/3 1/2 1 2 C4 1/4 1/3 1/2 1第一步求每一列的和第1列 10.50.33330.25 2.0833第2列 210.50.3333 3.8333第3列 3210.5 6.5第4列 4321 10。第二步每个元素除以所在列的和得到归一化矩阵C1 C2 C3 C4 C1 0.4800 0.5217 0.4615 0.4000 C2 0.2400 0.2609 0.3077 0.3000 C3 0.1600 0.1304 0.1538 0.2000 C4 0.1200 0.0870 0.0769 0.1000第三步按行求平均w1 (0.48000.52170.46150.4000)/4 0.4658w2 (0.24000.26090.30770.3000)/4 0.2772w3 (0.16000.13040.15380.2000)/4 0.1611w4 (0.12000.08700.07690.1000)/4 0.0960合计 0.46580.27720.16110.0960 1.0001舍入误差在可接受范围内。手算时有个小技巧先看归一化矩阵的列向量是否彼此接近。如果某两列的数值差别很大说明这张矩阵的一致性可能不太好后面CR大概率会超标。这一步相当于提前预警比算完再返工省时间。3.2 几何平均法方根法方根法的思路是先把每行元素连乘再开n次方得到行几何平均然后归一化。它对极端值的敏感度低于算术平均法所以很多软件默认用这个方法。还是上面那张矩阵第1行连乘1×2×3×4 24开4次方 24^0.25 ≈ 2.2134第2行连乘0.5×1×2×3 3开4次方 ≈ 1.3161第3行连乘0.3333×0.5×1×2 0.3333开4次方 ≈ 0.7598第4行连乘0.25×0.3333×0.5×1 0.04167开4次方 ≈ 0.4518求和2.21341.31610.75980.4518 4.7411归一化w1 0.4669w2 0.2776w3 0.1603w4 0.0953。对比算术平均法的结果0.4658、0.2772、0.1611、0.0960差异在0.002以内说明这张矩阵比较干净。如果两种方法算出来的权重差得很远比如超过0.02那基本可以判定矩阵的一致性有问题这是个非常好用的交叉验证手段教材上很少提。3.3 特征值法与最大特征值严格来说AHP的理论基础是特征值问题对于完全一致的判断矩阵存在关系 A·w n·w此时最大特征值 λmax nw 就是对应的特征向量。当矩阵不完全一致时λmax 会略大于 n主特征向量作为权重向量仍然是最优估计。先把上一步的权重代进去算 A·w。用 w (0.4658, 0.2772, 0.1611, 0.0960)第1行1×0.4658 2×0.2772 3×0.1611 4×0.0960 0.46580.55440.48330.3840 1.8875第2行0.5×0.4658 1×0.2772 2×0.1611 3×0.0960 0.23290.27720.32220.2880 1.1203第3行0.3333×0.4658 0.5×0.2772 1×0.1611 2×0.0960 0.15530.13860.16110.1920 0.6470第4行0.25×0.4658 0.3333×0.2772 0.5×0.1611 1×0.0960 0.11650.09240.08060.0960 0.3855然后逐分量除以对应的 w1.8875/0.4658 4.05221.1203/0.2772 4.04150.6470/0.1611 4.01620.3855/0.0960 4.0146取平均λmax (4.05224.04154.01624.0146)/4 4.0311。四阶矩阵的理论值应该是4实际算出4.0311超出的0.0311就是不一致带来的偏差。偏差越大λmax 超出 n 越多。手算时有个细节要注意四种方法算术平均、几何平均、特征值法、最小二乘法算出的权重通常有微小差异写报告时要注明用了哪种。我见过审稿人专门追问这件事的因为不同方法在一致性较差时差异会放大。3.4 CI、RI、CR 到底在检验什么接下来是一致性检验三步走第一步算一致性指标 CICI (λmax - n)/(n - 1)。本例中 CI (4.0311-4)/(4-1) 0.0104。第二步查随机一致性指标 RI。RI 是通过大量随机正互反矩阵统计出来的平均CI是个经验常数n123456789101112131415RI000.520.891.121.261.361.411.461.491.521.541.561.581.59n4时 RI 0.89。第三步算一致性比率 CR CI/RI。本例 CR 0.0104/0.89 0.0117。判定规则CR 0.1 认为一致性可接受否则需要调整判断矩阵。0.0117 远小于0.1通过。这里必须说清楚一个经常被误解的点CR 检验的是你的判断有没有自相矛盾不是你的判断对不对。一张CR0.001的矩阵可能完全荒谬比如你认为价格比质量重要100倍如果标度允许的话只要内部逻辑自洽CR照样很小。所以CR是必要不充分条件通过了不代表权重合理通不过一定说明有矛盾。注意n1和n2时 RI 为0此时不需要也无法做一致性检验CR没有意义。很多代码在这里除零报错记得加分支判断。4. MATLAB 完整实现与跑通案例4.1 代码骨架该怎么设计我不太喜欢网上那种一个脚本从读矩阵到出图全写完的写法改一个地方就要翻半天。我的习惯是拆成四个职责清晰的函数checkMatrix输入校验检查正数、互反、对角线、维度、最大标度。calcWeight权重计算同时输出三种方法的结果方便交叉验证。consistency一致性检验返回 λmax、CI、RI、CR。ahpSynthesize层次总排序把准则权重和方案权重合起来。再写一个主脚本把它们串起来负责输入数据和最终展示。这样拆的好处是别人接手时能快速定位问题而且每个函数都能单独测试。输入数据我建议用结构体组织避免一堆位置参数传来传去data.criteriaNames {价格,质量,交期,服务}; data.altNames {供应商A,供应商B,供应商C}; data.A [1 2 3 4; 1/2 1 2 3; 1/3 1/2 1 2; 1/4 1/3 1/2 1]; data.Aalt {...}; % 每个准则对应一张方案层判断矩阵4.2 完整可运行的 MATLAB 代码下面这段代码可以直接复制到 MATLAB 里运行包含了从校验到总排序的全部流程。function ahp_demo() %% AHP 完整演示校验 权重 一致性 总排序 clc; close all; criteriaNames {价格,质量,交期,服务}; altNames {方案A,方案B,方案C}; % 准则层判断矩阵 A [ 1 2 3 4; 1/2 1 2 3; 1/3 1/2 1 2; 1/4 1/3 1/2 1]; % 方案层判断矩阵每个准则一张 B {}; B{1} [1 2 3; 1/2 1 2; 1/3 1/2 1]; % 价格 B{2} [1 1/2 1/2; 2 1 1; 2 1 1]; % 质量 B{3} [1 1 1/2; 1 1 1/2; 2 2 1]; % 交期 B{4} [1 1 1/3; 1 1 1/3; 3 3 1]; % 服务 %% 1. 准则层 fprintf( 准则层一致性检验 \n); [wC, lambda, CI, CR] ahpCore(A); for i 1:numel(criteriaNames) fprintf( %-4s 权重 %.4f\n, criteriaNames{i}, wC(i)); end fprintf( lambda_max %.4f, CI %.4f, CR %.4f\n, lambda, CI, CR); %% 2. 方案层 nAlt numel(altNames); wAlt zeros(nAlt, numel(B)); fprintf(\n 方案层一致性检验 \n); for k 1:numel(B) [w, lambda, CI, CR] ahpCore(B{k}); wAlt(:,k) w; fprintf( 准则 %-4s : CR %.4f, 权重 [%s]\n, ... criteriaNames{k}, CR, num2str(w, %.4f )); if CR 0.1 warning(准则 %s 的判断矩阵未通过一致性检验, criteriaNames{k}); end end %% 3. 层次总排序 score wAlt * wC; fprintf(\n 层次总排序 \n); [~, idx] sort(score, descend); for i 1:nAlt fprintf( 第%d名: %-6s 综合得分 %.4f\n, i, altNames{idx(i)}, score(idx(i))); end %% 4. 总排序一致性 CIc zeros(1, numel(B)); RIc zeros(1, numel(B)); for k 1:numel(B) [~, lam, ci] ahpCore(B{k}); CIc(k) ci; RIc(k) riOfN(size(B{k},1)); end CItotal sum(wC .* CIc); RItotal sum(wC .* RIc); fprintf(\n总排序一致性: CI %.4f, RI %.4f, CR %.4f\n, ... CItotal, RItotal, CItotal/RItotal); %% 5. 可视化 figure(Color,w,Position,[100 100 800 350]); subplot(1,2,1); bar(wC); set(gca,XTickLabel,criteriaNames); ylabel(权重); title(准则层权重); subplot(1,2,2); bar(score(idx)); set(gca,XTickLabel,altNames(idx)); ylabel(综合得分); title(方案综合得分排序); end %% ---------- 核心计算 ---------- function [w, lambda_max, CI, CR] ahpCore(A) checkMatrix(A); n size(A,1); % 算术平均法 colSum sum(A, 1); A_norm A ./ repmat(colSum, n, 1); w1 mean(A_norm, 2); % 几何平均法 gm prod(A, 2) .^ (1/n); w2 gm / sum(gm); % 特征值法 [V, D] eig(A); [lambda_max, pos] max(real(diag(D))); w3 real(V(:, pos)); w3 w3 / sum(w3); w w3; % 默认采用特征值法 if max(abs(w - w1)) 0.02 warning(三种方法结果差异较大请检查矩阵一致性。); end CI (lambda_max - n) / (n - 1); RI riOfN(n); if RI 0 CR 0; else CR CI / RI; end end %% ---------- 随机一致性指标 ---------- function RI riOfN(n) table [0 0 0.52 0.89 1.12 1.26 1.36 1.41 1.46 1.49 ... 1.52 1.54 1.56 1.58 1.59]; if n 15 RI table(n); else RI 1.59; end end %% ---------- 矩阵合法性校验 ---------- function checkMatrix(A) n size(A,1); assert(size(A,1) size(A,2), 判断矩阵必须是方阵); assert(all(A(:) 0), 判断矩阵元素必须为正数); assert(max(abs(diag(A) - 1)) 1e-8, 主对角线元素必须为1); assert(n 2 n 15, 矩阵维度建议在2到15之间); for i 1:n for j 1:n assert(abs(A(i,j)*A(j,i) - 1) 1e-8, ... sprintf(元素(%d,%d)与(%d,%d)不满足互反性, i,j,j,i)); end end end代码里有几个设计点值得说一下。第一ahpCore同时算三种方法并做差异比对一旦超过0.02就告警这是个很好用的体检机制。第二riOfN单独抽出来方便以后扩展更大的n。第三校验函数用assert而不是弹窗出错时能直接定位到是哪一行断言失败。4.3 案例跑通与结果解读把上面的代码跑一遍输出大概是这样准则层权重是价格0.4658、质量0.2772、交期0.1611、服务0.0960CR约为0.012通过检验。这个结果符合直觉——大部分采购场景里价格确实是第一权重但也没到压倒性的程度。方案层的四张矩阵各自通过检验后把权重矩阵与准则权重相乘得到三个方案的综合得分。我调整了数据让结果有点悬念方案A在价格和服务上领先方案B在质量上最弱但价格接近方案C在交期上占优。最终算下来方案A综合得分0.385、方案B约0.347、方案C约0.268方案A以不到4个百分点的优势胜出。这时候真正的工作才开始去看权重接近的地方意味着什么。方案A和方案B只差0.038那就说明在当前偏好下两者其实难分伯仲最终取舍应该考虑AHP没建模的因素比如长期合作意愿、切换成本。如果硬拿0.385对0.347说方案A明显更优那是拿数字骗自己。我一般会做一次敏感性分析把价格权重上下浮动10%0.42到0.51重新算综合得分看排名会不会翻转。如果翻转了说明结论对价格权重高度敏感必须在报告里说明如果不翻转结论才比较稳。这一步很多论文省掉了但它是从算出个数字到真的做了决策分析的分水岭。4.4 层次总排序与整体一致性检验准则层和方案层各自通过检验不代表整体一定通过这是教材上强调但实践中经常被忽略的一点。整体一致性要用加权的方式算CItotal Σ wj × CIjRItotal Σ wj × RIjCRtotal CItotal / RItotal其中 wj 是准则层第j个准则的权重CIj 和 RIj 是该准则下方案层判断矩阵的对应值。判别标准依然是 CRtotal 0.1。为什么必须做这一步因为准则层的一致性再好方案层里那些小偏差会在加权合成时累积。我处理过一个五准则的项目每个准则下的方案层CR都在0.08左右看起来都过了但总排序的CR跑到了0.11超了。解决办法不是随便改数字而是回过头检查一致性最差的那张方案层矩阵通常问题就出在那里。提示代码里CItotal sum(wC .* CIc)这一行wC 必须是准则层的权重向量顺序要和方案层矩阵的排列一致。这个顺序错位是排查中最隐蔽的bug因为代码不会报错只是结果不对。建议在结构体里给每张矩阵带上准则名的字段合成前做一次对齐校验。5. 常见问题排查与踩坑实录5.1 CR超标了到底该怎么调这是最高频的问题。我的处理顺序是固定的从改结构往改数字依次尝试第一步检查矩阵填错了没有。有没有把倒数填反的有没有某个位置手误填成了8结果应该是1/8我遇到过的CR超标里接近三成是纯粹的录入错误改完就过了。第二步检查有没有语义重叠的准则。前面提过价格便宜和成本可控这类重复准则会让矩阵天然难以自洽。这时候要合并或删掉一个而不是硬调。第三步找出最矛盾的三个元素。具体做法是按方根法算出权重后计算理论标度 a(ij) wi/wj与实际填的 a(ij) 做比值找出偏离最大的几个位置。这些就是矛盾集中点重点复核这几个判断即可不用全盘重填。第四步才考虑微调数字。微调原则是只动那些你觉得本来就没想清楚的位置标度变化不超过两档比如从5改到4而不是改到1。如果一张矩阵需要改动超过三分之一的位置才能过检验那说明这张矩阵反映的偏好本身就是混乱的应该重做判断流程而不是修数字。最后这条是我最想说的一句为了过CR而编数字是AHP最大的滥用方式。见过有人写个小循环自动搜出一张CR0.1的矩阵交差那就完全背离了这个方法的意义。CR不过是有价值的信息它告诉你你的偏好不自洽这个信号值得花时间去看清楚。5.2 权重算出来跟直觉不符怎么办先分清楚是两种情况数学错了还是你的直觉其实站不住脚。如果权重排序和你的预期完全相反比如你认为质量最重要但算出来质量排第三先回溯判断矩阵。多数情况下你会发现在填某几个位置时为了应付而随手填的数字累积起来改变了排序。这种情况我相信你的直觉回到矩阵重填。但有时候恰恰相反算出来的结果让你不舒服但它反映的是你真实行为所体现的偏好。举个例子口头上大家都说安全第一但在资源分配的实际选择中成本和进度总是被优先保障。如果判断矩阵是你基于真实取舍填的那么算出来的权重就比口号更真实。这时候应该做的不是改数字而是问一句我们的实际偏好和宣称的偏好哪个才对还有一种情况是权重过于平均。四个准则算出0.26、0.25、0.25、0.24几乎平分。这说明你的判断里到处都是差不多重要AHP在这里没有提供额外信息。要么承认这几个准则确实权重接近要么重新梳理想清楚差异在哪。5.3 多个专家的意见怎么合群决策是实际项目里绕不开的问题。三种常见做法的差异很大我按推荐度排一下。第一种聚合判断矩阵推荐。让每位专家各填一张矩阵做一致性检验剔除或修正不合格的然后逐元素取几何平均得到聚合矩阵再统一算权重。几何平均比算术平均更适合因为判断矩阵元素是比值尺度几何平均能保持互反性算术平均会破坏四舍五入的互反性需要对上三角做处理。第二种聚合权重。每位专家的矩阵各自算权重再对权重向量取平均。这种做法简单但会丢信息因为不同专家的一致性水平被平等对待了。改进办法是加专家权重用一致性水平或资历来加权。第三种只取一个人的。如果专家之间分歧极大硬合出来的矩阵CR必然很差。这时候与其合成不如把分歧本身作为结论汇报出来——关于质量和交期哪个更重要团队内部存在明显分歧这个信息对决策者可能比一个虚假的平均值更有用。几何平均的公式很简单聚合矩阵的每个元素 a(ij) 所有专家在该位置标度的乘积^(1/m)m是专家数。实现时注意别直接用算术平均那会破坏互反性。5.4 常见问题速查表把上面这些整理成一张表方便对照排查现象可能原因处理办法CR 大于 0.1矩阵录入错误检查互反性和倒数是否填反CR 略超 0.1个别判断矛盾定位偏离最大的三个元素重点复核CR 远超 0.1准则语义重叠或偏好混乱重构层次结构重做判断流程三种算法权重差异大矩阵一致性差先修一致性再对比方法结果权重排序与直觉相反判断受应付式填写影响回溯矩阵重填分歧位置权重过于平均准则区分度不足合并准则或重新定义评价维度方案层某张矩阵过不了方案在该准则上确实难分高下考虑换用客观打分或承认并列专家分歧极大偏好结构本身不统一报告分歧而不是强行平均总排序CR超标各层小偏差累积查一致性最差的方案层矩阵结果对权重高度敏感权重不确定性强做敏感性分析报告区间结论6. 一些不那么教科书但很实用的补充6.1 Python 版本更省事的替代方案如果项目在 Linux 环境或者需要批量跑MATLAB 不一定方便。用 numpy 复刻核心逻辑不到30行import numpy as np RI_TABLE {1:0, 2:0, 3:0.52, 4:0.89, 5:1.12, 6:1.26, 7:1.36, 8:1.41, 9:1.46, 10:1.49, 11:1.52, 12:1.54, 13:1.56, 14:1.58, 15:1.59} def ahp(matrix): A np.asarray(matrix, dtypefloat) n A.shape[0] assert A.shape[0] A.shape[1], 必须是方阵 assert np.all(A 0), 元素必须为正 assert np.allclose(np.diag(A), 1), 对角线必须为1 assert np.allclose(A * A.T, 1), 必须满足互反性 # 几何平均法权重 gm np.prod(A, axis1) ** (1 / n) w gm / gm.sum() # 最大特征值 lam np.mean((A w) / w) CI (lam - n) / (n - 1) if n 1 else 0 RI RI_TABLE.get(n, 1.59) CR CI / RI if RI 0 else 0.0 return w, lam, CI, CR if __name__ __main__: A [[1, 2, 3, 4], [1/2, 1, 2, 3], [1/3, 1/2, 1, 2], [1/4, 1/3, 1/2, 1]] w, lam, ci, cr ahp(A) print(权重:, np.round(w, 4)) print(flambda_max{lam:.4f}, CI{ci:.4f}, CR{cr:.4f})跑出来的权重应该是 [0.4669, 0.2776, 0.1603, 0.0953]CR 约 0.012和 MATLAB 那边一致。这里用np.mean((A w) / w)计算 λmax比调eig快得多对一致性不太差的矩阵精度也够用。如果要做严格的论文级计算还是用幂法迭代或者eig更稳妥。6.2 AHP 和其他赋权方法的关系AHP 属于主观赋权法它的同类还有专家打分法、环比评分法对应的是客观赋权法比如熵权法、CRITIC、变异系数法。两者各有软肋主观法的问题在于人的判断有偏差容易受近期事件影响上个月出了质量事故这个月质量权重就会被抬高。客观法的问题在于它完全依赖数据本身的离散程度某个指标数据差异大就权重高但这个差异可能是量纲或异常值造成的跟重要性无关。我的实际做法是组合赋权AHP 算一组熵权法算一组然后按一个系数加权合成比如 w 0.6×w_AHP 0.4×w_obj。这样既保留了决策者的偏好表达又让数据有机会修正主观偏差。当然组合前一定要检查两组权重的方向是否一致如果 AHP 认为质量最重要而熵权法认为质量最不重要那说明数据和认知之间存在根本冲突这时候应该先去查数据而不是急着合成。6.3 我这些年用下来最想说几句第一AHP 的价值在于过程不在于结果。真正把判断矩阵填清楚、把一致性调明白的那几个小时你对这个决策问题的理解会比拿到权重数字更有收获。很多人把矩阵当成负担其实它才是这个方法的正文。第二永远别只报一个排名。把权重、CR值、敏感性分析的区间一起给出来。决策者看到方案A得分0.385方案B得分0.347价格权重在0.42到0.51范围内排名不变比看到A最优要踏实得多。第三结构比数字重要。层次结构搭错了后面无论怎么调矩阵都是在错误的方向上优化。我现在的习惯是在动笔算之前先把层次图画在纸上给每个准则写一句人话定义确保不同的人看了都能理解一致再动手填矩阵。第四也是最后一点CR 通不过不要急着改数字先改你自己的理解。每次遇到通不过的矩阵我最后都发现是自己对某两个准则的关系没想清楚。那个想清楚的瞬间才是这套方法真正给你的东西。后面如果要继续扩展可以考虑往这几个方向走引入模糊判断矩阵处理差不多重要这类模糊表达用 ANP 处理准则之间有依赖关系的情况或者把 AHP 定权重和 TOPSIS、VIKOR 组合起来做成完整的评价流程。这几条路子我都试过哪个更合适取决于你的准则之间到底有没有耦合以及你手上有没有客观数据可用。
返回列表