简介:这份文档围绕层次分析法(AHP)在城市竞争力评价中的应用展开,面向经济学、统计学、城市规划与系统工程等专业的学习者及政策研究者,帮助解决多指标综合评价中指标权重难以量化的问题。文档以课程学习报告形式,系统梳理AHP的基本思想与操作流程:从目标层、准则层、要素层、指标层四级结构入手,说明判断矩阵的1—9标度构造、特征向量权重计算及一致性检验(CR小于0.1)的判断标准,并结合中国城市竞争力评价实例,展示71项指标的分层归并与权重赋值过程。压缩包内含1个doc文档,约832KB,为完整课程学习报告,便于直接查阅和打印;目前已有140人学习。读者可从中获得AHP建模的完整框架、指标体系分层示例与一致性检验的实操思路,适合用作课程报告撰写参考,也可为城市竞争力评价、区域发展研究中的权重确定提供方法借鉴。
1. 在搜索框里输入“层析分析法”的人,十有八九想找的是层次分析法
层析是化学里按亲和力把混合物分开的手段,跟决策分析没有关系,一个词的输入法习惯就这么把概念带偏了很多年。而层次分析法在城市竞争力评价里干的事,本质上也是分离:把几十上百个互相纠缠的指标,拆成一层层能两两比较的小块,再把各处分散的专家判断汇总成一个权重向量。它最反直觉的一点是,整张排名表的可信度并不来自数据有多精确,而来自那个看起来最主观的环节——专家指着两个指标问“哪个更重要”。把这句主观回答变成可检验的数字,才是这套方法的真正基础;搞懂这一层转换,你也就能判断一份 AHP 报告到底能不能用。
2. 判断矩阵:为什么“两两比较”能比“直接打分”更稳
2.1 1-9 标度的心理物理依据
最省事的做法显然是让专家直接给指标打 0 到 100 分,然后归一化当权重。这条路在实践中很快会遇到麻烦:不同专家对“80 分”的理解不同,有人习惯打高,有人习惯打低;同一个人今天和明天给出的锚点也会漂移。绝对刻度依赖稳定的内部参照系,而人对量级的记忆恰恰是最不稳定的。
两两比较把问题从“它值多少分”换成“它比它重要多少倍”,用相对刻度替换了绝对刻度。人对相对差异的判断比绝对量级判断稳定得多,这是心理物理学里老掉牙的结论:感知强度按比例变化,而不是按差值变化。1-9 标度正是嵌在这个区间里的——再细的分档,人自己也分不清了。
| 标度 | 含义 | 典型表述 |
|---|---|---|
| 1 | 两者同等重要 | 差不多,说不上谁更关键 |
| 3 | 前者比后者稍重要 | 明显偏一头,但不悬殊 |
| 5 | 前者比后者明显重要 | 差距拉开了 |
| 7 | 前者比后者强烈重要 | 差得比较多 |
| 9 | 前者比后者极端重要 | 完全不是一个量级 |
| 2,4,6,8 | 上述相邻判断的中值 | 介于两档之间 |
注意这套标度的上限为什么是 9。它约等于一个数量级内的可分辨档位,超过这个范围,专家给出的“11 倍”和“13 倍”已经失去区分意义,反而把噪声引了进来。如果确实存在量级悬殊的指标,正确做法是把它挪到上一层去比较,而不是硬拉大标度。
2.2 互反性与传递性:判断矩阵的两条硬性约束
一个 n 阶判断矩阵 A,元素 a_ij 表示“第 i 项相对第 j 项的重要性倍数”。它必须满足三条:a_ij > 0、a_ji = 1/a_ij(互反性)、a_ii = 1(自反性)。互反性不是数学洁癖,而是防止专家自相矛盾:同一对指标问两遍方向,答案必须互为倒数,否则这个矩阵根本没法解释。
更严格的约束叫完全一致性:a_ij = a_ik × a_jk 对任意 i、j、k 成立。举个例子,专家认为 A 比 B 重要 3 倍,B 比 C 重要 2 倍,那么 A 相对 C 就该是 6 倍。可 6 这个数在标度表里没有名字,很多人凭手感会填 5 或 7,偏差就这么产生了。人脑不是传递闭包,n 越大、链条越长,这种偏差累积得越厉害。
这就解释了为什么一份能落地的城市竞争力评价,不会把 71 项指标塞进一个矩阵。71 阶矩阵需要填 C(71,2) = 2485 个独立判断,没有专家填得完,更没人能保证它的传递性。分层不是为了让结构图好看,而是把一次不可能完成的大判断,切成若干次能完成的判断。
2.3 四层递阶结构:把判断矩阵的阶数压在认知负荷之内
目标层、准则层、要素层、指标层,这四层的划分对应四种不同的抽象粒度:要回答的问题分别是“评价什么”“从哪几个方面看”“每个方面由哪些要素构成”“拿什么数据算”。分层的关键约束不在层数,而在每一层判断矩阵的阶数——通常在 3 到 7 之间最稳,正好落在人一次能同时权衡的元素数量上。
从权重数值能反推出这套结构:准则层四个分量 动力 0.4883、阻力 0.0893、相互影响 0.2328、环境水平 0.1896,加起来正好是 1.0000;再往下,经济实力 0.4162、政府作用 0.2618、消费水平 0.0624、人力资源 0.0986、科技实力 0.1611 这五项之和是 1.0001,说明它们是挂在“动力”下面的兄弟节点,在舍入误差内归一。
| 层级 | 元素 | 相对上层权重 |
|---|---|---|
| 准则层 | 动力 / 阻力 / 相互影响 / 环境水平 | 0.4883 / 0.0893 / 0.2328 / 0.1896 |
| 要素层(动力下) | 经济实力 / 政府作用 / 消费水平 / 人力资源 / 科技实力 | 0.4162 / 0.2618 / 0.0624 / 0.0986 / 0.1611 |
| 要素层(相互影响下) | 对外开放 / 依存度 | 0.6667 / 0.3333 |
| 要素层(环境水平下) | 基础设施 / 环境水平 | 0.5 / 0.5 |
这张表里有两个细节值得注意。对外开放与依存度是 2:1 的整数关系,而 2 阶矩阵只有一个自由度,一致性天然成立,这里的“通过检验”其实不携带任何信息。基础设施和环境水平各占 0.5,说明专家认为两者同等重要——1 标度的判断,也是 2 阶矩阵的典型结果。读懂这些,比读 CR 值更能判断一份权重表是怎么来的。
3. 特征向量为什么就是权重:主特征值与幂法迭代
3.1 正互反矩阵的主特征向量给出了权重的数学定义
设真实权重向量为 w,如果专家完全理性、判断完全一致,那么 a_ij 就该精确等于 w_i / w_j。此时矩阵的每一行都正比于 w,A 的秩为 1,A w = n w,最大特征值恰好是 n,特征向量就是 w 本身。这就是权重与特征向量的原始联系:一致时它们是同一个东西。
现实中 A 不会完美,就退一步——找一个 w,使 a_ij 尽可能接近 w_i / w_j。这个“尽可能”的最小二乘解,在正互反矩阵上由 Perron-Frobenius 定理保证存在唯一的正的主特征向量。定理说的是:全正矩阵存在一个代数重数为 1 的正实特征值,其模严格大于其他所有特征值的模,对应特征向量严格为正。权重不能有负数、不能有两个解,这两条硬要求正是靠这个定理兜底的。
所以“求特征向量”不是某种约定俗成的算法选择,而是把“最接近真实比例关系的那组权重”这件事数学化之后,唯一站得住的答案。
3.2 幂法:原文那四步迭代到底在算什么
主特征值不需要求全部特征值再挑最大的,幂法用迭代就能逼近:任取一个正初始向量,反复左乘 A 并归一化,方向会迅速被主特征向量“吸”过去。每乘一次,次主特征值对应的分量就被主分量甩开一个 |λ2/λmax| 的倍率,所以收敛速度完全由这个比值决定。
import numpy as np def power_iteration(A, tol=1e-12, max_iter=200): n = A.shape[0] w = np.ones(n) / n # 初始向量取均匀分布,保证全正 lam = 0.0 for k in range(max_iter): v = A @ w # 左乘:放大主特征方向的分量 lam_new = v.sum() # 用 l1 范数当归一化因子,同时逼近 λmax w_new = v / lam_new # 归一化后权重之和恒为 1 if np.abs(w_new - w).max() < tol: return lam_new, w_new w, lam = w_new, lam_new return lam, w A = np.array([ [1, 5, 3, 2 ], [1/5, 1, 1/3, 1/4], [1/3, 3, 1, 1/2], [1/2, 4, 2, 1 ], ]) lam, w = power_iteration(A) print(f"λmax = {lam:.4f}") # 约 4.0514 print(f"w = {w.round(4)}") # 约 [0.4709 0.0737 0.1715 0.2840]这段代码里的三个参数值得说清楚。初始向量取均匀分布而不是随机值,是为了避免“初始方向恰好与主特征向量正交”这种概率极低但会让迭代原地踏步的情况。归一化用 l1 范数(各分量求和)而不是 l2 范数,是因为权重向量的定义就要求分量之和为 1,用求和归一化可以在每一步都直接得到一个合法的权重向量,迭代过程本身就有解释力。tol 取 1e-12 已经很奢侈,实践中 1e-8 就够了,因为判断矩阵本身的标度误差远大于这个量级。
上面那个 4 阶矩阵是为了跑通流程临时构造的示意矩阵,不代表任何真实报告的原始判断,但它的一致性水平接近真实场景:λmax 略大于 n,特征向量四项之和为 1。
3.3 算术平均法与几何平均法:三种近似为什么结果接近
幂法是迭代解,工程上更常用的是两种闭式近似。算术平均法先把每一列归一化,再按行取平均;几何平均法按行求几何平均再归一化。它们都在逼近同一个主特征向量,只是逼近路径不同。
def arithmetic_mean(A): B = A / A.sum(axis=0) # 按列归一化:消掉各列的量级差异 return B.mean(axis=1) # 行平均:每一行的平均值即该指标的权重 def geometric_mean(A): n = A.shape[0] g = np.prod(A, axis=1) ** (1.0 / n) # 行几何平均:对极端值更稳健 return g / g.sum() wa = arithmetic_mean(A) wg = geometric_mean(A) print(wa.round(4)) # [0.4709 0.0737 0.1715 0.2840] print(wg.round(4)) # 与上式在小数点后三位内一致算术平均法的逻辑很直白:a_ij 近似等于 w_i / w_j,那么第 j 列归一化之后,第 i 行的值就近似是 w_i,把所有列上的估计平均一下,噪声就被压低了。几何平均法的优势在于对极端标度不敏感——如果某位专家填了一个 9,算术平均会被它拉偏,几何平均则把它当成乘法意义上的一个因子,影响被压缩。
对完全一致矩阵,这三种方法给出完全相同的结果,这是它们能互相替代的根本原因。对接近一致的矩阵,差异只在扰动的一阶项上,量级通常小于专家判断本身的误差。原文选择算术平均法并不算错,但如果判断矩阵里存在个别极端标度,几何平均法通常更稳。
4. 一致性检验:CR<0.1 是阈值还是经验判据
4.1 λmax 与 n 的差值,度量的是判断偏差而非数据错误
完全一致时 λmax = n,这是 3.1 节已经给出的结论。不一致时 λmax 会严格大于 n,而且偏离越远、值越大。这个性质给了我们一把现成的尺子:把 λmax - n 拿出来,就得到了“判断偏离一致性的总幅度”。
直接用它不行,因为矩阵阶数越大,随机偏差累积得越多,同样“不一致程度”的 3 阶矩阵和 8 阶矩阵,λmax - n 根本不可比。所以除以 n - 1 做归一化,得到一致性指标 CI = (λmax - n) / (n - 1)。分母取 n - 1 是自由度意义上的类比:n 阶矩阵有 n 个特征值,和为迹,即 n,多出来的那部分由 n - 1 个自由度分摊。
def consistency(A, w): n = A.shape[0] lam = float(np.mean((A @ w) / w)) # 用特征向量反算 λmax,比 sum 更稳 ci = (lam - n) / (n - 1) if n > 1 else 0.0 return lam, ci lam, ci = consistency(A, wa) print(f"λmax={lam:.4f} CI={ci:.4f}") # λmax≈4.0514 CI≈0.0171用 (Aw)/w 的平均值反算 λmax,比幂法里用求和逼近更精确,因为这一步已经拿到了收敛的 w,逐分量相除再平均能抵掉一部分舍入误差。这个写法在只有一个判断矩阵时无所谓,但在要批量检验几十个矩阵的报告里,它能避免“同一个矩阵算出两个 λmax”的尴尬。
4.2 RI 是模拟出来的经验表,不是推导出来的公式
CI 有了,还缺一个参照系:多大的 CI 算“大”?这个问题的答案不是算出来的,是模拟出来的。随机生成大量正互反矩阵(元素从 1-9 及其倒数里均匀抽取),对每一个算 CI,取平均,就得到随机一致性指标 RI。它代表“完全随机瞎填的情况下,平均会偏离一致性多远”。
| n | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|---|
| RI | 0 | 0 | 0.58 | 0.90 | 1.12 | 1.24 | 1.32 | 1.41 | 1.45 | 1.49 |
看这张表要注意两点。第一,n ≤ 2 时 RI = 0,因为 1 阶和 2 阶矩阵的一致性天然成立,没有检验的必要,硬算会除零。第二,RI 随 n 单调上升,说明随机填的矩阵阶数越大越不一致——这也解释了为什么第 2 章强调要把判断矩阵压小,阶数一大,你连“及格线”都会跟着抬高。
最终指标是一致性比率 CR = CI / RI。上面那个示意矩阵 CR = 0.0171 / 0.90 ≈ 0.019,远低于 0.1,通过检验。
4.3 CR 不通过时该怎么调,而不是怎么凑
CR < 0.1 是 Saaty 给出的经验阈值,本质是“偏离随机水平不超过一成”,没有更深的数学必然性。它的正确用法是当成一个待复核信号,而不是必须通过的关卡。
真正需要的是定位不一致的来源。做法是把 A 的每个元素和 w_i / w_j 比一遍,偏差最大的那几个位置,就是专家判断最不自洽的地方。
def locate_inconsistency(A, w, topk=3): n = A.shape[0] ratio = np.abs(A - np.outer(w, 1 / w)) # a_ij 与 w_i/w_j 的绝对偏差 idx = np.dstack(np.unravel_index( np.argsort(ratio, axis=None)[::-1], (n, n)))[0] out = [] for i, j in idx: if i < j: # 只看上三角,避免重复 out.append((i, j, round(float(ratio[i, j]), 3))) if len(out) == topk: break return out这段函数返回偏差最大的三个上三角位置。调整时优先动这几处,重新问一遍专家“这两项到底差几档”,而不是随手把一个 5 改成 4 去凑 CR。前者修正的是判断,后者修正的是数字——数字好看了,判断反而更假,这张权重表后面所有的排名都会继承这个假。
还有一种情况值得单独说:CR 怎么调都过不去,往往不是专家填错了,而是这些指标本来就不该放在同一个矩阵里。比如把“经济实力”和“空气质量”直接比重要性,两者的可比性本身就成问题。这时候该做的是把它们拆到不同父节点下,而不是继续在同一层里微调。
5. 常见问题与排查:AHP 在落地时最容易出错的五个地方
5.1 现象:CR 完美等于 0,报告写着“一致性极佳”
原因通常有两个。一是矩阵阶数为 2,一致性天然成立,CR 恒为 0,这个数字不携带任何信息。二是有人先算出权重、再用 w_i / w_j 反填判断矩阵,这样构造出来的矩阵必然完全一致,也就失去了检验的意义——你检验的不是专家的判断,而是自己的除法。
解决的办法是要求报告同时给出 n、λmax 和 CR 三个值。只写 CR 而不写 n 的,基本可以怀疑;n = 2 的矩阵,直接注明“无需检验”,别把它当成质量证明。
5.2 现象:总表 CR 合格,但某个子矩阵 CR 达到 0.3
原因是把一致性检验当成了整体指标。AHP 的一致性检验是逐矩阵进行的,准则层的 CR 合格,完全不保证要素层、指标层那十几个小矩阵也合格。权重是分层合成的,任何一层的偏差都会顺着乘法链传到最终指数上,而且下层矩阵数量多,翻车的概率远高于顶层。
解决办法是在代码里对每个判断矩阵单独跑一遍 consistency,输出一张清单,任何一个超标就回退到那一层重填。这一步做成流水线里的硬性检查,比事后人工翻附件可靠得多。
5.3 现象:局部权重算对了,合成出来的总指数却和单层算的对不上
原因是把局部权重当成了全局权重。要素层里经济实力的 0.4162 是相对于“动力”的,它相对于总目标的权重是 0.4162 × 0.4883 ≈ 0.2032。直接拿 0.4162 去乘原始数据,等于把“动力”这个父节点的 0.4883 丢了,所有下层指标被系统性放大。
正确的合成是递归相乘:某一指标的全局权重,等于从它往上走到目标层路径上所有局部权重的连乘。写代码时用一个字典缓存每层的全局权重,从顶层往下逐层累乘,比在公式里手写一长串乘积安全。合成完之后做个校验,同一父节点下所有子节点的全局权重之和,应当等于该父节点的全局权重。
5.4 现象:排名结果和经济直觉完全相反,富裕的排到了后面
原因是无量纲化时没有区分正向指标和逆向指标。城市竞争力指标里,人均 GDP、科研投入这类越大越好,贫富分化、污染排放这类越小越好。如果统一用 (x - min) / (max - min) 处理,逆向指标会被算成“数值越大得分越高”,排名直接反过来。
解决办法是在指标元数据里给每个指标打上 direction 标记,无量纲化时对逆向指标取 1 - x',或者直接用 (max - x) / (max - min)。这一步最好在数据加载阶段就固化下来,别等到算完指数才发现,那时候排查起来要一路回溯到最上游。
5.5 现象:换一位专家重填,排名前十变了六个
原因是判断矩阵对扰动有敏感性,而权重又会被逐层放大。要素层某个指标权重从 0.06 变成 0.08,看着不起眼,但经过父层 0.4883 的放大后再乘上它在指标层的分量,落到最终指数上可能挪动好几个名次。指标层元素多、单个权重小,不代表影响小,因为数据本身的离散程度可能很大。
解决办法是做敏感性分析,而不是相信单一结果。具体做法是每次只把一个判断矩阵里的某个标度上下调一档,重跑全流程,记录排名的变动幅度。排名稳定的区间可以直接用于决策,排名频繁翻转的区间,说明这批指标的权重信息量不足,该补数据或者该合并指标,而不是继续在权重上做文章。
6. 从矩阵到排名:AHP 给了权重,但给不了“差多少”
AHP 在整个评价链条里承担的角色,比很多人以为的要窄。它只回答一个问题:在给定指标体系下,各项的相对重要性是多少。它不回答“某个城市在这项上比另一个城市强多少”,那是无量纲化和原始数据的活。把这两件事混在一起,是这套方法最常见的误用。
这个边界带来的第一个设计取舍,是权重和数据必须分开处理。合理的流程是:先用 AHP 得到每个底层指标的全局权重,再用统一的极差法把原始数据映射到 0-1 区间,最后按权重加权求和。两步之间不要互相污染——权重不该因为某个城市数据异常而调整,数据也不该因为权重小而放宽量纲要求。
第二个取舍是验证方式。AHP 的结果没有唯一正确答案,它是一组专家共识的数学表达,所以单一的 CR 通过说明不了什么。我一般会做两件事交叉验证:一是敏感性分析,单点扰动判断矩阵看排名是否稳定;二是换一种赋权方法(比如熵权法),看两种权重下的排名相关性。如果相关性很低,问题往往出在指标冗余上——几个指标高度共线,AHP 却把它们当成独立维度各给了一份权重,等于变相加倍。
第三个取舍是关于精度。AHP 的权重只到小数点后三四位,标度本身也只有 9 档,这意味着最终指数的分辨率是有限的。排名前十和第十一之间的差距,如果在 0.005 以内,其实不该被解读成“强于”。报告里给出分档(第一梯队、第二梯队)比给出精确名次更诚实。
血泪教训来自一次指标合并。当时有两项指标被专家判为“同等重要”,权重各 0.5,数据算完发现其中一项在所有样本上几乎不变,方差接近于零——它实际上没有区分度,却稳稳占着 50% 的分量,把另一项的信号稀释掉了一半。从那以后,我每次跑完 AHP 都会强制走一遍“权重 × 数据离散度”的联合检查,看有没有哪个高权重指标的方差低得离谱。权重是专家给的,离散度是数据给的,两者不匹配的地方,就是这份评价最该被质疑的地方。希望帮到你。
本文还有配套的精品资源,点击获取