一、模型介绍
熵权法是一种通过对已知数据的处理,从而获得影响因子权重的方法,其基本思路是根据指标变异性的大小来确定客观权重。
熵权法的优点在于其根据各项指标指标值的变异程度来确定指标权数的,是一种客观赋权法,避免了人为因素带来的偏差。相对那些主观赋值法,精度较高客观性更强,能够更好的解释所得到的结果。
熵权法的缺点在于忽略了指标本身重要程度,有时确定的权重会与预期的结果相差甚远,同时熵值法不能减少评价指标的维数,也就是熵权法符合数学规律具有严格的数学意义,但往往会忽视决策者主观的意图。并且如果指标值的变动很小或者很突然地变大变小,熵权法使用时会存在一定的局限。
二、基本思路与步骤
(1)指标正向化
不同的指标代表含义不一样,有的指标越大越好,称为正向指标;有的指标越小越好,称为负向指标;而有些指标在某个点或者区间是最好的,称为适度指标。为方便评价,应把所有指标进行同向化处理。
正向指标:
负向指标:
适度指标:
(2)数据标准化
将指标按比例缩放,使它们落在特定的区间,从而可以去除量纲的影响,使得不同单位或者量级的指标能够进行比较、加权。
这里采用常用的离差标准化法对数据进行处理:
(3)计算信息熵
根据信息论中信息熵的定义,一组数据的信息熵计算公式为:
如果:
则:
(4)确定各指标的权重并计算得分
通过信息熵计算各指标的权重:
三、代码实现
数据表格式:
这里指标名后缀用Positive(正向指标)、Negative(负向指标)、Moderate(适度指标)来对指标类型进行标识。
Python代码如下:
import pandas as pdimport numpy as npimport re#定义文件读取方法def read_data(file):file_path=fileraw_data = pd.read_excel(file_path, header=0)#print(raw_data)return raw_data#定义数据正向化、标准化方法def data_normalization(data):data_nor=data.copy()columns_name=data_nor.columns.valuesfor i in range((len(columns_name)-1)):name=columns_name[i+1]#print(name)#正向指标直接标准化if ('Positive' in name)==True:max=data_nor[columns_name[i+1]].max()min=data_nor[columns_name[i+1]].min()data_nor[columns_name[i+1]]=(data_nor[columns_name[i+1]]-min)/(max-min)#print(data_nor[columns_name[i+1]])#负向指标先正向化、在标准化if ('Negative' in name)==True:max0=data_nor[columns_name[i+1]].max()data_nor[columns_name[i+1]]=(max0-data_nor[columns_name[i+1]])#正向化max=data_nor[columns_name[i+1]].max()min=data_nor[columns_name[i+1]].min()data_nor[columns_name[i+1]]=(data_nor[columns_name[i+1]]-min)/(max-min)#标准化#print(data_nor[columns_name[i+1]])#适度指标先正向化、在标准化if ('Moderate' in name)==True:try:val_range= re.search(r'.*[\((](.*),(.*)[\))]',name)val_down= float(val_range.group(1))val_up= float(val_range.group(2))val_op=(val_up+val_down)/2except:val_range= re.search(r'.*[\((](.*)[\))]',name)val_op= float(val_range.group(1))#print(val_op)data_nor[columns_name[i + 1]] = 1-(abs(data_nor[columns_name[i + 1]]-val_op)/(abs(data_nor[columns_name[i + 1]]-val_op).max()))#正向化max=data_nor[columns_name[i+1]].max()min=data_nor[columns_name[i+1]].min()data_nor[columns_name[i+1]]=(data_nor[columns_name[i+1]]-min)/(max-min)#标准化#print(data_nor[columns_name[i+1]])#print(data_nor)return data_nor#定义计算熵权方法def entropy_weight(data_nor):columns_name=data_nor.columns.valuesn=data_nor.shape[0]E=[]for i in columns_name[1:]:#计算信息熵#print(i)data_nor[i]=data_nor[i]/sum(data_nor[i])data_nor[i]=data_nor[i]*np.log(data_nor[i])data_nor[i]=data_nor[i].where(data_nor[i].notnull(),0)#print(data_nor[i])Ei=(-1)/(np.log(n))*sum(data_nor[i])E.append(Ei)#print(E)#计算权重W=[]for i in E:wi=(1-i)/((len(columns_name)-1)-sum(E))W.append(wi)#print(W)return W#计算得分def entropy_score(data,w):data_s=data.copy()columns_name=data_s.columns.valuesfor i in range((len(columns_name)-1)):name=columns_name[i+1]data_s[name]=data_s[name]*w[i]return data_sfile='data.xls'#声明数据文件地址data=read_data(file)#读取数据文件data_nor=data_normalization(data)#数据标准化、正向化,生成标准化后的数据data_norW=entropy_weight(data_nor)#计算熵权权重data_s=entropy_score(data,W)#计算赋权后的得分,使用原数据计算data_nor_s=entropy_score(data_nor,W)W.insert(0,'熵权法权重')#将结果保存为csvW0=pd.DataFrame(W).Tdata_s.to_csv('熵权法得分结果(原始数据).csv',index=0)W0.to_csv('熵权法得分结果(原始数据).csv', mode='a', header=False,index=0)data_nor_s.to_csv('熵权法得分结果(标准化数据).csv',index=0)W0.to_csv('熵权法得分结果(标准化数据).csv', mode='a', header=False,index=0)