熵值法是指用来判断某个指标的离散程度的数学方法。离散程度越大,该指标对综合评价的影响越大。可以用熵值判断某个指标的离散程度。熵值法是一种客观赋权方法,借鉴了信息熵思想,它通过计算指标的信息熵,根据指标的相对变化程度对系统整体的影响来决定指标的权重。
熵值法是一种常用的多指标综合评价方法,它可以将多个指标的数据进行综合分析,得出一个综合评价结果。熵值法的作用非常广泛,可以应用于各种领域,如企业管理、环境评价、投资决策等。
熵值法与层次分析法(AHP)对比,是属于客观评价,而层次分析法是主观评价。除了熵值法,还可以使用主成分分析法、因子分析法等统计方法来确定权重。需要注意的是,无论使用哪种方法确定权重,都应结合实际情况和指标性质进行综合考虑,并进行敏感性分析,以确定所选择的权重是否合理可靠。
在信息论中,熵是对不确定性的一种度量。信息量越大,不确定性就越小,熵也就越小;信息量越小,不确定性越大,熵也越大。根据熵的特性,我们可以通过计算熵值来判断一个事件的随机性及无序程度,也可以用熵值来判断某个指标的离散程度,指标的离散程度越大,该指标对综合评价的影响越大(权重越大,熵值越小)。
设有 m m m个待评方案, n n n项评价指标,形成原始指标数据矩阵 X = ( X i j ) m × n X=(X_{ij})_{m \times n} X=(Xij)m×n,对于某项指标 X j X_j Xj,指标值 X i j X_{ij} Xij的差距越大,则该指标在综合评价中所起的作用越大;如果某项指标的指标值全部相等,则该指标在综合评价中不起作用。
设有 n n n个样本, m m m个评价指标,形成原始数据矩阵:
A = ( X 11 … X 1 m ⋮ ⋮ ⋮ X n 1 … X n m ) A=\begin{pmatrix} X_{11} & \dots & X_{1m} \\ \vdots & \vdots & \vdots \\ X_{n1} & \dots & X_{nm} \end{pmatrix} A= X11⋮Xn1…⋮…X1m⋮Xnm
其中, X i j 为第 X_{ij}为第 Xij为第i 个方案第 个方案第 个方案第j$指标的数值。
由于熵值法计算采用的是各个方案某一指标占同一指标值总和的比值,因此不存在量纲的影响,一般不需要进行标准化处理,若数据中有负数,就需要对数据进行非负化处理!此外,为了避免求熵值时对数的无意义,需要进行数据平移,乃至于标准化处理。
对于正向指标:
y i j = X i j − m i n ( X i j ) m a x ( X i j ) − m i n ( X i j ) y_{ij}=\frac{X_{ij}-min(X_{ij})}{max(X_{ij})-min(X_{ij})} yij=max(Xij)−min(Xij)Xij−min(Xij)
对于负向指标:
y i j = m a x ( X i j ) − X i j m a x ( X i j ) − m i n ( X i j ) y_{ij}=\frac{max(X_{ij})-X_{ij}}{max(X_{ij})-min(X_{ij})} yij=max(Xij)−min(Xij)max(Xij)−Xij
对于中性指标:
y i j = { X i j − m i n ( X i j ) m a x ( X i j ) − m i n ( X i j ) , X i j < m e a n ( X i j ) m a x ( X i j ) − X i j m a x ( X i j ) − m i n ( X i j ) , X i j ≥ m e a n ( X i j ) y_{ij}=\left\{\begin{matrix} \frac{X_{ij}-min(X_{ij})}{max(X_{ij})-min(X_{ij})}, &X_{ij}
上式中, y i j y_{ij} yij代表无量纲化后数据,经过无量纲化的数据都落到了 [ 0 , 1 ] [0,1] [0,1]区间, y i j y_{ij} yij值越大,说明评价结果越高。
由于部分数据在无量纲化处理后为零或负值,为了便面在熵值求权数时取对数无意义,需要对数据进行处理。这里采取平移法。
Z i j = y i j + 1 ( i = 1 , 2 , . . . m ; j = 1 , 2 , . . . n ) Z_{ij}=y_{ij}+1 (i=1,2,...m;j=1,2,...n) Zij=yij+1(i=1,2,...m;j=1,2,...n)
计算第 j j j项指标下第 i i i个方案中占该指标的比重。
p i j = Z i j ∑ i = 1 m Z i j , ( i = 1 , 2 , . . . m ; j = 1 , 2 , . . . n ) p_{ij}=\frac{Z_{ij}}{\sum_{i=1}^{m}Z_{ij}},(i=1,2,...m;j=1,2,...n) pij=∑i=1mZijZij,(i=1,2,...m;j=1,2,...n)
熵值的计算公式如下:
E i = − 1 ln ( n ) ∑ j = 1 n p i j ln p i j E_i = -\frac{1}{\ln(n)} \sum_{j=1}^n p_{ij} \ln p_{ij} Ei=−ln(n)1∑j=1npijlnpij
其中, p i j p_{ij} pij 表示第 i i i 个因素在第 j j j 个数据点中的数值。
计算出各个因素的熵值之后,我们可以进一步计算其权重。权重的计算公式如下:
W i = 1 − E i ∑ j = 1 n ( 1 − E j ) W_i = \frac{1-E_i}{\sum_{j=1}^n(1-E_j)} Wi=∑j=1n(1−Ej)1−Ei
其中, n n n 表示因素的数量。
import pandas as pd
import numpy as np
# 正向指标
def set_Standard(data):
y = (data - data.min(axis=0))/(data.max(axis=0)-data.min(axis=0))
return y
def set_Standards(data, positive=None, negative=None, middle=None):
row = data.shape[0]
col = data.shape[1]
data_max = data.max(axis=0)
data_min = data.min(axis=0)
data_mean = data.mean(axis=0)
data_maxmin = data_max - data_min
y = np.zeros((row, col),dtype='float32')
if positive==None and negative==None and middle==None:
# 默认为正向指标,越大越好
y = (data - data_min)/data_maxmin
# 正向
if positive!=None:
for j in positive:
for i in range(row):
y[i,j] = (data[i,j] - data_min[j])/data_maxmin[j]
# 负向
if negative!=None:
for j in negative:
for i in range(row):
y[i,j] = (data_max[j] - data[i,j])/data_maxmin[j]
# 中性
if middle!=None:
do = True
if do:
for j in middle:
for i in range(row):
if data[i,j] > data_mean[j]:
y[i,j] = (data[i,j] - data_min[j])/data_maxmin[j]
else:
data[i,j] = (data_max[j] - data[i,j])/data_maxmin[j]
else:
for j in middle:
for i in range(row):
y[i,j] = data[i,j]
return y
# 计算熵值,得到权重
def get_weights(data, positive=None, negative=None, middle=None):
"""
输入数据data,标准化后采用熵值法计算权重,综合得分以及排序位置
"""
data = np.array(data)
y = set_Standards(data, positive, negative, middle)
#print(y)
# 平移,避免0
z = y + 1e-10
#print(z)
# 计算指标值占比
w = z/sum(z)
# 计算熵值
k = 1/np.log(y.shape[0])
e = -k*(w*np.log(w)).sum(axis=0)
Wi = (1 - e)/sum(1 - e)
print('weights', Wi)
score = np.matmul(np.array(data), Wi)
print('score', score)
index = sorted(score, reverse=True)
#print(index)
# 输出名次结果
sor = [index.index(score[l]) + 1 for l in range(len(index))]
print('sort ',sor)
results = {}
results['weights'] = list(Wi)
results['score'] = list(score)
results['pos'] = sor
print(results)
return str(results)
if __name__ == '__main__':
data = pd.DataFrame({'指标1': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
'指标2': [2, 4, 6, 8, 10, 2, 4, 6, 8, 10],
'指标3': [1, 2, 1, 3, 2, 1, 3, 2, 3, 1],
'指标4': [3, 1, 2, 3, 5, 8, 7, 8, 8, 9]
})
df = np.array(data)
get_weights(df, positive=[0, 1, 2], negative=[3], middle=None)
运行结果:
weights [0.16859554 0.21985199 0.37852868 0.2330238 ]
score [1.68589962 2.20668019 2.66947483 4.26785551 4.96367395 3.69399634
4.82632941 5.28912404 6.27595223 6.36021818]
sort [10, 9, 8, 6, 4, 7, 5, 3, 2, 1]
参考:
forxtz. python 基于熵值法进行综合评价. 博客园. 2021.05
洋洋菜鸟. 熵权法 —— python. CSDN博客. 2022.01