熵權法是一種在綜合考慮各因素提供信息量的 基礎上計算一個綜合指標的數學方法。作為客觀綜合定權法,其主要根據各指標傳遞給決策者的信息量大小來確定權重。根據信息論基本原理,信息是系統有序程度的度量;而熵則是系統無序程度的度量。因此,可用系 統熵來反映其提供給決策者的信息量大小,系統熵可通過熵權法得到。
熵值法確定權重的基本步驟:
- 選取n個樣本,m個指標,則
為第i個樣本的第j個指標的數值(i=1, 2…, n; j=1,2,…, m);
-
指標的歸一化處理:異質指標同質化由於各項指標的計量單位並不統一,因此在用它們計算綜合指標前,先要對它們進行標准化處理,即把指標的絕對值轉化為相對值,並令
,從而解決各項不同質指標值的同質化問題。而且,由於正向指標(極大型指標)和負向指標(極小型指標)數值代表的含義不同(正向指標數值越高越好,負向指標數值越低越好),因此,對於高低指標我們用不同的算法進行數據標准化處理。其具體方法如下:
正向指標:負向指標:則為第 i個樣本的第 j個指標的數值( i=1, 2…, n; j=1, 2,…, m)。為了方便起見,歸一化后的數據仍記為
; 其他類型指標如下圖所示,在運行程序中有對應處理代碼。
3.計算第j項指標下第i個樣本占該指標的比重:
4.計算第j項指標的熵值:其中
. 滿足
;
5.計算信息熵冗余度:
6.計算各項指標的權值:
7. 計算各樣本的綜合得分:
運行代碼:
clc;clear; % 實現用熵值法求各指標(列)的權重及各數據行的得分 % x為原始數據矩陣, 一行代表一個樣本, 每列對應一個指標 % s返回各行得分, w返回各列權重 load('data_water_quality.mat')%載入數據 x=X; %X為工作表中的樣本數據 %% 數據的正向化處理 [n,m]=size(x); % X中有n個樣本, m個指標 disp(['共有' num2str(n) '個評價對象, ' num2str(m) '個評價指標']) Judge = input(['這' num2str(m) '個指標是否需要經過正向化處理,需要請輸入1 ,不需要輸入0: ']); if Judge == 1 Position = input('請輸入需要正向化處理的指標所在的列,例如第2、3、6三列需要處理,那么你需要輸入[2,3,6]: '); %[2,3,4] disp('請輸入需要處理的這些列的指標類型(1:極小型, 2:中間型, 3:區間型) ') Type = input('例如:第2列是極小型,第3列是區間型,第6列是中間型,就輸入[1,3,2]: '); %[2,1,3] % 注意,Position和Type是兩個同維度的行向量 for i = 1 : size(Position,2) %這里需要對這些列分別處理,因此我們需要知道一共要處理的次數,即循環的次數 X(:,Position(i)) = Positivization(X(:,Position(i)),Type(i),Position(i)); % Positivization是我們自己定義的函數,其作用是進行正向化,其一共接收三個參數 % 第一個參數是要正向化處理的那一列向量 B(:,Position(i)) X(:,n)表示取第n列的全部元素 % 第二個參數是對應的這一列的指標類型(1:極小型, 2:中間型, 3:區間型) % 第三個參數是告訴函數我們正在處理的是原始矩陣中的哪一列 % 該函數有一個返回值,它返回正向化之后的指標,我們可以將其直接賦值給我們原始要處理的那一列向量 end disp('正向化后的矩陣 X = ') disp(X) end %% 數據的歸一化處理 % Matlab2010b,2011a,b版本都有bug,需如下處理. 其它版本直接用[X,ps]=mapminmax(x',0,1);即可 [B,ps]=mapminmax(X'); ps.ymin=0.002; % 歸一化后的最小值 ps.ymax=0.996; % 歸一化后的最大值 ps.yrange=ps.ymax-ps.ymin; % 歸一化后的極差,若不調整該值, 則逆運算會出錯 B=mapminmax(X',ps); % mapminmax('reverse',xx,ps); % 反歸一化, 回到原數據 B=B'; % B為歸一化后的數據 %% 計算第j個指標下,第i個記錄占該指標的比重p(i,j) for i=1:n for j=1:m p(i,j)=B(i,j)/sum(X(:,j)); end end %% 計算第j個指標的熵值e(j) k=1/log(n); for j=1:m e(j)=-k*sum(p(:,j).*log(p(:,j))); end d=ones(1,m)-e; % 計算信息熵冗余度 w=d./sum(d); % 求權值w s=w*p'; % 求綜合得分[\code] disp("信息冗余度為");disp(d) disp("各樣本綜合得分s為");disp(s); disp("各指標權重w為");disp(w);
正向化函數代碼
(1)Positivization
% function [輸出變量] = 函數名稱(輸入變量) % 函數的中間部分都是函數體 % 函數的最后要用end結尾 % 輸出變量和輸入變量可以有多個,用逗號隔開 % function [a,b,c]=test(d,e,f) % a=d+e; % b=e+f; % c=f+d; % end % 自定義的函數要單獨放在一個m文件中,不可以直接放在主函數里面(和其他大多數語言不同) function [posit_x] = Positivization(x,type,i) % 輸入變量有三個: % x:需要正向化處理的指標對應的原始列向量 % type: 指標的類型(1:極小型, 2:中間型, 3:區間型) % i: 正在處理的是原始矩陣中的哪一列 % 輸出變量posit_x表示:正向化后的列向量 if type == 1 %極小型 disp(['第' num2str(i) '列是極小型,正在正向化'] ) posit_x = Min2Max(x); %調用Min2Max函數來正向化 disp(['第' num2str(i) '列極小型正向化處理完成'] ) disp('~~~~~~~~~~~~~~~~~~~~分界線~~~~~~~~~~~~~~~~~~~~') elseif type == 2 %中間型 disp(['第' num2str(i) '列是中間型'] ) best = input('請輸入最佳的那一個值: '); posit_x = Mid2Max(x,best); disp(['第' num2str(i) '列中間型正向化處理完成'] ) disp('~~~~~~~~~~~~~~~~~~~~分界線~~~~~~~~~~~~~~~~~~~~') elseif type == 3 %區間型 disp(['第' num2str(i) '列是區間型'] ) a = input('請輸入區間的下界: '); b = input('請輸入區間的上界: '); posit_x = Inter2Max(x,a,b); disp(['第' num2str(i) '列區間型正向化處理完成'] ) disp('~~~~~~~~~~~~~~~~~~~~分界線~~~~~~~~~~~~~~~~~~~~') else disp('沒有這種類型的指標,請檢查Type向量中是否有除了1、2、3之外的其他值') end end
(2)Inter2Max
function [posit_x] = Inter2Max(x,a,b) r_x = size(x,1); % row of x M = max([a-min(x),max(x)-b]); posit_x = zeros(r_x,1); %zeros函數用法: zeros(3) zeros(3,1) ones(3) % 初始化posit_x全為0 初始化的目的是節省處理時間 for i = 1: r_x if x(i) < a posit_x(i) = 1-(a-x(i))/M; elseif x(i) > b posit_x(i) = 1-(x(i)-b)/M; else posit_x(i) = 1; end end end
(3)Mid2Max
function [posit_x] = Mid2Max(x,best) M = max(abs(x-best)); posit_x = 1 - abs(x-best) / M; end
(4)Min2Max
function [posit_x] = Min2Max(x) posit_x = max(x) - x; %posit_x = 1 ./ x; %如果x全部都大於0,也可以這樣正向化 end
運行結果如下圖所示: