目录
1.层次分析法
层次分析法(AHP)是对一些较为复杂、较为模糊的问题作出决策的简易方法,它适用于那些难以完全定量分析的问题。
2.模型原理
应用AHP分析决策问题时,首先要把问题条理化、层次化,构造出一个有层次的结构模型。
- 最高层:这一层只有一个元素,一般是分析问题的预定目标或理想结果,因此也称为目标层。
- 中间层:即为实现目标所涉及的中间环节,可由若干层次组成,包括所需考虑的准则、子准则,因此也称为准则层。
- 最底层:即为实现目标可供选择的各种措施、决策方案等,因此也称为措施层或方案层。
3.建模步骤
1)建立递阶层次结构模型。
2)构造出各层次中的所有判断矩阵。
3)一致性检验。
4)求权重后进行评价。
4.建模步骤详解
4.1 建立递阶层次结构模型(如上图)
4.2 构造出各层次中的所有判断矩阵
1)对指标的重要性进行两两比较,构造判断矩阵,从而科学求出权重。
2)矩阵中元素的意思是第i个指标相对第j个指标的重要程度。大于1,i重要;小于1,j重要。
* 又因两两比较的过程中忽略了其他因素,导致最后的结果可能出现矛盾,如下图中 颜值 < 作品质量,
颜值 > 作品数量,由上面两个式子可以
作品质量 > 作品数量,但又
作品质量 < 作品数量,所以矛盾。这时,我们需要进行一致性检验。
粉丝数 | 颜值 | 作品质量 | 作品数量 | |
粉丝数 | 1 | 2 | 3 | 5 |
颜值 | 1/2 | 1 | 1/2 | 2 |
作品质量 | 1/3 | 2 | 1 | 1/2 |
作品数量 | 1/5 | 1/2 | 2 | 1 |
4.3 一致性检验
一致矩阵:
- 若矩阵中每个元素
且满足
,则称该矩阵为正互反矩阵。在层次分析法中,我们构造的判断矩阵均是正互反矩阵。
- 若正互反矩阵满足
,则称其为一致矩阵。
一致性检验原理:检验我们构造的判断矩阵和一致矩阵是否有太大差别。
一致性检验步骤:
1)计算一致性指标CI,其中
为最大特征值,n为矩阵阶数(即行和列数)
2)查找对应的平均随机一致性指标RI(会查表即可)
3)计算一致性比例CR
CR=0:判断矩阵为一致矩阵;CR0.1:判断矩阵一致;CR
0.1:判断矩阵不一致。
4.4 求权重(代码部分会有具体介绍)
①算术平均法
②几何平均法
③特征值法
4.5 评价
综合评分=权重1*因素1+权重2*因素2+......+权重n*因素n
5.案例代码实现
对以上表格内的数据进行一致性检验:
import numpy as np
def calculate_cr(matrix):
# 计算特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(matrix)
# 获取最大特征值
max_eigenvalue = max(eigenvalues)
# 矩阵阶数
n = matrix.shape[0]
# 计算一致性指标 CI
CI = (max_eigenvalue - n) / (n - 1)
# 随机一致性指标 RI 表
RI_values = {1: 0.00, 2: 0.00, 3: 0.58, 4: 0.90, 5: 1.12, 6: 1.24, 7: 1.32, 8: 1.41, 9: 1.45, 10: 1.49}
RI = RI_values[n]
# 计算一致性比率 CR
CR = CI / RI
return max_eigenvalue, n, CI, RI, CR
# 判断矩阵
A = np.array([
[1, 2, 3, 5],
[1/2, 1, 1/2, 2],
[1/3, 2, 1, 1/2],
[1/5, 1/2, 2, 1]
])
# 计算并打印最大特征值、阶数、CI、RI 和 CR
max_eigenvalue, n, CI, RI, CR = calculate_cr(A)
print(f"最大特征值 (λ_max): {max_eigenvalue.real}")
print(f"矩阵阶数 (n): {n}")
print(f"一致性指标 (CI): {CI.real}")
print(f"随机一致性指标 (RI): {RI}")
print(f"一致性比率 (CR): {CR.real}")
可以发现CR0.1,需修改判断矩阵,这里我们把作品质量与作品数量的值(矛盾的值)进行对换,得到修改后的判断矩阵,数据如下:
粉丝数 | 颜值 | 作品质量 | 作品数量 | |
粉丝数 | 1 | 2 | 3 | 5 |
颜值 | 1/2 | 1 | 1/2 | 2 |
作品质量 | 1/3 | 2 | 1 | 2 |
作品数量 | 1/5 | 1/2 | 1/2 | 1 |
再次对修改后的判断矩阵进行一致性检验,代码和上面一样,只需把判断矩阵的数据改一下就可以了,得出结果如下,可以发现CR0.1,判断矩阵一致:
接下来,就可以求权重了:
1)算术平均法求权重:
import numpy as np
# 定义判断矩阵A
A=np.array([[1,2,3,5],[1/2,1,1/2,2],[1/3,2,1,2],[1/5,1/2,1/2,1]])
# 计算每列的和
# axis=0 表示按列计算总和,axis=1 表示按行计算总和
ASum=np.sum(A,axis=0)
# 获取A的行和列
n=A.shape[0]
# 归一化,二维数组除以一维数组,会自动将一维数组扩展为与二维数组相同的形状,然后进行逐个元素的除法运算
Stand_A=A/ASum
# 各列相加到同一行
ASumr=np.sum(Stand_A,axis=1)
# 计算权重向量
weights=ASumr/n
print(weights)
2)几何平均法求权重
import numpy as np
# 定义判断矩阵A
A=np.array([[1,2,3,5],[1/2,1,1/2,2],[1/3,2,1,2],[1/5,1/2,1/2,1]])
# 获取A的行和列
n=A.shape[0]
# 将A中每一行元素相乘得到一列矩阵
# np.prod 函数可以计算一维数组中所有元素的乘积
# 在二维数组中,axis=0 表示按列计算乘积,axis=1 表示按行计算乘积。
prod_A=np.prod(A,axis=1)
# 将新的向量的每个分量开n次方等价求1/n次方
# np.power用于对数组中的元素进行幂运算
prod_n_A=np.power(prod_A,1/n)
# 归一化处理
re_prod_A=prod_n_A/np.sum(prod_n_A)
# 展示权重结果
print(re_prod_A)
3)特征值法求权重
import numpy as np
# 定义判断矩阵A
A=np.array([[1,2,3,5],[1/2,1,1/2,2],[1/3,2,1,2],[1/5,1/2,1/2,1]])
# 获取A的行和列
n=A.shape[0]
# 求出特征值和特征向量
eig_values,eig_vectors=np.linalg.eig(A)
# 找出最大特征值的索引,np.argmax 用于返回数组中最大值的索引
max_index=np.argmax(eig_values)
# 找出对应的特征向量
max_vector=eig_vectors[:,max_index]
# 对特征向量进行归一化处理,得到权重
weights=max_vector/np.sum(max_vector)
# 输出权重
print(weights)
求完权重之后,就可以进行评分了:
这里选择特征值法:综合评分=0.493*粉丝数+0.179*颜值+0.230*作品质量+0.097*作品数量。最后比较每个明星的综合评分就可以做出决策了。
PS:可以思考一下实际求解时如果需要修改判断矩阵,如何知道需要修改哪里。(提示:这里可以通过比较原始判断矩阵与一致性矩阵,计算它们之间的偏差,从而找到偏差最大的元素对进行调整)