我们在进行综合评价的时候需要确定每个指标的权重,权重设置的差异会导致出现完全不同的评价结果,然而权重的确定是一个令人头疼的事情。权重的确定方法主要可以分成三大类,主观赋权以及客观赋权,以及主客观相结合的方式。这里我们不讨论各种方式的优缺点,以及各种方法的理论,直接使用代码实现三大类方法各一种
层次分析法(AHP)
## 层次分析法权重计算
def AHP(A):
A=A
#step:计算特征值和对应的特征向量
A_lambda,A_vector=np.linalg.eig(A)
#step2:获取对他的特征值
A_maxlambda=max(A_lambda).real.round(4)
#step3:获取对打特征值的索引号
A_index=np.argmax(A_lambda)
#step4:获取最大特征值对应的特征向量
A_maxvector=A_vector[:,A_index].real.round(4)
# step5: 特征值法求权重
A_weight=A_maxvector/A_maxvector.sum()
# 进行一致性检验
RI_list = [0, 0, 0.58 , 0.90, 1.12, 1.24, 1.32, 1.41, 1.45]
A_CI=(A_maxlambda-A.shape[0])/(A.shape[0]-1)
A_RI=RI_list[A.shape[0]-1]
A_CR=A_CI/RI_list[A.shape[0]-1]
if A_CR<0.1 :
print('CR值为',A_CR,' 小于0.1 通过一致性检验')
return A_weight,A_maxlambda
else:
print('CR值为',A_CR,' 未通过一致性检验')
熵值法
import math
from numpy import array
# 定义熵值法确定权重
def cla_entry_weight(data):
x=data
#求k
rows=x.index.size # 行
cols=x.columns.size # 列
k=1.0/math.log(rows)
lnf = [[None] * cols for i in range(rows)]
#矩阵计算
#信息熵
x = array(x)
lnf = [[None] * cols for i in range(rows)]
lnf = array(lnf)
for i in range(0, rows):
for j in range(0, cols):
if x[i][j] == 0:
lnfij = 0.0
else:
p = x[i][j] / x.sum(axis=0)[j]
lnfij = math.log(p) * p * (-k)
lnf[i][j] = lnfij
lnf = pd.DataFrame(lnf)
E = lnf
# 计算冗余度
d = 1 - E.sum(axis=0)
# 计算各指标的权重
w = [[None] * 1 for i in range(cols)]
for j in range(0, cols):
wj = d[j] / sum(d)
w[j] = wj
# 计算各样本的综合得分,用最原始的数据
w=pd.DataFrame(w)
return w
博弈论
import pandas as pd
import numpy as np
#层次分析法获取权重
w1=np.array([[0.1675,0.06,0.025,0.345,0.105,0.105,0.195]])
#熵值法获取权重
w2=np.array([0.344,0,0.074,0.184,0.096,0,0.302])
def game_throry(w1,w2):
'''
w1:方法1计算的权重
w2:方法2计算的权重
d1:博弈论中w1的占比
d2:博弈论中w2的占比
w:计算结果
'''
w1=w1
w2=w2
w1_T=w1.T
w2_T=w2.T
AA=w1.dot(w1_T).reshape(1)
BB=w1.dot(w2_T).reshape(1)
CC=w2.dot(w1_T).reshape(1)
DD=w2.dot(w2_T).reshape(1)
mm=np.array([[AA,BB],[CC,DD]]).reshape(2,2)
Y=np.concatenate((AA,DD)).reshape(2,1)
re=np.linalg.solve(mm,Y)
d1=re[0]/(re.sum())
d2=re[1]/(re.sum())
w=w1*d1+w2*d2
return d1,d2,w