【建模算法】层次分析法(Python实现)
01 算法用途
在很多情况下,我们对事物评价,应该要多维度评价。多维度评价之后我们要如何把它们合并成一个指标用于比较事物的好坏呢,这时候需要对各个指标赋权, 层次分析法就是用来赋权重的了。
这个方法主观性比较强,在数据集比较小,实在不好比较的时候可以用这个方法,如果有别的选择还是尽量不要用这个算法比较好。可以看下以往建模获奖论文,此算法的出现频率还是挺高的,所以存在即有它存在的道理。
02 建模案例
小美要选男朋友了,现有小明、小李两个人选,到底该选谁呢?现在小美要从四个指标去选择,分别是身高、颜值、学历、性格。小美对他们各个指标的评分如下:
这也太难抉择了吧!!
03 原理解析
step1:小美查阅图书资料,选择依据如下:
step2:小美开始构造判断矩阵
小美的主观判断:
1.身高与颜值相比,身高稍重要
2.身高与学历相比,同样重要
3.身高和性格相比,性格稍重要
4.颜值和学历相比,学历介于相同重要和稍微重要之间
5.颜值和性格相比,性格明显重要
6.性格和学历相比,性格稍重
身高 | 颜值 | 学历 | 性格 | |
---|---|---|---|---|
身高 | 1 | 3 | 1 | 1/3 |
颜值 | 1/3 | 1 | 1/2 | 1/5 |
学历 | 1 | 2 | 1 | 1/3 |
性格 | 3 | 5 | 3 | 1 |
小美终于得到了判断矩阵。
step3:翻阅图书,小美找到检验标准
对判断矩阵的一致性检验的步骤如下:
- 计算一致性指标CI
查找相应的平均随机一致性指标RI,对n=1,…,9,Satty给出了RI的值如下表所示:
RI是通过随机方法构造500个样本矩阵,随机地从1~9及其例数中抽取数字构造正反矩阵,求最大特征根的平均值
λ
m
a
x
\lambda_{max}
λmax并定义
R
I
=
λ
m
a
x
−
n
n
−
1
RI=\frac{\lambda_{max}-n}{n-1}
RI=n−1λmax−n
- 计算一致性比例CR
C R = C I R I CR=\frac{CI}{RI} CR=RICI
当 CR<0.10时,一致性接受,否则该矩阵应该适当修改参数
step4 :计算权重以及得分
- 得到最大特征值对应特征向量
T = [ t 1 t 2 . . . t n ] T=[t_1\quad t_2\quad ...\quad t_n] T=[t1t2...tn]
- 得到权重向量
W = [ w 1 w 2 . . . w n ] w i = t i ∑ i = 1 n t i W=[w_1\quad w_2\quad ... \quad w_n]\\ w_i=\frac{t_i}{\displaystyle \sum^n_{i=1}t_i} W=[w1w2...wn]wi=i=1∑ntiti
- 小美对男嘉宾的评分为P,最后得分S
S = P × W S=P\times W S=P×W
真相大白,小明是最佳选择~得分如下
Python源码
#层次分析法完整代码:
import numpy as np
#计算特征向量和最大特征值
a=np.array([[1,3,1,1/3],[1/3,1,1/2,1/5],[1,2,1,1/3],[3,5,3,1]]) #a为自己构造的输入判别矩阵
w=np.linalg.eig(a) #np.linalg.eig(matri)返回特征值和特征向量
tzz=np.max(w[0]) #最大特征值
t=np.argwhere(w[0]==tzz) #寻找最大特征值所在的行和列
tzx=w[1][::-1,t[0]] #最大特征值对应的特征向量
#一致性检验
RILIST=[0,0,0.58,0.9,1.12,1.24,1.32,1.41,1.45,1.49,1.52,1.54,1.56,1.58,1.59]
n=a.shape[0]
RI=RILIST[n]
CI=(tzz-n)/(n-1)
CR=CI/RI
print(CR)
print("通过一致性检验") if CR<0.1 else print("没有通过一致性检验")
P=np.array([[8,7,6,8],[7,8,8,7]]) #每一行代表一个对象的指标评分
#赋权重
quan=np.zeros((n,1));
quan=tzx/sum(tzx)
Q=quan
#显示出所有评分对象的评分值
score=np.dot(P,Q) #矩阵乘法
for i in range(len(score)):
print('对象{:}得分={:}'.format(i+1,score[i,0].real))