一、层次分析法简介
层次分析法(AHP),是指将与决策总是有关的元素分解成目标、准则、方案等层次,在此基础之上进行定性和定量分析的决策方法。该方法是美国运筹学家匹茨堡大学教授萨蒂于20世纪70年代初,在为美国国防部研究"根据各个工业部门对国家福利的贡献大小而进行电力分配"课题时,应用网络系统理论和多目标综合评价方法,提出的一种层次权重决策分析方法。
层次分析法应用过程中,通常的操作步骤主要包括四个:第一步是目标、准则、方案等层次结构模型的构建;第二步构造判断矩阵来衡量准则间的相对权重;第三步为层次单排序及其一致性检验,这步即为对指标定权;第四步为层次总排序及其一致性检验。
二、层次分析法具体流程
1. 构建层次结构模型
假设我们要给b站几名知名百大up主进行排名,下面几位知名up主的数据表
我们的目标层是确定五位up主的名次,准则层是依据粉丝数,最高播放量、获赞数和稿件数这四种指标来衡量,方案层是指对五位up主进行数据分析
2. 归一化处理
从上面四种指标的表格数据可以明显看出,指标间的数量级有所差别,为了更好地统一指标的数据进行比较,我们需要对每个指标下的数据进行归一化处理,即求第i行第j列数据的占第j列数据和的比 a i j a_{ij} aij
a i j = x i j / ∑ i = 1 4 x i j a_{ij} = x_{ij} / \sum_{i=1}^4x_{ij} aij=xij/i=1∑4xij
在将同指标数据进行归一化处理后就会得到下表数据
3. 判断矩阵确定权重
归一化处理得到每位up主各项指标的数据后,我们需要确定每项指标的权重,再通过将指标权重与指标数据的乘积加和来确定最终评分,那关键的一步就来了,如何更加客观科学地衡量各项指标的权重呢?这也是层次分析法比较重要的一步,这里我们需要用到判断矩阵。
判断矩阵的方法,是通过两两比较评价因子的重要性来确定因子间的相对权重,最后一次性确定所有因子的权重求得该层次的各元素对上一层次某元素的优先权重,最后再加权和的方法递阶归并各备择方案对总目标的最终权重,有效规避了各种评价指标的权重难以确定的问题
矩阵中的每个权重值是行指标相对列指标的相对权重,且主对角线的权重值互为倒数,这里的相对权重我们设为 w i j w_{ij} wij
w
i
j
=
w
i
/
w
j
w_{ij} = w_{i} / w_{j}
wij=wi/wj
w
i
j
=
1
/
w
j
i
w_{ij} = 1 / w_{ji}
wij=1/wji
我们认为粉丝数比最重要,最高播放量比稿件数重要一点,获赞数比最高播放量重要一点,最后列出来下表,然后就来到最重要一步:一致性检验
4. 一致性检验
层次分析法的难点就在于一致性检验,一致性检验主要是为了解决因子间比较不一致的问题,即我们在考虑指标间的相对权重时往往会忽视其他指标间的相互关系。其实我们在设定判断矩阵的相对权重时也是主观的,难以达到严格的一致矩阵。
一致性矩阵是满足关系式 a i j = a i k a k j , ∀ i , j , k = { 1 , 2 , . . . , n } a_{ij} = a_{ik} a_{kj},{\forall}i,j,k = \lbrace1,2,...,n\rbrace aij=aikakj,∀i,j,k={1,2,...,n}的正反矩阵称为一致性矩阵,一般情况下我们只需要进行一致性检验,使判断矩阵接近一致矩阵即可。
进行一致性检验要先求矩阵的最大特征值 λ m a x \lambda_{max} λmax,最大特征值和其特征向量在机器学习中应用广泛,其关系有点像在有阻力的情况下你往哪个方向才能走出最快的速度
C
I
=
λ
m
a
x
−
n
n
−
1
CI = \frac{\lambda_{max}-n}{n-1}
CI=n−1λmax−n
C
R
=
C
I
R
I
CR = \frac{CI}{RI}
CR=RICI
一致性检验得到 CR 后,当 CR<0.10 时,改矩阵与一致性矩阵相近,可以接受,否则该矩阵应该适当修改参数以通过一致性检验。
5. 加权求和排名
得到通过一致性检验的判断矩阵后,我们直接按列算出该指标与其他行指标相对列指标的权重和的占比后按行一一相加就能得到该指标的最终权值,最后将指标权重与指标数据的乘积加和得到每位up主的最终评分即可确定排名
三、Python实现层次分析法
使用Python的pandas库创建DataFrame对象来导入数据,然后按流程将原始数据归一化,构造判断矩阵和进行一致性检验,其中需要用到numpy的线性代数库来算特征值,下面呈上代码
import numpy as np
import pandas as pd
#以万为单位的数据
arr1 = ["老番茄","何同学","木鱼水心","凉风Kaze","罗翔说刑法"]
arr2 = ["粉丝数","最高播放量","获赞数","稿件数"]
arr3 = [[1686,3182,12000,0.0397],[903,1916,3439,0.0043],[837,817,4748,0.1159],[824,1296,12000,0.0442],[2110,1465,6199,0.0228]]
#归一化函数
def func1(arr3,arr2,arr1):
data = pd.DataFrame(arr3,columns=arr2,index = arr1)
data_together = pd.DataFrame(np.zeros(20).reshape(5,4),columns=arr2,index=arr1)
for i in arr1:
for j in arr2:
data_together.at[i,j] = data.at[i,j]/data[j].sum()
return(data_together)
data_together=func1(arr3,arr2,arr1)
print(data_together)
print('\n')
#写好的判断矩阵
Matrix = [[1, 2, 3, 5], [1 / 2, 1, 1 / 2, 2], [1 / 3, 2, 1, 2], [1 / 5, 1 / 2, 1 / 2, 1]]
#最大特征值函数
def func2(Matrix):
M = np.array(Matrix) # 自己构造的判别矩阵
w = np.linalg.eig(M) # np.linalg.eig(matri)返回特征值和特征向量
value_max = np.max(w[0]) # 最大特征值
t = np.argwhere(w[0] == value_max) # 寻找最大特征值所在的行和列
vector_max = w[1][::-1, t[0]]# 最大特征值对应的特征向量
return (value_max)
data_value_max=func2(Matrix)
print(data_value_max)
print('\n')
#一致性检验
def func3(Matrix,value_max):
RI_list = [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]
M = np.array(Matrix)
n = M.shape[0]
RI = RI_list[n]
CI = (value_max - n) / (n - 1)
CR = CI / RI
print(CR)
if CR < 0.1:
print("通过一致性检验")
print('\n')
else:
print("没有通过一致性检验")
func3(Matrix,data_value_max)
#综合权重计算函数
def func4(Matrix):
M = np.array(Matrix)
S = M.shape
M_p = np.zeros(S[0]*S[1]).reshape(S[0],S[1])
M_add = np.zeros(S[0]).reshape(S[0],1)
for n in range(S[0]):
for m in range(S[1]):
M_p[n][m] = M[n][m]/M[:,m].sum() #按列算出该指标与其他行指标相对列指标的权重和的占比
print(M_p)
print('\n')
for k in range(S[0]):
M_add[k][0] = M_p[k,:].sum()/S[1] #按行算出综合权重
print(M_add)
print('\n')
return(M_add)
Matrix_add = func4(Matrix)
data = np.array(data_together)
grade = pd.DataFrame(np.dot(data,Matrix_add), columns = ["总评分"], index = [arr1]) #最终评分表
print(grade)
#/usr/bin/python3.8 /home/ljm/PycharmProject/pythoncode1/code4.py
粉丝数 最高播放量 获赞数 稿件数
老番茄 0.265094 0.366759 0.312614 0.174967
何同学 0.141981 0.220839 0.089590 0.018951
木鱼水心 0.131604 0.094168 0.123691 0.510798
凉风Kaze 0.129560 0.149378 0.312614 0.194799
罗翔说刑法 0.331761 0.168857 0.161491 0.100485
(4.112830038192152+0j)
(0.033580368509569136+0j)
通过一致性检验
[[0.49180328 0.36363636 0.6 0.5 ]
[0.24590164 0.18181818 0.1 0.2 ]
[0.16393443 0.36363636 0.2 0.2 ]
[0.09836066 0.09090909 0.1 0.1 ]]
[[0.48885991]
[0.18192996]
[0.2318927 ]
[0.09731744]]
总评分
老番茄 0.285839
何同学 0.132206
木鱼水心 0.159860
凉风Kaze 0.181963
罗翔说刑法 0.240132
#Process finished with exit code 0
总结
以上就是层次分析法学习笔记的内容,本文仅仅简单介绍了层次分析法的使用流程。层次分析法在数学建模中应用广泛,虽然它有自己的不足例如判断矩阵较为主观,最后的综合权重也带有主观性,但层次分析法非常适合评价类问题。当然如果我们定义的指标不同也会有不同结果,所以层次分析并无定论,不同的剖析问题的角度会给我们带来异样的惊喜!