熵权法计算权重原理python实现
信息熵越大,信息量到底是越大還是越小?權重和信息熵的大小到底是正相關還是負相關?
網上有一些相反的說法。
有些說:熵越大,方差越大,包含的信息越多,權重越大。
另一些說:熵越小,不確定性越小,提供的信息越大,權重越大。
今天復盤一下熵權法計算權重的原理,并python實現。
文章目錄
- 熵權法計算權重原理
- 信息熵計算
- 熵權法計算
- 熵權悖論的解釋
- Python實現信息熵求權重
熵權法計算權重原理
信息熵計算
熵是對混亂程度的一種度量。混亂程度越大,熵就越大,包含的信息量越大;混亂程度越小,熵就越小,包含的信息量就越小。
計算公式:
這里的p是指標 j 中值為 i 的樣本數占總樣本數量的比例。
比如,共有2個樣本,當指標 j 取值分別為0,1,那么p(j=0)=1/2,p(j=1)=1/2,帶入公式可得e=1。
當2個樣本取值分別為1/2,1/2時,p只有一個,p(j=1/2)=1,帶入公式得e=0。
由此可知,方差越大,熵越大,包含的信息越多,權重應當越大。
那么,為什么會有一些地方說,熵越小,信息量越大,權重越大呢?
熵權法計算
這個問題要從熵權法計算權重的公式說起:
歸一化
對于不同量綱的指標比較信息熵顯然沒有意義,需要先進行歸一化。
同時,需要對負向指標正向化處理,處理后的指標均為正向指標。
計算熵值
需要注意的是,這里的p不再是每個取值的數量所占的比例,而是該取值的大小除以該指標所有取值的總和。
比如,共有2個樣本,當指標 j 取值分別為0,1,那么p1=0/(0+1),p2=1/(0+1),帶入公式可得e=0。
當2個樣本取值分別為1/2,1/2時,p1=1/2/(1/2+1/2)=1/2,p2=1/2/(1/2+1/2),帶入公式可得e=1。
計算信息熵冗余度(差異):
計算各項指標的權重:
計算各樣本的綜合得分:
注意,這里的xij是歸一化后的取值,即第一步的結果。
熵權悖論的解釋
由此可知,權重與信息熵冗余度d正相關,與信息熵e是負相關的。也就是說,方差越大,熵越小,包含的信息越多,權重應當越大。
這里與前面的結論相悖的原因就在于熵權法計算熵的公式中,p不是各取值的比例,而是各個取值的相對大小。公式不一樣,結論自然不一樣了。
Python實現信息熵求權重
import pandas as pd import numpy as np import mathdef nml(series): # 正向指標歸一化 減最小值的min-max方法l = []for i in series:l.append((i - series.min()) / (series.max() - series.min()))return pd.Series(l, name=series.name)def nml_max(series): #負向指標歸一化l = []for i in series:l.append((series.max() - i) / (series.max() - series.min()))return pd.Series(l, name=series.name)def nmlzt(df): #歸一化函數,對正負向指標分別調用nml()和nml_max()dfn = pd.DataFrame()for i in df.columns:if (i=='D'):dfn = pd.concat([dfn, nml_max(df[i])], axis=1)else:dfn = pd.concat([dfn, nml(df[i])], axis=1)# dfn為歸一化的數據return dfndef pij(df): #求信息熵公式中的p,這里直接用取值除以取值總和,而不是數量的比例D = df.copy()for i in range(D.shape[1]): # 列sum = D.iloc[:, i].sum()for j in range(D.shape[0]): # 行D.iloc[j, i] = D.iloc[j, i] / sum# 算pijreturn Ddef entropy(series): #計算信息熵_len = len(series)def ln(x):if x > 0:return math.log(x)else:return 0s = 0for i in series:s += i * ln(i)return -(1 / ln(_len)) * sdef _result(dfij): #求e、d、w并返回dfn = dfij.copy()w = pd.DataFrame(index=dfn.columns, dtype='float64')l = []for i in dfn.columns:l.append(entropy(dfn[i]))w['熵'] = lw['差異性系數'] = 1 - np.array(l)sum = w['差異性系數'].sum()l = []for i in w['差異性系數']:l.append(i / sum)w['權重'] = lreturn wdf = pd.read_csv('Blues_D.csv') #讀取你需要計算的文件 df=df[['D','GTI']] #選取需要計算的屬性列 dfn = nmlzt(df) #歸一化 dfij = pij(dfn) #求p w = _result(dfij) #求權重 w.to_excel('weight_info_entropy.xlsx', sheet_name='權重')#輸出結果 dfn = dfn.set_index(df.index, drop=True) print(dfn)總結
以上是生活随笔為你收集整理的熵权法计算权重原理python实现的全部內容,希望文章能夠幫你解決所遇到的問題。