文章目錄
- TOPSIS法(優劣解距離法)介紹及 python3 實作
- 1 簡述
- 2 TOPSIS過程
-
- 2.1 名額屬性同向化,一般選擇名額正向化
-
- 2.1.1 極小型名額:期望名額值越小越好(如患病率、死亡率等)
- 2.1.2 中間型名額:期望名額值既不要太大也不要太小,适當取中間值最好(如水品質評估 PH 值)
- 2.1.3 區間型名額:期望名額的取值最好落在某一個确定的區間最好(如體溫)
- 2.2 構造歸一化初始矩陣
- 2.3 确定最優方案和最劣方案
- 2.4 計算各評價對象與最優方案、最劣方案的接近程度
- 2.5 計算各評價對象與最優方案的貼近程度Cj
- 2.6 根據Ci大小進行排序,給出評價結果
- 2.7 TOPSIS法算法程式
- 補充:不同的算法步驟MATLAB版本
-
- TOPSIS算法步驟
- 對應MATLAB程式
TOPSIS法(優劣解距離法)介紹及 python3 實作
轉載原文:
https://zhuanlan.zhihu.com/p/37738503
1 簡述
C.L.Hwang 和 K.Yoon 于1981年首次提出 TOPSIS (Technique for Order Preference by Similarity to an Ideal Solution)。TOPSIS 法是一種常用的組内綜合評價方法,能充分利用原始資料的資訊,其結果能精确地反映各評價方案之間的差距。基本過程為基于歸一化後的原始資料矩陣,采用餘弦法找出有限方案中的最優方案和最劣方案,然後分别計算各評價對象與最優方案和最劣方案間的距離,獲得各評價對象與最優方案的相對接近程度,以此作為評價優劣的依據。該方法對資料分布及樣本含量沒有嚴格限制,資料計算簡單易行。
通俗的例子:小明數學考試 134 分,要怎麼知道他的成績是好還是不好呢?
基于分布的評價方法會觀察小明的分數位于班級分數的哪個水準(如前 5%、前 10%),但這種評價方法隻能給出一個方向的情況。如班上成績除了最高分外,其餘都是 134 分,那麼小明的成績就是并列的倒數第一,但是正向評價給出的結果是前 5%。
而 TOPSIS 就是找出班上最高分(假設是 147 分)、最低分(假設是 69 分),然後計算小明的分數和這兩個分數之間的差距,進而得到自己分數好壞的一個客觀評價。距離最高分越近,那麼評價情況越好,距離最低分越近,那麼評價情況越糟。
2 TOPSIS過程
網上大部分資料對此部分均有描述,但不少資料與文獻原文存在較大偏差、排版較為混亂,并且沒有深入思考原理。此部分内容轉述外網文獻,并加入了筆者自己的了解。
2.1 名額屬性同向化,一般選擇名額正向化
TOPSIS 法使用距離尺度來度量樣本差距,使用距離尺度就需要對名額屬性進行同向化處理(若一個次元的資料越大越好,另一個次元的資料越小越好,會造成尺度混亂)。通常采用成本型名額向效益型名額轉化(即數值越大評價越高,事實上幾乎所有的評價方法都需要進行轉化),此外,如果需要使用雷達圖進行展示,建議此處将所有資料都變成正數。
2.1.1 極小型名額:期望名額值越小越好(如患病率、死亡率等)
M為名額 x可能取值的最大值
2.1.2 中間型名額:期望名額值既不要太大也不要太小,适當取中間值最好(如水品質評估 PH 值)
其中M為名額 x的可能取值的最大值, m為名額 x 的可能取值的最小值
2.1.3 區間型名額:期望名額的取值最好落在某一個确定的區間最好(如體溫)
其中 [a,b] 為名額 x的最佳穩定區間, [a*,b*] 為最大容忍區間
def dataDirection_1(datas, offset=0):
def normalization(data):
return 1 / (data + offset)
return list(map(normalization, datas))
def dataDirection_2(datas, x_min, x_max):
def normalization(data):
if data <= x_min or data >= x_max:
return 0
elif data > x_min and data < (x_min + x_max) / 2:
return 2 * (data - x_min) / (x_max - x_min)
elif data < x_max and data >= (x_min + x_max) / 2:
return 2 * (x_max - data) / (x_max - x_min)
return list(map(normalization, datas))
def dataDirection_3(datas, x_min, x_max, x_minimum, x_maximum):
def normalization(data):
if data >= x_min and data <= x_max:
return 1
elif data <= x_minimum or data >= x_maximum:
return 0
elif data > x_max and data < x_maximum:
return 1 - (data - x_max) / (x_maximum - x_max)
elif data < x_min and data > x_minimum:
return 1 - (x_min - data) / (x_min - x_minimum)
return list(map(normalization, datas))
2.2 構造歸一化初始矩陣
設共有 [公式] 個待評價對象,每個對象都有 [公式] 個名額(屬性),則原始資料矩陣構造為:
構造權重規範矩陣,屬性進行向量規範化,即每一列元素都除以目前列向量的範數(使用餘弦距離度量)
由此得到歸一化處理後的标準化矩陣 Z :
2.3 确定最優方案和最劣方案
最優方案Z+由 [Z中每列元素的最大值構成:
最劣方案 Z- 由 Z中每列元素的最小值構成:
2.4 計算各評價對象與最優方案、最劣方案的接近程度
其中 wj為第 j 個屬性的權重(重要程度),名額權重建議根據實際确定或使用專家評估方法。在本文第 4 部分也提供了兩種常用的确定權重的方法及簡要分析。
2.5 計算各評價對象與最優方案的貼近程度Cj
2.6 根據Ci大小進行排序,給出評價結果
2.7 TOPSIS法算法程式
使用的程式設計語言:python3.7.1 (Anaconda3)
使用的編輯器:Sublime Text 3
使用的子產品:pandas、numpy
import pandas as pd
import numpy as np
def topsis(data, weight=None):
# 歸一化
data = data / np.sqrt((data ** 2).sum())
# 最優最劣方案
Z = pd.DataFrame([data.min(), data.max()], index=['負理想解', '正理想解'])
# 距離
weight = entropyWeight(data) if weight is None else np.array(weight)
Result = data.copy()
Result['正理想解'] = np.sqrt(((data - Z.loc['正理想解']) ** 2 * weight).sum(axis=1))
Result['負理想解'] = np.sqrt(((data - Z.loc['負理想解']) ** 2 * weight).sum(axis=1))
# 綜合得分指數
Result['綜合得分指數'] = Result['負理想解'] / (Result['負理想解'] + Result['正理想解'])
Result['排序'] = Result.rank(ascending=False)['綜合得分指數']
return Result, Z, weight
topsis 函數需要輸入:
data:原始資料,pandas.DataFrame 類型
weight:權系數, 預設使用熵權法定權. 也可以傳入指定權重清單. (熵權法代碼見下文)
補充:不同的算法步驟MATLAB版本
原文連結:https://blog.csdn.net/CSDN___CSDN/article/details/81042527
TOPSIS算法步驟
對應MATLAB程式
說明:有‘%’的地方可靈活變換數值
a=[1 2 3;4 5 6;7 8 9];%【】
c=sqrt(sum(a.*a));
for i=1:3%【[ma,na]=size(A); %ma為A矩陣的行數,na為A矩陣的列數】
for j=1:3%【】
d(i,j)=a(i,j)/c(j)%【d為規範化決策矩陣】
end
end
w=[1 2 3];%【】
for i=1:3%【】
for j=1:3%【】
c(i,j)=d(i,j)*w(j)%【c為權重矩陣】
end
end
cmax=max(c);
cmin=min(c);
for i=1:3%【】
c1=c(i,:)-cmax
s1(i)=norm(c1)
c2=c(i,:)-cmin
s2(i)=norm(c2)
T(i)=s2(i)/(s1(i)+s2(i))
end