层次分析法(Analytic Hierarchy Process)
层次分析法建模步骤:
- ①建立递阶层次结构模型
- ②构造出各层次中的所有判断矩阵
- ③层次单排序及一致性检验
- ④层次总排序及一致性检验
1 建立递阶层次结构模型
将决策的目标、考虑的因素(决策准则)和决策对象按他们之间的相互关系分成最高层、中间层和最低层
- 最高层:只有一个元素,是决策目标
- 中间层(准则层):包含了为实现目标所涉及的中间环节,它可以由若干个层次组成,包括所需考虑的因素、决策的准则,因此也称为准则层
- 最低层(措施层、方案层):包括了为实现目标可供选择的各种措施、决策方案
2 构造出各层次中的所有判断矩阵
若要比较本层所有 nnn 个因素 X=x1,x2,...,xnX={x_1,x_2,...,x_n}X=x1,x2,...,xn 对更高一层某 111 个因素 ZZZ 的影响大小,可以采用对本层因素进行两两比较建立判断矩阵的方法,Z−XZ-XZ−X 之间的判断矩阵
A=(aij)n×naij=xixji,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
- AAA 为正互反矩阵,aij>0,aij=1/ajia_{ij}>0,a_{ij}=1/a_{ji}aij>0,aij=1/aji
Santy 的 1~9 标度
标度 | 含义 |
---|---|
1 | 表示两个因素相比,具有相同重要性 |
3 | 表示两个因素相比,前者比后者稍重要 |
5 | 表示两个因素相比,前者比后者明显重要 |
7 | 表示两个因素相比,前者比后者强烈重要 |
9 | 表示两个因素相比,前者比后者极端重要 |
2,4,6,8 | 表示上述相邻判断的中间值 |
倒数 | 若因素 xix_ixi 与因素 xjx_jxj 的重要性之比为 aija_{ij}aij, 那么因素 xjx_jxj 与因素 xix_ixi 的重要性之比为 ajia_{ji}aji |
3 层次单排序及一致性检验
层次单排序
Z−XZ-XZ−X 之间的判断矩阵 AAA 对应于最大特征值 λmax\lambda_{\max}λmax 的特征向量 WWW,经过归一化之后,即为本层所有 nnn 个因素 X=x1,x2,...,xnX={x_1,x_2,...,x_n}X=x1,x2,...,xn 对更高一层某 111 个因素 ZZZ 的相对重要性的排序权值,称为层次单排序权值。
对判断矩阵 AAA 的一致性检验
-
①计算一致性指标 CICICI
CI=λmax−nn−1 CI=\frac{\lambda_{\max}-n}{n-1} CI=n−1λmax−n- λmax\lambda_{\max}λmax 为判断矩阵 AAA 的最大特征值
-
②查找相应的平均随机一致性指标 RIRIRI
nnn 1 2 3 4 5 6 7 8 9 RIRIRI 0.00 0.00 0.58 0.90 1.12 1.24 1.32 1.41 1.45 -
③计算一致性比例 CRCRCR
CR=CIRI CR=\frac{CI}{RI} CR=RICI
当 CR<0.10CR < 0.10CR<0.10 时,认为判断矩阵的一致性是可以接受的,否则应对判断矩阵 AAA 作适当修正。
4 层次总排序及一致性检验
层次总排序
在进行决策方案选择时,需要根据最低层中各个决策方案对最高层中决策目标的排序权值进行选择。为了得到最低层的层次总排序权值,需要自顶向下地对权值进行合成,合成步骤如下:
当前层(BBB 层)有 nnn 个因素 B1,B2,...,BnB_1,B_2,...,B_nB1,B2,...,Bn,相对 BBB 层的更高一层 AAA 层有 mmm 个因素 A1,A2,...,AmA_1,A_2,...,A_mA1,A2,...,Am,因素 AjA_jAj 的层次总排序权值为 aja_jaj ,因素 BiB_iBi 对因素 AjA_jAj 的层次单排序权值为 bijb_{ij}bij,则因素 BiB_iBi 的层次总排序权值 bib_ibi 为
bi=∑j=1majbij(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)
- 可能出现因素 BjB_jBj 与因素 AiA_iAi 无关联的情况,这时 bij=0b_{ij}=0bij=0
- 相对最高层的更低一层中,各因素的层次总排序权值即为层次单排序权值
对层次总排序的一致性检验
在对 Aj−BA_j-BAj−B 之间的判断矩阵 B(j)B^{(j)}B(j) 一致性检验中求得一致性指标 CIjCI_jCIj,相应的平均随机一致性指标为 RIjRI_jRIj,则 BBB 层总排序的一致性比例为
CR=∑j=1mCIjaj∑j=1mRIjaj
CR=\frac{\displaystyle\sum_{j=1}^mCI_ja_j}{\displaystyle\sum_{j=1}^mRI_ja_j}
CR=j=1∑mRIjajj=1∑mCIjaj
- 因为可能出现因素 BjB_jBj 与因素 AiA_iAi 无关联的情况,所以 RIjRI_jRIj 不为定值
当 CR<0.10CR < 0.10CR<0.10 时,认为 BBB 层的层次总排序结果具有较满意的一致性并接受该分析结果。
# 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()