层次分析法(Analytic Hierarchy Process)
层次分析法建模步骤:
- ①建立递阶层次结构模型
- ②构造出各层次中的所有判断矩阵
- ③层次单排序及一致性检验
- ④层次总排序及一致性检验
1 建立递阶层次结构模型
将决策的目标、考虑的因素(决策准则)和决策对象按他们之间的相互关系分成最高层、中间层和最低层
- 最高层:只有一个元素,是决策目标
- 中间层(准则层):包含了为实现目标所涉及的中间环节,它可以由若干个层次组成,包括所需考虑的因素、决策的准则,因此也称为准则层
- 最低层(措施层、方案层):包括了为实现目标可供选择的各种措施、决策方案
2 构造出各层次中的所有判断矩阵
若要比较本层所有
n
n
n 个因素
X
=
x
1
,
x
2
,
.
.
.
,
x
n
X={x_1,x_2,...,x_n}
X=x1,x2,...,xn 对更高一层某
1
1
1 个因素
Z
Z
Z 的影响大小,可以采用对本层因素进行两两比较建立判断矩阵的方法,
Z
−
X
Z-X
Z−X 之间的判断矩阵
A
=
(
a
i
j
)
n
×
n
a
i
j
=
x
i
x
j
i
,
j
=
1
,
2
,
.
.
.
,
n
A= \begin{pmatrix} a_{ij} \end{pmatrix}_{n\times n} \qquad a_{ij}=\frac{x_i}{x_j} \qquad i,j=1,2,...,n
A=(aij)n×naij=xjxii,j=1,2,...,n
- A A A 为正互反矩阵, a i j > 0 , a i j = 1 / a j i a_{ij}>0,a_{ij}=1/a_{ji} aij>0,aij=1/aji
Santy 的 1~9 标度
标度 | 含义 |
---|---|
1 | 表示两个因素相比,具有相同重要性 |
3 | 表示两个因素相比,前者比后者稍重要 |
5 | 表示两个因素相比,前者比后者明显重要 |
7 | 表示两个因素相比,前者比后者强烈重要 |
9 | 表示两个因素相比,前者比后者极端重要 |
2,4,6,8 | 表示上述相邻判断的中间值 |
倒数 | 若因素
x
i
x_i
xi 与因素
x
j
x_j
xj 的重要性之比为
a
i
j
a_{ij}
aij, 那么因素 x j x_j xj 与因素 x i x_i xi 的重要性之比为 a j i a_{ji} aji |
3 层次单排序及一致性检验
层次单排序
Z − X Z-X Z−X 之间的判断矩阵 A A A 对应于最大特征值 λ max \lambda_{\max} λmax 的特征向量 W W W,经过归一化之后,即为本层所有 n n n 个因素 X = x 1 , x 2 , . . . , x n X={x_1,x_2,...,x_n} X=x1,x2,...,xn 对更高一层某 1 1 1 个因素 Z Z Z 的相对重要性的排序权值,称为层次单排序权值。
对判断矩阵 A A A 的一致性检验
-
①计算一致性指标 C I CI CI
C I = λ max − n n − 1 CI=\frac{\lambda_{\max}-n}{n-1} CI=n−1λmax−n- λ max \lambda_{\max} λmax 为判断矩阵 A A A 的最大特征值
-
②查找相应的平均随机一致性指标 R I RI RI
n n n 1 2 3 4 5 6 7 8 9 R I RI RI 0.00 0.00 0.58 0.90 1.12 1.24 1.32 1.41 1.45 -
③计算一致性比例 C R CR CR
C R = C I R I CR=\frac{CI}{RI} CR=RICI
当 C R < 0.10 CR < 0.10 CR<0.10 时,认为判断矩阵的一致性是可以接受的,否则应对判断矩阵 A A A 作适当修正。
4 层次总排序及一致性检验
层次总排序
在进行决策方案选择时,需要根据最低层中各个决策方案对最高层中决策目标的排序权值进行选择。为了得到最低层的层次总排序权值,需要自顶向下地对权值进行合成,合成步骤如下:
当前层(
B
B
B 层)有
n
n
n 个因素
B
1
,
B
2
,
.
.
.
,
B
n
B_1,B_2,...,B_n
B1,B2,...,Bn,相对
B
B
B 层的更高一层
A
A
A 层有
m
m
m 个因素
A
1
,
A
2
,
.
.
.
,
A
m
A_1,A_2,...,A_m
A1,A2,...,Am,因素
A
j
A_j
Aj 的层次总排序权值为
a
j
a_j
aj ,因素
B
i
B_i
Bi 对因素
A
j
A_j
Aj 的层次单排序权值为
b
i
j
b_{ij}
bij,则因素
B
i
B_i
Bi 的层次总排序权值
b
i
b_i
bi 为
b
i
=
∑
j
=
1
m
a
j
b
i
j
(
i
=
1
,
2
,
.
.
.
,
n
)
b_i=\sum_{j=1}^{m}a_jb_{ij}\qquad (i=1,2,...,n)
bi=j=1∑majbij(i=1,2,...,n)
- 可能出现因素 B j B_j Bj 与因素 A i A_i Ai 无关联的情况,这时 b i j = 0 b_{ij}=0 bij=0
- 相对最高层的更低一层中,各因素的层次总排序权值即为层次单排序权值
对层次总排序的一致性检验
在对
A
j
−
B
A_j-B
Aj−B 之间的判断矩阵
B
(
j
)
B^{(j)}
B(j) 一致性检验中求得一致性指标
C
I
j
CI_j
CIj,相应的平均随机一致性指标为
R
I
j
RI_j
RIj,则
B
B
B 层总排序的一致性比例为
C
R
=
∑
j
=
1
m
C
I
j
a
j
∑
j
=
1
m
R
I
j
a
j
CR=\frac{\displaystyle\sum_{j=1}^mCI_ja_j}{\displaystyle\sum_{j=1}^mRI_ja_j}
CR=j=1∑mRIjajj=1∑mCIjaj
- 因为可能出现因素 B j B_j Bj 与因素 A i A_i Ai 无关联的情况,所以 R I j RI_j RIj 不为定值
当 C R < 0.10 CR < 0.10 CR<0.10 时,认为 B B B 层的层次总排序结果具有较满意的一致性并接受该分析结果。
# author : Lee
# date : 2021/3/27 11:14
import pandas as pd
import numpy as np
class AHP:
RI = np.array([0, 0, 0.58, 0.90, 1.12, 1.24, 1.32, 1.41, 1.45])
def __init__(self, A, b):
self.A = A # Z-A
self.b = b # A-B
self.m = A.shape[0] # size of A
self.n = b.shape[1] # size of B
@staticmethod
def cal_CR(A):
eig_val, eig_vec = np.linalg.eig(A)
lambda_max = max(eig_val.real)
W = eig_vec[:, np.argmax(eig_val.real)].real
W = W / np.sum(W) # normalization
n = A.shape[0]
CI = (lambda_max - n) / (n - 1)
CR = CI / AHP.RI[n - 1]
return W, CR, CI
def ahp(self):
W_A, CR_A, _ = AHP.cal_CR(self.A)
W_b = np.empty((self.n, self.m))
CR_b = np.empty(self.m)
CI_b = np.empty(self.m)
for i, b_i in enumerate(self.b):
W_b[:, i], CR_b[i], CI_b = AHP.cal_CR(b_i)
W_Z = W_b @ W_A[:, None]
CR_Z = np.sum(CI_b * W_A) / np.sum(AHP.RI[self.n - 1] * W_A)
return W_A, CR_A, W_b, CR_b, W_Z, CR_Z
def main():
A = np.array([[1, 1, 1, 4, 1, 1 / 2],
[1, 1, 2, 4, 1, 1 / 2],
[1, 1 / 2, 1, 5, 3, 1 / 2],
[1 / 4, 1 / 4, 1 / 5, 1, 1 / 3, 1 / 3],
[1, 1, 1 / 3, 3, 1, 1],
[2, 2, 2, 3, 3, 1]])
b_1 = np.array([[1, 1 / 4, 1 / 2],
[4, 1, 3],
[2, 1 / 3, 1]])
b_2 = np.array([[1, 1 / 4, 1 / 5],
[4, 1, 1 / 2],
[5, 2, 1]])
b_3 = np.array([[1, 3, 1 / 3],
[1 / 3, 1, 1 / 7],
[3, 7, 1]])
b_4 = np.array([[1, 1 / 3, 5],
[3, 1, 7, ],
[1 / 5, 1 / 7, 1]])
b_5 = np.array([[1, 1, 7],
[1, 1, 7],
[1 / 7, 1 / 7, 1]])
b_6 = np.array([[1, 7, 9],
[1 / 7, 1, 1],
[1 / 9, 1, 1]])
b = np.array([b_1, b_2, b_3, b_4, b_5, b_6])
lee = AHP(A, b)
W_A, CR_A, W_b, CR_b, W_Z, CR_Z = lee.ahp()
pd.set_option('precision', 5)
np.set_printoptions(precision=5)
print('-' * 4 + ' A层 ' + '-' * 4)
df_A = pd.DataFrame(W_A[None, :],
columns=['A_' + str(i + 1) for i in range(lee.m)])
print(df_A)
print('CR : ', CR_A)
print('-' * 4 + ' B层 ' + '-' * 4)
df_b = pd.DataFrame(np.vstack((W_b, CR_b)),
index=['B_' + str(i + 1) for i in range(lee.n)] + ['CR'],
columns=['A_' + str(i + 1) for i in range(lee.m)])
df_b.loc['CT', :] = CR_b < 0.1
print(df_b)
print('-' * 4 + ' 层次总排序及一致性检验 ' + '-' * 4)
df_Z = pd.DataFrame(W_Z,
index=['B_' + str(i + 1) for i in range(lee.n)])
print(df_Z)
print('CR : ', CR_Z)
if __name__ == '__main__':
main()