熵值法是一种依据各指标值所包含的信息量的多少确定指标权重的客观赋权法,某个指标的熵越小,说明该指标值的变异程度越大,提供的信息量也就越多,在综合评价中起的作用越大,则该指标的权重也应越大。熵值法可单独进行综合评价;也可以与其他方法相结合,如层次分析法,用熵值法确定各指标的权重,然后运用层次分析法得到各个评价对象的综合得分。
1.熵值法的基本步骤
假设i(取值范围[1,m])表示评价对象,j(取值范围[1,n])表示评价指标。
- 指标标准化。
对于正向指标: x i j ′ = x i j − m i n ( x j ) m a x ( x j ) − m i n ( x j ) \mathop x\nolimits_{ij}^\prime = \frac{{\mathop x\nolimits_{ij} - min(\mathop x\nolimits_{j} )}}{{max(\mathop x\nolimits_{j} ) - min(\mathop x\nolimits_{j} ) }} xij′=max(xj)−min(xj)xij−min(xj)
对于反向向指标: x i j ′ = m a x ( x j ) − x i j m a x ( x j ) − m i n ( x j ) \mathop x\nolimits_{ij}^\prime = \frac{{max(\mathop x\nolimits_{j} )-\mathop x\nolimits_{ij}}}{{max(\mathop x\nolimits_{j} ) - min(\mathop x\nolimits_{j} ) }} xij′=max(xj)−min(xj)max(xj)−xij - 计算第i个研究对象下第j项指标的比重
p
i
j
p_{ij}
pij。
p i j = x i j ∑ i = 1 m x i j {p_{ij}} = \frac{{{x_{ij}}}}{{\sum\limits_{i = 1}^m {{x_{ij}}} }} pij=i=1∑mxijxij - 计算第j项指标的熵值
e
j
{e_j}
ej。
e j = − k ∑ i = 1 m p i j ln p i j {e_j} = - k\sum\limits_{i = 1}^m {{p_{ij}}} \ln {p_{ij}} ej=−ki=1∑mpijlnpij,其中 k = 1 ln m k = \frac{1}{{\ln m}} k=lnm1 - 计算第j项指标的差异系数
g
j
{g_j}
gj,差异系数越大越好,表示该指标对于研究对象所起的作用越大,该指标较好。
g j = 1 − e j {g_j} = 1 - {e_j} gj=1−ej - 给指标赋权,定义权重
w
j
{w_j}
wj。
w j = g j ∑ j = 1 n g j {w_j} = \frac{{{g_j}}}{{\sum\limits_{j = 1}^n {{g_j}} }} wj=j=1∑ngjgj - 通过权重计算样本评价值,第i个研究对象下第j项指标的评价值为:
F i j = a j x i j ′ {F_{ij}} = {a_j}{x_{ij}}^\prime Fij=ajxij′
则第i个研究对象的总体评价值为:
F i = ∑ j = 1 m F i j {F_i} = \sum\limits_{j = 1}^m {{F_{ij}}} Fi=j=1∑mFij
2.熵值法的应用示例
运用熵值法综合评价2015年贵州省各市州城市建设环境,选取指标为城市燃气普及率、城市用水普及率、人均城市道路面积、每万人拥有公共交通车辆、人均公园绿地面积、生活垃圾无害化处理率,下面截图来自《中国经济社会大数据研究平台》。
根据熵值及权重设定表得,6个指标的权重由大到小依次为城市燃气普及率、生活垃圾无害化处理率、人均公园绿地面积、城市用水普及率、人均城市道路面积、每万人拥有公共交通车辆,即城市燃气普及率对城市建设环境的影响最大。从评价结果可得,贵州省各市城市建设环境差距并不是很显著,宜居城市排序为贵阳市、毕节市、六盘水市、遵义市、仁怀市、清镇市、安顺市、兴义市、凯里市、都匀市、赤水市、铜仁市。其中贵阳市在城市燃气普及率和每万人拥有公共交通车辆上遥遥领先于其他各市,兴义市的人均城市道路面积最多,毕节市的人均公园绿地面积高于其他各市。各市生活垃圾无害化处理率都比较高,均超过了90%。
3.运用Python实现熵值法
- 读取数据
import numpy as np
import pandas as pd
##读取数据
data=pd.read_csv('data.csv',encoding='gb18030',index_col=0)
indicator=data.columns.tolist() ##指标个数
project=data.index.tolist() ##方案数、评价主体
value=data.values
print(indicator)
print(project)
print(value)
data.head()
- 数据标准化
###定义数据标准化函数。为了避免求熵值时对数无意义,对数据进行平移,对标准化后的数据统一加了常数0.001
def std_data(value,flag):
for i in range(len(indicator)):
print(flag[i])
if flag[i]=='+':
value[:,i]=(value[:,i]-np.min(value[:,i],axis=0))/(np.max(value[:,i],axis=0)-np.min(value[:,i],axis=0))+0.001
elif flag[i]=='-':
value[:,i]=(np.max(value[:,i],axis=0)-value[:,i])/(np.max(value[:,i],axis=0)-np.min(value[:,i],axis=0))+0.001
return value
##数据标准化
flag=["-","+","-","+","+","+"] ##表示指标为正向指标还是反向指标
std_value=std_data(value,flag)
std_value.round(3)
- 计算权重和综合得分
#定义熵值法函数、熵值法计算变量的权重
def cal_weight(indicator,project,value):
p= np.array([[0.0 for i in range(len(indicator))] for i in range(len(project))])
#print(p)
for i in range(len(indicator)):
p[:,i]=value[:,i]/np.sum(value[:,i],axis=0)
e=-1/np.log(len(project))*sum(p*np.log(p)) #计算熵值
g=1-e # 计算一致性程度
w=g/sum(g) #计算权重
return w
##结果
w=cal_weight(indicator,project,std_value)
w=pd.DataFrame(w,index=data.columns,columns=['权重'])
print("#######权重:#######")
print(w)
score=np.dot(std_value,w).round(2)
#print(score)
score=pd.DataFrame(score,index=data.index,columns=['综合得分']).sort_values(by =['综合得分'],ascending = False)
score
附:完整代码和案例数据请自行下载。
链接:https://pan.baidu.com/s/1ItC-IdJR-QqCWz0he64tPQ
提取码:100p
ps:初衷是通过撰写博文记录自己所学所用,实现知识的梳理与积累;将其分享,希望能够帮到面临同样困惑的小伙伴儿。如发现博文中存在问题,欢迎随时交流~~