层次分析法模型
本文最后更新于 2025年7月28日 上午
怎么能让指标在同一数量级,且保证在同一指标下其差距不变?
归一化处理:数组[a, b, c] -> $\frac{a}{a+b+c}, \frac{b}{a+b+c}, \frac{c}{a+b+c}$,再调整各自的权重
层次分析法(AHP):
模型原理:
将问题分成三个层次:最高层(结果),中间层,最底层(决策提供的方案 )
基本步骤
1. 建立递阶层次结构模型
2. 构造出各层次中的所有判断矩阵
- 对指标的重要性进行两两比较,构造判断矩阵,从而科学地求出权重
- 矩阵中$a_{ij}$的含义:第$i$个指标相对于第$j$个指标的重要程度
| 标度 | 含义 |
|---|---|
| 1 | 表示两个因素相比,具有同样重要性 |
| 3 | 表示两个因素相比,一个因素比另一个因素稍微重要 |
| 5 | 表示两个因素相比,一个因素比另一个因素明显重要 |
| 7 | 表示两个因素相比,一个因素比另一个因素强烈重要 |
| 9 | 表示两个因素相比,一个因素比另一个因素极端重要 |
| 2, 4, 6, 8 | 上述两相邻判断的中值 |
如果每次都只是两两比较,最后可能产生矛盾,这时需要一致性检验
正负反矩阵:$a_{ij}>0且a_{ij} \times a_{ji}=1且各行各列成比例$
一致矩阵:若正负反矩阵满足$a_{ik} \times a_{kj}=a_{ij}$,则为一致矩阵
一致性检验原理:检验我们构造的判断矩阵和一致矩阵是否有太大差别

3. 求权重(得到最后的权重向量)
套板子就行)
- 几何平均法求权重
- 算术平均法求权重
- 特征值法求权重
层次分析法 python代码 (ai)
代码
import numpy as np
class AHP:
"""
使用 Python 实现层次分析法 AHP
"""
def __init__(self, criteria, judgment_matrix):
"""
初始化 AHP 类
:param criteria: list, 评价准则的名称列表
:param judgment_matrix: np.ndarray, 判断矩阵
"""
self.criteria = criteria
self.matrix = np.array(judgment_matrix)
self.n = self.matrix.shape[0]
# 随机一致性指标 RI 表
self.RI = {
1: 0, 2: 0, 3: 0.58, 4: 0.90, 5: 1.12, 6: 1.24, 7: 1.32,
8: 1.41, 9: 1.45, 10: 1.49, 11: 1.51, 12: 1.48, 13: 1.56,
14: 1.57, 15: 1.59
}
def _check_consistency(self, max_eigenvalue):
"""
一致性检验
公式: CR = CI / RI, CI = (λ_max - n) / (n - 1)
"""
CI = (max_eigenvalue - self.n) / (self.n - 1)
# 当 n <= 2 时,判断矩阵总是一致的
if self.n <= 2:
CR = 0
else:
try:
CR = CI / self.RI[self.n]
except KeyError:
print(f"警告: 矩阵大小 n={self.n} 超出预设的 RI 表范围,无法计算 CR。")
CR = float('nan') # Not a Number
print("\n--- 一致性检验 ---")
print(f"最大特征值 λ_max = {max_eigenvalue:.4f}")
print(f"一致性指标 CI = {CI:.4f}")
if self.n > 2:
print(f"随机一致性指标 RI = {self.RI.get(self.n, 'N/A')}")
print(f"一致性比率 CR = {CR:.4f}")
if CR < 0.10:
print("结果: 判断矩阵通过一致性检验。")
return True
else:
print(f"结果: 判断矩阵未通过一致性检验 (CR = {CR:.4f} >= 0.10),建议修正判断矩阵。")
return False
def arithmetic_mean_method(self):
"""
算术平均法求权重
1. 将判断矩阵按列归一化
2. 将归一化后的矩阵按行求和
3. 将行和向量归一化得到权重向量
"""
# 1. 按列归一化
col_sum = np.sum(self.matrix, axis=0)
normalized_matrix = self.matrix / col_sum
# 2. 按行求和
row_sum = np.sum(normalized_matrix, axis=1)
# 3. 归一化得到权重
weights = row_sum / self.n
print("\n--- 1. 算术平均法 (Arithmetic Mean Method) ---")
for i, w in enumerate(weights):
print(f" {self.criteria[i]:<10}: {w:.4f}")
return weights
def geometric_mean_method(self):
"""
几何平均法求权重
1. 计算判断矩阵每行元素的几何平均数
2. 将得到的向量归一化
"""
# 1. 计算每行乘积
row_product = np.prod(self.matrix, axis=1)
# 2. 计算 n 次方根
root = np.power(row_product, 1 / self.n)
# 3. 归一化得到权重
weights = root / np.sum(root)
print("\n--- 2. 几何平均法 (Geometric Mean Method) ---")
for i, w in enumerate(weights):
print(f" {self.criteria[i]:<10}: {w:.4f}")
return weights
def eigenvalue_method(self):
"""
特征值法求权重
1. 求出判断矩阵的最大特征值及其对应的特征向量
2. 对特征向量进行归一化处理
"""
# 1. 计算特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(self.matrix)
# 2. 找到最大特征值及其索引
max_eigenvalue_index = np.argmax(eigenvalues)
max_eigenvalue = np.real(eigenvalues[max_eigenvalue_index])
# 3. 提取对应的特征向量
eigenvector = np.real(eigenvectors[:, max_eigenvalue_index])
# 4. 归一化权重向量
weights = eigenvector / np.sum(eigenvector)
print("\n--- 3. 特征值法 (Eigenvalue Method) ---")
for i, w in enumerate(weights):
print(f" {self.criteria[i]:<10}: {w:.4f}")
# 进行一致性检验
self._check_consistency(max_eigenvalue)
return weights, max_eigenvalue
if __name__ == '__main__':
# --- 示例 ---
# 假设需要选择一个旅游目的地,考虑四个准则:
# C1: 景色
# C2: 费用
# C3: 交通
# C4: 饮食
criteria_names = ['景色', '费用', '交通', '饮食']
# 构建判断矩阵 A
# A[i, j] 表示准则 i 相对于准则 j 的重要性
# 例如 A[0, 1] = 3 表示 "景色" 比 "费用" '稍重要'
judgment_matrix = [
[1, 3, 4, 2],
[1 / 3, 1, 2, 1 / 2],
[1 / 4, 1 / 2, 1, 1 / 3],
[1 / 2, 2, 3, 1]
]
# 实例化 AHP
ahp_solver = AHP(criteria=criteria_names, judgment_matrix=judgment_matrix)
# 分别使用三种方法计算权重
w_arithmetic = ahp_solver.arithmetic_mean_method()
w_geometric = ahp_solver.geometric_mean_method()
# 特征值法会同时进行一致性检验
w_eigen, lambda_max = ahp_solver.eigenvalue_method()
print("\n--- 最终权重对比 ---")
print(f"{'准则':<10} {'算术平均法':<12} {'几何平均法':<12} {'特征值法':<12}")
print("-" * 50)
for i in range(len(criteria_names)):
print(f"{criteria_names[i]:<10} {w_arithmetic[i]:<12.4f} {w_geometric[i]:<12.4f} {w_eigen[i]:<12.4f}")