理论
在解决如何确定指标重要性问题的过程中,往往要考虑到各级指标的权重,而权重确定的方法也有很多,例如经常被使用的层次分析法、主成分分析法、灰色关联法等,但是很多方法都受到实际问题中数据量不够、主观成分较大等问题的限制。
熵权法可用信息论的基本原理来解释,信息是用来测量系统的有序程度,熵则是用来测量系统的无序程度;根据信息熵的定义,对于某项指标,可以用熵值来判断某个指标的离散程度,并且信息熵值越小,指标的离散程度(无须程度)越大,该指标对综合评价的影响(即权重)就越大,如果某项指标的值全部相等,则该指标在综合评价中不起作用。所以,我们可以充分利用信息熵来计算各个指标的权重,为具有多个指标的综合评价提供依据。
相比较于其他的综合评价方法,熵权法是一种客观赋权法,可以直接根据各项指标的观测值提供的信息量大小,即指标的变异程度,来确定指标权重,避免了人为因素带来的误差,相较于主观赋权法具有较高的可信度和精确度。
第一步:数据标准化
通过pandas读取数据,看看原始数据的本来面目,再根据数据的正向性(越大越好)或负向性(越小越好)进行0-1标准化,注意标准化的方法有很多,此处使用的标准化方法并不是唯一的,也不一定是最好的,标准化的方法要根据实际情况选择相对合理的。可以参考这篇文章的三种标准化方法。sklearn库三种标准化与反标准化方法介绍-CSDN博客
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
datas=pd.read_excel(r'层次分析法所用指标.xlsx')
datas=datas.iloc[:,:-2]
datas.set_index(datas.columns.tolist()[0], inplace=True)#把第一列(时间列)作为索引
datas
注意:此处指标中只有利润率是效益性指标(越大越好),其余指标均是成本型指标(最小越好)
#数据标准化
columns=datas.columns.tolist()#列名用列表形式表示,方便读取
#正向指标标准化
for col in columns[:1]:
datas[col]=(datas[col]-datas[col].min())/(datas[col].max()-datas[col].min())#x=(x-最小值)/(最大值-最小值)
datas[col]=datas[col]/datas[col].sum()#x/一列总和
#负向指标标准化
for col in columns[1:]:
datas[col]=(datas[col].max()-datas[col])/(datas[col].max()-datas[col].min())#x=(最大值-x)/(最大值-最小值)
datas[col]=datas[col]/datas[col].sum()#x/一列总和
datas=datas.replace({0.000000:0.00000001})#此处把0值用一个极小值代替,可避免后续0作为分母报错
datas
第二步:计算每个指标的信息熵e
n=len(datas[columns[0]].tolist())#数据长度
E=[]#用于存储每个指标的e(信息熵)值
for col in columns:
num=0
for p in datas[col].tolist():
num+=p*np.log(p)
E.append((-1/np.log(n))*num)
E
第三步:计算权重
d=1-pd.Series(E,name='权重',index=columns)#信息效用值
w=d/d.sum()#权重
w
第四步:加权计算每一年的得分
S=P*W
W=np.array(w).reshape(6,1)#数组化,便于矩阵相乘
P=np.array(datas.values.tolist()) #每一行代表一个对象的指标评分
score=np.dot(P,W) #矩阵相乘
score=score*4+1#把结果整体扩大,便于观察差异
score
最后我们画个折线图看一下趋势:
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.plot([x for x in range(2012,2022)],list(score),marker='o')
plt.title('南京市2012-2021年土地价值指数评价')
plt.xlabel('年份')
plt.ylabel('土地价值指数')
plt.grid()
Python完整代码如下:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
datas=pd.read_excel(r'层次分析法所用指标.xlsx')
datas=datas.iloc[:,:-2]
datas.set_index(datas.columns.tolist()[0], inplace=True)#把第一列(时间列)作为索引
##数据标准化
columns=datas.columns.tolist()#列名用列表形式表示,方便读取
#正向指标标准化
for col in columns[:1]:
datas[col]=(datas[col]-datas[col].min())/(datas[col].max()-datas[col].min())#x=(x-最小值)/(最大值-最小值)
datas[col]=datas[col]/datas[col].sum()#x/一列总和
#负向指标标准化
for col in columns[1:]:
datas[col]=(datas[col].max()-datas[col])/(datas[col].max()-datas[col].min())#x=(最大值-x)/(最大值-最小值)
datas[col]=datas[col]/datas[col].sum()#x/一列总和
datas=datas.replace({0.000000:0.00000001})#此处把0值用一个极小值代替,可避免后续0作为分母报错
##熵权法
n=len(datas[columns[0]].tolist())#数据长度
E=[]#用于存储每个指标的e(信息熵)值
for col in columns:
num=0
for p in datas[col].tolist():
num+=p*np.log(p)
E.append((-1/np.log(n))*num)
d=1-pd.Series(E,name='权重',index=columns)#信息效用值
w=d/d.sum()#权重
##计算加权后的指标得分
W=np.array(w).reshape(6,1)#数组化,便于矩阵相乘
P=np.array(datas.values.tolist()) #每一行代表一个对象的指标评分
score=np.dot(P,W) #矩阵相乘
score=score*4+1#把结果整体扩大,便于观察差异
##可视化
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.plot([x for x in range(2012,2022)],list(score),marker='o')
plt.title('南京市2012-2021年土地价值指数评价')
plt.xlabel('年份')
plt.ylabel('土地价值指数')
plt.grid()
熵权法是常用的权重计算方法,但是针对指标很多,维度很多的复杂指标体系,熵权法可能效果一般,所以评价类方法解决复杂问题的往往会用熵权法+云模型、熵权-突变级数法、熵权法+层次分析法等组合方法,后续会用同样的数据介绍其他的评价类方法,例如云模型、主成分分析法等。
需要数据的点赞收藏,评论区说一声即可。