文章目录
前言
善始者繁多,克终者盖寡。
确定评价系统中各评价指标权重的方法有很多,本人认为可以分为经验的方法、数学的方法和混合的方法三种类型,其中熵权法、离差最大化法是较为常用的确定评价指标权重的数学方法,在 熵权法计算评价指标权重——使用Python和Excel实现 一文中已经和大家分享了熵权法的实现方法,现在和各位分享使用离差最大化法计算评价指标权重的具体操作步骤。
**描述如果不当,还请指教!!!**
一、离差最大化
1.1 离差(deviation)
理解了“离差”就相当于已经掌握了离差最大化,剩下的就是具体操作的问题了。离差的详细描述参看百度百科离差。我们可以将离差理解为:
离差是观测值与真实值之间的差,反映了数据之间的离散程度。
离差的表示方式并不唯一,但通常以“距离”反映数据间的差异,距离大则差异大。
一维
对于一条线的两个点,离差可以表述为两点的差值;
当一条线上存在多个点时,离差可以表述为该点与所有点均值的差值。二维
对于平面上的两个点,离差可以表示为两点间的方差、标准差等;
当平面上存在多个点时,离差可以表述为该点与所有点均值的方差、标准差等。多维
从几何的角度看,离差可以表示为空间中不同点之间的距离。
1.2 离差最大化
离差最大化的思想是:
如果某个指标内数据的差异程度大,则其对系统最终的评估结果影响大,赋予该指标的权重也应当大。
举一个极端的例子,假设已经通过调查发现人的气质可能由身高、体重、年龄三个因素影响,现已收集到几位被试的数据。
从表中我们发现,11位被试的年龄相同,不论如何对“年龄”这个指标赋予权重,“年龄”对于各位被试最终得分的影响可以完全忽略;11位被试中身高的差异较大,体重的差异变化不明显,单凭借直觉我们就可以判断,“身高”对于最终得分的影响肯定大。
1.3 离差的计算
离差最大化计算权重的目标函数为:
j表示系统的第j个指标;
p(nj)、p(ij)分别表示系统中第j个指标中的第n、i个数据;
dev(p(nj),p(ij))表示第j列中两点的离差;
w(j)表示第j个指标的权重;
该目标函数表示的是j列下所有数据的离差和与指标权重的乘积
经过变换我们可以求得w(j)的最优解为:
j表示系统的第j个指标
w(j)表示第j个指标的权重;
k表示系统中指标的总个数
可以理解为第j个指标的权重等于该列离差和与所有指标离差和的比值
1.4 离差的表示
我们已经知道离差反映的是数据之间的差异程度,而且由很多种方式表示,那么我们应当如何选择呢?
最常用的方式是以“平均值”作为参照,计算各数据到平均值的离差,但是所有数据到平均值的离差的和为0(大家可以自行举例验证),也就是说如果选择每列属性的平均值作为参照计算该列的总离差,每列的总离差都为0,并不能够依此确定各指标的权重。
本文选择离差的表示方法为:
dev(p(ij))=max(j)-p(ij)
dev(p(ij))表示第j列第i个数据的离差;
max(j)表示第j列中元素的最大值;
p(ij)表示第j列第i个元素的值。
归一化后,可以将每个数据的离差理解为该数据到最大值1之间的距离,为了保证结果为正数,所有使用最大值减去当前元素的值。
二、Excel实现
假设已经通过调查得出人的气质由身高、体重、年龄三个因素影响,部分被试信息如图:
2.1 数据归一化
归一化的目的是消除量纲的影响。
选用极差法对数据进行归一化,其计算公式为:
ci表示第i个元素归一化后的值,取值范围为[0,1];
Xi表示第i个元素;
min(X)、max(X)表示当前指标中的最大、最小值。
以A2单元格为例,其计算公式为:
=(A2-MIN(A$2:A$6))/(MAX(A$2:A$6)-MIN(A$2:A$6))
归一化后数据变为:
2.2 计算各记录离差
以A2单元格为例,离差计算公式为:
=MAX(E$2:E$6)-E2
各单元格离差为:
依此计算出各指标(列)总离差,并计算其权重,以“身高”为例,其权重计算公式为:
=SUM(I2:I6)/SUM($I 2 : 2: 2:K$6)
计算后各指标权重如图所示,三指标权重和为1:
以第一条记录为例,其最终得分计算公式为:
=E2*$M 3 + F 2 ∗ 3+F2* 3+F2∗N 3 + G 2 ∗ 3+G2* 3+G2∗O$3
各记录归一化后的最终得分如图所示:
三、Python实现
3.1 读取数据文件
本人习惯将数据文件保存在“files”目录下,如果想将数据文件直接直接放在程序同级目录下,删除path变量即可。
filename = "示例离差最大化.xlsx"
path = "files/"
data = pandas.read_excel(path+filename,sheet_name=0)
#保留原始数据
data_yuanshi = data.copy()
print(data)
3.2 归一化数据
此处data当做一张二维表处理,sklearn中有实现归一化的模块也可以直接使用。
max = data.max()
min = data.min()
cols = data.columns
#归一化数据
for i in range(data.shape[0]):
for j in range(data.shape[1]):
data.iloc[i,j] = (float(data.iloc[i,j])-float(min[cols[j]]))/(float(max[cols[j]])-float(min[cols[j]]))
data_guiyi = data.copy()
data_quanzhong = data.copy()
print(data)
3.3 计算离差
根据1.4中提及的离差表示方法计算出每一列中每一个数据的离差。
#计算每一个单元格的离差
max_guiyi = data.max()
for i in range(data.shape[0]):
for j in range(data.shape[1]):
data.iloc[i,j] = float(max_guiyi[cols[j]])-float(data.iloc[i,j])
data_licha = data.copy()
print(data)
3.4 计算各指标权重
参照1.3中各指标权重计算公式,第j列指标权重等于该列指标离差和与所有指标离差和的比值。
#计算每一列的总离差并计算出权重
cols_licha = data.sum()
print(cols_licha)
sum_licha = cols_licha.sum()
print(sum_licha)
weight = []
for i in cols_licha:
weight.append(i/sum_licha)
print(weight)
3.5 计算最终得分
#计算各记录最终得分并另存文件(原始数据文件)
cores = []
for i in range(data_yuanshi.shape[0]):
result_core = 0
for j in range(data_yuanshi.shape[1]):
result_core += float(data_yuanshi.iloc[i,j])*weight[j]
cores.append(result_core)
print(cores)
data_yuanshi["最终评分"] = cores
print(data_yuanshi)
#计算各记录最终得分并另存文件(归一化数据文件)
cores2 = []
for i in range(data_guiyi.shape[0]):
result_core = 0
for j in range(data_guiyi.shape[1]):
result_core += float(data_guiyi.iloc[i,j])*weight[j]
cores2.append(result_core)
print(cores2)
data_guiyi["最终评分"] = cores2
print(data_guiyi)
3.6 保存文件
#保存文件
f1 = filename.split(".")[0]+"最终得分.xlsx"
f2 = filename.split(".")[0]+"归一化.xlsx"
f3 = filename.split(".")[0]+"权重.xlsx"
data_yuanshi.to_excel(path+f1,index=False)
data_guiyi.to_excel(path+f2,index=False)
data.to_excel(path+f3)
3.7 程序运行结果
程序运行后生成三个文件。
文件一在原始数据上计算了最终得分;
文件二在归一化数据上计算了最终得分;
文件三在归一化数据后添加了指标权重。
记录2归一化后得分高于记录5,但是原始数据的最终得分却低于记录5,这是由于原始记录中不同量纲的影响。