python 實現熵權法確定各指標的權重
熵權法是一種客觀賦權方法,計算步驟如下:
a.構建各年份各評價指標的判斷矩陣:
b.將判斷矩陣進行歸一化處理, 得到歸一化判斷矩陣:
c.根據熵的定義,根據各年份評價指標,可以確定評價指標的熵。
d.定義熵權。定義了第n個指標的熵後,可得到第n個指標的熵權。
f.計算系統的權重值.
要求表格形式
表格整理格式如下,但是下面的代碼中沒有設置不讀取第一列,所以需刪除第一列的名稱(此列爲字符串格式,不能列入計算範圍)
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
@author: xiaosu
"""
import pandas as pd
import numpy as np
import math
from numpy import array
# 1讀取數據
df = pd.read_excel('表格名.xlsx', encoding='gb2312')
# 2數據預處理 ,去除空值的記錄
df.dropna()
#定義熵值法函數
def cal_weight(x):
'''熵值法計算變量的權重'''
# 標準化
x = x.apply(lambda x: ((x - np.min(x)) / (np.max(x) - np.min(x))))
'''
如果數據實際不爲零,則賦予最小值
if x==0:
x=0.00001
else:
pass
'''
# 求k
rows = x.index.size # 行
cols = x.columns.size # 列
k = 1.0 / math.log(rows)
lnf = [[None] * cols for i in range(rows)]
# 矩陣計算--
# 信息熵
x = array(x)
lnf = [[None] * cols for i in range(rows)]
lnf = array(lnf)
for i in range(0, rows):
for j in range(0, cols):
if x[i][j] == 0:
lnfij = 0.0
else:
p = x[i][j] / x.sum(axis=0)[j]
lnfij = math.log(p) * p * (-k)
lnf[i][j] = lnfij
lnf = pd.DataFrame(lnf)
E = lnf
# 計算冗餘度
d = 1 - E.sum(axis=0)
# 計算各指標的權重
w = [[None] * 1 for i in range(cols)]
for j in range(0, cols):
wj = d[j] / sum(d)
w[j] = wj
# 計算各樣本的綜合得分,用最原始的數據
w = pd.DataFrame(w)
return w
if __name__ == '__main__':
# 計算df各字段的權重
w = cal_weight(df) # 調用cal_weight
w.index = df.columns
w.columns = ['weight']
print(w) #輸出權重
print('熵權法計算權重運行完成!')
數據計算結果如下圖:(只是部分截圖)
關於程序中的部分說明:
1.本文中所用的是 min-max標準化(Min-Max Normalization)
2.遇到負向指標: 歸一化是將數據變成0-1之間的小數,將有量綱變成無量綱。所以負向指標中的數據提前加上負號(但是計算出來的權重可能不是小於零的)(本人涉及不深,今後會逐步補充完善)
3.關於負向指標的標準化,貌似有不同的計算中(印象中),再看到就加進去