层次分析法Python实现
I. 理论基础
-
建立层次结构模型
结构模型包括目标层 O O O、准则层 A = { a 1 , a 2 , … , a n } A=\{a_1,a_2,\ldots,a_n\} A={a1,a2,…,an}、方案层 B = { b 1 , b 2 , … , b m } B=\{b_1,b_2,\ldots,b_m\} B={b1,b2,…,bm};
-
构建判断(成对比较)矩阵
M a t r i x A = [ r 1 , 1 r 1 , 2 … r 1 , n r 2 , 1 r 2 , 2 … r 2 , n ⋮ ⋮ ⋱ ⋮ r n , 1 r n , 2 … r n , n ] Matrix_A = \left[ \begin{matrix} r_{1,1} & r_{1,2} & \ldots & r_{1,n} \\ r_{2,1} & r_{2,2} & \ldots & r_{2,n} \\ \vdots & \vdots & \ddots & \vdots \\ r_{n,1} & r_{n,2} & \ldots & r_{n,n} \\ \end{matrix} \right] MatrixA= r1,1r2,1⋮rn,1r1,2r2,2⋮rn,2……⋱…r1,nr2,n⋮rn,n
其中, r i , j = 1 r j , i r_{i,j}=\frac{1}{r_{j,i}} ri,j=rj,i1, r i , i = 1 r_{i,i}=1 ri,i=1
-
层次单排序与一致性检验
3.1 计算权重
(1)若采用均值法计算权重,则首先计算列归一化矩阵:
N o m a l i z e M a t r i x A = [ n r 1 , 1 n r 1 , 2 … n r 1 , n n r 2 , 1 n r 2 , 2 … n r 2 , n ⋮ ⋮ ⋱ ⋮ n r n , 1 n r n , 2 … n r n , n ] NomalizeMatrix_A = \left[ \begin{matrix} nr_{1,1} & nr_{1,2} & \ldots & nr_{1,n} \\ nr_{2,1} & nr_{2,2} & \ldots & nr_{2,n} \\ \vdots & \vdots & \ddots & \vdots \\ nr_{n,1} & nr_{n,2} & \ldots & nr_{n,n} \\ \end{matrix} \right] NomalizeMatrixA= nr1,1nr2,1⋮nrn,1nr1,2nr2,2⋮nrn,2……⋱…nr1,nnr2,n⋮nrn,n
其中, n r i , j = r i , j S j , S j = ∑ i = 1 n r i , j , j = 1 , 2 , … , n nr_{i,j}=\frac{r_{i,j}}{S_j},S_{j}=\sum_{i=1}^n{r_{i,j}},j=1,2,\ldots,n nri,j=Sjri,j,Sj=∑i=1nri,j,j=1,2,…,n然后再计算权重,为:
W = { w 1 , w 2 , … , w n } W=\{w_1,w_2,\ldots,w_n\} W={w1,w2,…,wn}
其中, w i = ∑ j = 1 n n r i , j n , i = 1 , 2 , … , n w_i=\frac{\sum_{j=1}^n{nr_{i,j}}}{n},i=1,2,\ldots,n wi=n∑j=1nnri,j,i=1,2,…,n(2)若采用几何法计算权重,则首先按行求积,再计算1/n次幂,计算公式为:
w i = ∏ j = 1 n r i , j n , i = 1 , 2 , … , n w_{i} = \sqrt[n]{\prod_{j=1}^{n}r_{i,j}},i=1,2,\ldots,n wi=nj=1∏nri,j,i=1,2,…,n然后再对各权重进行归一化处理,计算如下:
w i ‾ = w i ∑ i = 1 n w i \overline{w_{i}} = \frac{w_i}{\sum_{i=1}^{n}w_i} wi=∑i=1nwiwi
W = { w 1 ‾ , w 2 ‾ , … , w n ‾ } W=\{\overline{w_{1}},\overline{w_{2}},\ldots,\overline{w_{n}}\} W={w1,w2,…,wn}
3.2 计算判断矩阵特征根
(1) 计算加权矩阵
W
e
i
g
h
t
M
a
t
r
i
x
A
=
[
w
r
1
,
1
w
r
1
,
2
…
w
r
1
,
n
w
r
2
,
1
w
r
2
,
2
…
w
r
2
,
n
⋮
⋮
⋱
⋮
w
r
n
,
1
w
r
n
,
2
…
w
r
n
,
n
]
WeightMatrix_A = \left[ \begin{matrix} wr_{1,1} & wr_{1,2} & \ldots & wr_{1,n} \\ wr_{2,1} & wr_{2,2} & \ldots & wr_{2,n} \\ \vdots & \vdots & \ddots & \vdots \\ wr_{n,1} & wr_{n,2} & \ldots & wr_{n,n} \\ \end{matrix} \right]
WeightMatrixA=
wr1,1wr2,1⋮wrn,1wr1,2wr2,2⋮wrn,2……⋱…wr1,nwr2,n⋮wrn,n
其中,
w
r
i
,
j
=
r
i
,
j
×
w
j
,
j
=
1
,
2
,
…
,
n
wr_{i,j}=r_{i,j}\times{w_j},j=1,2,\ldots,n
wri,j=ri,j×wj,j=1,2,…,n
(2) 对加权矩阵按行求和,然后再除以权重,从而得到特征根向量
λ
=
{
∑
j
=
1
n
w
r
1
,
j
w
1
,
∑
j
=
1
n
w
r
2
,
j
w
2
,
…
,
∑
j
=
1
n
w
r
n
,
j
w
n
}
\lambda = \{\frac{\sum_{j=1}^{n}wr_{1,j}}{w_1},\frac{\sum_{j=1}^{n}wr_{2,j}}{w_2},\ldots,\frac{\sum_{j=1}^{n}wr_{n,j}}{w_n}\}
λ={w1∑j=1nwr1,j,w2∑j=1nwr2,j,…,wn∑j=1nwrn,j}
- 计算一致性指标CI值
C I = λ m a x − n n − 1 CI = \frac{\lambda_{max}-n}{n-1} CI=n−1λmax−n
其中, C I = 0 CI=0 CI=0表示判断矩阵完全一致, C I CI CI越大,判断矩阵的不一致性程度越严重。
-
根据CI和RI值求解CR值,判断其一致性是否通过
Satty模拟1000次得到的随机一致性指标RI取值如下表所示:
矩阵阶数n | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
RI | 0 | 0 | 0.58 | 0.90 | 1.12 | 1.24 | 1.32 | 1.41 | 1.45 | 1.49 | 1.51 | 1.54 | 1.56 |
C
R
=
C
I
R
I
CR = \frac{CI}{RI}
CR=RICI
当
C
R
<
0.1
CR\lt0.1
CR<0.1,表明判断矩阵
A
A
A的一致性程度被认为在容忍范围内,此时可用
A
A
A的特征向量开展权向量计算;若
C
R
≥
0.1
CR\geq0.1
CR≥0.1,则应考虑对判断矩阵
A
A
A进行修正。
-
计算方案层到指标层的权重
6.1 建立方案层到指标层的各个方案在每一个指标的两两对比矩阵:
B k = [ b 1 , 1 k b 1 , 2 k … b 1 , m k b 2 , 1 k b 2 , 2 k … b 2 , m k ⋮ ⋮ ⋱ ⋮ b m , 1 k b m , 2 k … b m , m k ] , k = 1 , 2 , … , m B^k=\left[ \begin{matrix} b_{1,1}^k & b_{1,2}^k & \ldots & b_{1,m}^k \\ b_{2,1}^k & b_{2,2}^k & \ldots & b_{2,m}^k \\ \vdots & \vdots & \ddots & \vdots \\ b_{m,1}^k & b_{m,2}^k & \ldots & b_{m,m}^k \\ \end {matrix} \right] ,k=1,2,\ldots,m Bk= b1,1kb2,1k⋮bm,1kb1,2kb2,2k⋮bm,2k……⋱…b1,mkb2,mk⋮bm,mk ,k=1,2,…,m6.2 按照上述操作,计算各个方案的权重
V k = { v k , 1 , v k , 2 , … , v k , m } , k = 1 , 2 , … , m V_k=\{v_{k,1},v_{k,2},\ldots,v_{k,m}\},k=1,2,\ldots,m Vk={vk,1,vk,2,…,vk,m},k=1,2,…,m最终得到方案到指标的权重矩阵
V = [ v 1 , 1 v 1 , 2 … v 1 , m v 2 , 1 v 2 , 2 … v 2 , m ⋮ ⋮ ⋱ ⋮ v n , 1 v n , 2 … v n , m ] V=\left[ \begin{matrix} v_{1,1} & v_{1,2} & \ldots & v_{1,m} \\ v_{2,1} & v_{2,2} & \ldots & v_{2,m} \\ \vdots & \vdots & \ddots & \vdots \\ v_{n,1} & v_{n,2} & \ldots & v_{n,m} \\ \end {matrix} \right] V= v1,1v2,1⋮vn,1v1,2v2,2⋮vn,2……⋱…v1,mv2,m⋮vn,m
6.3 进行层次总排序一致性判断
C I i = λ m a x i − n n − 1 , i = 1 , 2 , … , n CI_{i}=\frac{\lambda_{max}^i-n}{n-1},i=1,2,\ldots,n CIi=n−1λmaxi−n,i=1,2,…,n
C R = w 1 C I 1 + w 2 C I 2 + … + w n C I n w 1 R I 1 + w 2 R I 2 + … + w n R I n = ∑ i = 1 n w i C I i ∑ i = 1 n w k R I i = C I R I CR = \frac{w_{1}CI_{1}+w_{2}CI_{2}+\ldots+w_{n}CI_{n}}{w_{1}RI_{1}+w_{2}RI_{2}+\ldots+w_{n}RI_{n}}=\frac{\sum_{i=1}^{n}w_{i}CI_{i}}{\sum_{i=1}^{n}w_{k}RI_{i}}=\frac{CI}{RI} CR=w1RI1+w2RI2+…+wnRInw1CI1+w2CI2+…+wnCIn=∑i=1nwkRIi∑i=1nwiCIi=RICI
- 计算各个方案的综合评分结果
S L k = ∑ i = 1 n w i v i , k , k = 1 , 2 , … , m SL_k = \sum_{i=1}^{n}w_{i}v_{i,k},k=1,2,\ldots,m SLk=i=1∑nwivi,k,k=1,2,…,m
参考文献
Thomas L. Saaty. How to make a decision: The Analytic Hierarchy Process. European Journal of Operation Research,19990,48,9-26.
II. 实现流程
AHP实现流程如下:
III. Python
import numpy as np
from functools import reduce
def ahp_method(dataset, wd = 'm'):
# 随机一致性指标R.I.(inc_rat)
inc_rat = np.array([0, 0, 0, 0.58, 0.9, 1.12, 1.24, 1.32, 1.41, 1.45, 1.49, 1.51, 1.48, 1.56, 1.57, 1.59])
# 数据深复制
X = np.copy(dataset)
# 生成权重向量
weights = np.zeros(X.shape[1])
# 根据权重计算方法来确定各个权重
if (wd == 'm' or wd == 'mean'): #均值
weights = np.mean(X/np.sum(X, axis = 0), axis = 1)
elif (wd == 'g' or wd == 'geometric'): #几何
for i in range (0, X.shape[1]):
weights[i] = reduce( (lambda x, y: x * y), X[i,:])**(1/X.shape[1])
weights = weights/np.sum(weights)
# 计算特征根向量
vector = np.sum(X*weights, axis = 1)/weights
# 获得平均特征根
lamb_max = np.mean(vector)
# 计算一致性指标
cons_ind = (lamb_max - X.shape[1])/(X.shape[1] - 1)
# 一致性判断
rc = cons_ind/inc_rat[X.shape[1]]
return weights, rc
IV. 测试
案例参考[https://zhuanlan.zhihu.com/p/448412538]
指标层包括:景色( A 1 A_1 A1)、费用( A 2 A_2 A2)、住宿( A 3 A_3 A3)、饮食( A 4 A_4 A4)、交通( A 5 A_5 A5)
方案层包括:苏杭( B 1 B_1 B1)、北戴河( B 2 B_2 B2)、桂林( B 3 B_3 B3)
通过专家打分以及构建以下判断矩阵:
判断矩阵A:
景色 | 费用 | 住宿 | 饮食 | 交通 | |
---|---|---|---|---|---|
景色 | 1 | 5 | 5 | 1 3 \frac{1}{3} 31 | 8 |
费用 | 1 5 \frac{1}{5} 51 | 1 | 1 4 \frac{1}{4} 41 | 1 6 \frac{1}{6} 61 | 2 |
住宿 | 1 5 \frac{1}{5} 51 | 4 | 1 | 1 5 \frac{1}{5} 51 | 3 |
饮食 | 3 | 6 | 5 | 1 | 6 |
交通 | 1 8 \frac{1}{8} 81 | 1 2 \frac{1}{2} 21 | 1 3 \frac{1}{3} 31 | 1 6 \frac{1}{6} 61 | 1 |
得分矩阵分别为:
A 1 = [ 1 2 5 1 2 1 2 1 5 1 2 1 ] , A 2 = [ 1 1 3 1 8 3 1 1 3 8 3 1 ] , A 3 = [ 1 1 3 1 1 3 1 3 1 3 1 ] , A 4 = [ 1 1 3 4 1 3 1 1 1 4 1 1 ] , A 5 = [ 1 1 1 4 1 1 1 4 4 4 1 ] A_{1}=\left[ \begin{matrix} 1 & 2 & 5 \\ \frac{1}{2} & 1 & 2 \\ \frac{1}{5} & \frac{1}{2} & 1 \\ \end{matrix} \right] ,A_{2}=\left[ \begin{matrix} 1 & \frac{1}{3} & \frac{1}{8} \\ 3 & 1 & \frac{1}{3} \\ 8 & 3 & 1 \\ \end{matrix} \right] ,A_{3}=\left[ \begin{matrix} 1 & 1 & 3 \\ 1 & 1 & 3 \\ \frac{1}{3} & \frac{1}{3} & 1 \\ \end{matrix} \right] ,A_{4}=\left[ \begin{matrix} 1 & \frac{1}{3} & 4 \\ \frac{1}{3} & 1 & 1 \\ \frac{1}{4} & 1 & 1 \\ \end{matrix} \right] ,A_{5}=\left[ \begin{matrix} 1 & 1 & \frac{1}{4} \\ 1 & 1 & \frac{1}{4} \\ 4 & 4 & 1 \\ \end{matrix} \right] A1= 121512121521 ,A2= 138311381311 ,A3= 11311131331 ,A4= 131413111411 ,A5= 11411441411
测试代码:
##
A = np.array([
[1,5,5,1/3,8],
[1/5,1,1/4,1/6,2],
[1/5,4,1,1/5,3],
[3,6,5,1,6],
[1/8,1/2,1/3,1/6,1],
])
A_1 = np.array([
[1,2,5],
[1/2,1,2],
[1/5,1/2,1],
])
A_2 = np.array([
[1,1/3,1/8],
[3,1,1/3],
[8,3,1],
])
A_3 = np.array([
[1,1,3],
[1,1,3],
[1/3,1/3,1],
])
A_4 = np.array([
[1,1/3,4],
[1/3,1,1],
[1/4,1,1],
])
A_5 = np.array([
[1,1,1/4],
[1,1,1/4],
[4,4,1],
])
# 计算权重和RI
weight_A,RC_A = ahp_method(A)
print('A的权重为:',weight_A)
print('A的RC为:',RC_A)
print()
weight_A1, RC_A1 = ahp_method(A_1)
weight_A2, RC_A2 = ahp_method(A_2)
weight_A3, RC_A3 = ahp_method(A_3)
weight_A4, RC_A4 = ahp_method(A_4)
weight_A5, RC_A5 = ahp_method(A_5)
print('A1的权重为:',weight_A1)
print('A1的RC为:',RC_A1)
print('A2的权重为:',weight_A2)
print('A2的RC为:',RC_A2)
print('A3的权重为:',weight_A3)
print('A3的RC为:',RC_A3)
print('A4的权重为:',weight_A4)
print('A4的RC为:',RC_A4)
print('A5的权重为:',weight_A5)
print('A5的RC为:',RC_A5)
## 构建V矩阵
V = np.vstack((weight_A1,weight_A2,weight_A3,weight_A4,weight_A5))
print(V)
scores = np.matmul(weight_A,V)
print('综合评分为:',score
测试结果:
A的权重为: [0.30685018 0.06313468 0.12601939 0.45879775 0.04519801]
A的RC为: 0.09521589663079191
A1的权重为: [0.59488796 0.27661064 0.1285014 ]
A1的RC为: 0.004774741975367846
A2的权重为: [0.08199023 0.23644689 0.68156288]
A2的RC为: 0.0013293778439305783
A3的权重为: [0.42857143 0.42857143 0.14285714]
A3的RC为: 0.0
A4的权重为: [0.48036759 0.26858814 0.25104428]
A4的RC为: -0.18508347602743516
A5的权重为: [0.16666667 0.16666667 0.66666667]
A5的RC为: 0.0
[[0.59488796 0.27661064 0.1285014 ]
[0.08199023 0.23644689 0.68156288]
[0.42857143 0.42857143 0.14285714]
[0.48036759 0.26858814 0.25104428]
[0.16666667 0.16666667 0.66666667]]
综合评分为: [0.46965078 0.28457497 0.24577426]