TOPSIS法(Technique for Order Preference by Similarity to Ideal Solution),通常也称为优劣解距离法。TOPSIS 法是一种常用的综合评价方法,其能充分利用原始数据的信息,其结果能精确地反映各评价方案之间的差距。它用于解决的问题是:给出n个对象,以及n个对象关于m个指标的各项数据,根据这些数据对n个对象进行综合评价并打分,此分数能反映这n个对象的综合排名
我们通常将数据指标分为四种:极大型、极小型、中间型、区间型,具体区别如下表:
极大型 数据值越大越好,比如成绩、利润等 极小型 数据值越小越好,比如损失、挂科率等 中间型 数据值接近某个值时最好,比如某些情况下的ph值 区间型 数据值位于某个区间内最好 \begin{array}{c|c} \text{极大型} & \text{数据值越大越好,比如成绩、利润等}\\ \hline \text{极小型} & \text{数据值越小越好,比如损失、挂科率等}\\ \hline \text{中间型} & \text{数据值接近某个值时最好,比如某些情况下的ph值}\\ \hline \text{区间型} & \text{数据值位于某个区间内最好} \end{array} 极大型极小型中间型区间型数据值越大越好,比如成绩、利润等数据值越小越好,比如损失、挂科率等数据值接近某个值时最好,比如某些情况下的ph值数据值位于某个区间内最好
在这一步我们要做的是将m个指标全部转换为极大型指标,以下是对于每种数据类型的处理方法举例(因为转换成极大型的方法不止一种)
对于一组数据: y 1 , y 2 , ⋯ , y m y_1,y_2,\cdots,y_m y1,y2,⋯,ym
若其为极大型,则无需操作;
若其为极小型, y i ∗ = m a x { y 1 , y 2 , ⋯ , y m } − y i y_i^* = max\{y_1,y_2,\cdots,y_m\} -y_i yi∗=max{y1,y2,⋯,ym}−yi,则 y 1 ∗ , y 2 ∗ , ⋯ , y m ∗ y_1^*,y_2^*,\cdots,y_m^* y1∗,y2∗,⋯,ym∗组成一组极大型指标;
若其为中间型,设 y 0 y_0 y0为最优值, M = m a x { ∣ y i − y 0 ∣ } , y i ∗ = 1 − ∣ y i − y 0 ∣ M M = max\{|y_i-y_0|\},y_i^* = 1-\frac{|y_i-y_0|}{M} M=max{∣yi−y0∣},yi∗=1−M∣yi−y0∣,则 y 1 ∗ , y 2 ∗ , ⋯ , y m ∗ y_1^*,y_2^*,\cdots,y_m^* y1∗,y2∗,⋯,ym∗组成一组极大型指标;
若其为区间型,设最优区间为(a,b),并且假定大于b、小于a的数据均存在, M = m a x { a − m i n y i , m a x y i − b } M = max\{a-min\,y_i,max\,y_i-b\} M=max{a−minyi,maxyi−b}
y i ∗ = { 1 − a − y i M y i ≤ a 1 a < y i < b 1 − y i − b M y i ≥ b y_i^* = \begin{cases} 1-\frac{a-y_i}{M} & y_i \leq a \\ 1 & a < y_i < b \\ 1-\frac{y_i-b}{M} & y_i \geq b \end{cases} yi∗=⎩⎪⎨⎪⎧1−Ma−yi11−Myi−byi≤aa<yi<byi≥b则 y 1 ∗ , y 2 ∗ , ⋯ , y m ∗ y_1^*,y_2^*,\cdots,y_m^* y1∗,y2∗,⋯,ym∗组成一组极大型指标
设待评价的n个对象的m个指标的数据矩阵(经过正向化之后)如下:
[ x 11 x 12 ⋯ x 1 m x 21 x 22 ⋯ x 2 m ⋮ ⋮ ⋱ ⋮ x n 1 x n 2 ⋯ x n m ] \begin{bmatrix} x_{11} & x_{12} & \cdots & x_{1m} \\ x_{21} & x_{22} & \cdots & x_{2m} \\ \vdots & \vdots & \ddots & \vdots \\ x_{n1} & x_{n2} & \cdots & x_{nm} \\ \end{bmatrix} ⎣⎢⎢⎢⎡x11x21⋮xn1x12x22⋮xn2⋯⋯⋱⋯x1mx2m⋮xnm⎦⎥⎥⎥⎤
标准化是在此基础上构造新矩阵,使得每一列的元素平方和为1,不难验证以下操作得到的矩阵 Z Z Z即满足要求
z i j = x i j ∑ i = 1 n x i j 2 z_{ij} = \frac{x_{ij}}{\sqrt{\sum_{i=1}^{n}x_{ij}^2}} zij=∑i=1nxij2xij
之所以进行标准化,是因为各个指标的量纲不同,进行标准化是为了消除量纲差异
标准化矩阵为
[ z 11 z 12 ⋯ z 1 m z 21 z 22 ⋯ z 2 m ⋮ ⋮ ⋱ ⋮ z n 1 z n 2 ⋯ z n m ] \begin{bmatrix} z_{11} & z_{12} & \cdots & z_{1m} \\ z_{21} & z_{22} & \cdots & z_{2m} \\ \vdots & \vdots & \ddots & \vdots \\ z_{n1} & z_{n2} & \cdots & z_{nm} \\ \end{bmatrix} ⎣⎢⎢⎢⎡z11z21⋮zn1z12z22⋮zn2⋯⋯⋱⋯z1mz2m⋮znm⎦⎥⎥⎥⎤
将每列的最大值取出组成最大值向量: Z + = ( m a x { z i 1 } , m a x { z i 2 } , ⋯ , m a x { z i m } ) Z^+=(max\,\{z_{i1}\},max\,\{z_{i2}\},\cdots,max\,\{z_{im}\}) Z+=(max{zi1},max{zi2},⋯,max{zim}),同理得到最小值向量 Z − Z^- Z−
第i个对象的m个数据与最大值之间的距离为 D i + = ∑ j = 1 m ( z i j − Z j + ) 2 D_i^+=\sqrt{\sum_{j=1}^m{(z_{ij}-Z_j^+)^2}} Di+=∑j=1m(zij−Zj+)2,与最小值之间的距离为 D i − = ∑ j = 1 m ( z i j − Z j − ) 2 D_i^-=\sqrt{\sum_{j=1}^m{(z_{ij}-Z_j^-)^2}} Di−=∑j=1m(zij−Zj−)2那么我们将第i个对象的未归一化得分定义为 S i = D i − D i + + D i − S_i=\frac{D_i^-}{D_i^++D_i^-} Si=Di++Di−Di−,归一化之后,第i个对象的最终得分为 S i ∑ r = 1 n S r \frac{S_i}{\sum_{r=1}^nS_r} ∑r=1nSrSi,至此便完成了全部的打分工作,接下来根据分数便可看出n个对象的综合排名
下面通过一个实际问题来进一步理解该打分方法
例:下图为七个国家2020年在高等教育领域的七个指标的汇总,请根据其为七个国家在高等教育领域排名
在这七个指标中,通过查阅资料得出:第1、3、5、6项指标为极大型指标;招生人数为中间型,最优值2500;毕业率为中间型,最优值0.74;师生比为中间型,最优值0.105
import numpy as np
#定义转换函数:
def f_1(A):#极小型->极大型
x = np.max(A)
for i in range(0,A.shape[0]):
A[i] = x-A[i]
return A
def f_2(A,a):#中间型->极大型
x = np.max(np.abs(A-a))
for i in range(0,A.shape[0]):
A[i] = 1-np.abs(A[i]-a)/x
return A
def f_3(A,a,b):#区间型->极大型
u = a-np.min(A)
v = np.max(A)-b
M = v
if u>=v:
M=u
for i in range(0,A.shape[0]):
if A[i]<=a:
A[i] = 1-(a-A[i])/M
elif A[i]>=b:
A[i] = 1-(A[i]-b)/M
else:
A[i] = 1
return A
#定义标准化函数:
def standardize(A):
for j in range(0,A.shape[1]):
sum = 0
for i in range(0,A.shape[0]):
sum = sum+A[i][j]**2
for i in range(0,A.shape[0]):
A[i][j] = A[i][j]/np.sqrt(sum)
return A
#定义打分函数:
def score(Z):
Z = np.transpose(Z)
Z_max = []
Z_min = []
for j in range(0,Z.shape[0]):
Z_max.append(np.max(Z[j]))
Z_min.append(np.min(Z[j]))
S = []
for i in range(0,Z.shape[1]):
sum1 = 0
for j in range(0,Z.shape[0]):
sum1 = sum1+(Z[j][i]-Z_max[j])**2
D1 = np.sqrt(sum1)
sum2 = 0
for j in range(0,Z.shape[0]):
sum2 = sum2+(Z[j][i]-Z_min[j])**2
D2 = np.sqrt(sum2)
S.append(D2/(D1+D2))
return S
#归一化函数:
def g(S):
S = np.array(S)
sum = 0
for i in range(0,S.shape[0]):
sum = sum+S[i]
for i in range(0,S.shape[0]):
S[i] = S[i]/sum
return S
def main():
A = np.array([[28,19,3,5,3,3,8],
[1806,3180,3080,2560,3551,3309,3139],
[11.2,7.98,8.12,5.29,4.3,5.68,6.58],
[0.67,0.71,0.75,0.76,0.874,0.92,0.708],
[17413,11770,9081,11566,8295,9143,9556],
[0.823,0.741,0.804,0.7947,0.851,0.754,0.8676],
[0.112,0.111,0.1,0.091,0.071,0.058,0.067]])
A[1] = f_2(A[1],2500)
A[3] = f_2(A[3],0.74)
A[6] = f_2(A[6],0.105)
B = np.transpose(A)
Z = standardize(B)
S = score(Z)
S1 = g(S)
print(S1)
main()
结果为[0.22337069 0.19818175 0.1626775 0.18908219 0.04941305 0.0465146 0.13076021]由此得到各国的分数,可以看出每个国家在高等教育领域的发展程度,分数较低的国家需要寻找差距。
本道题目中默认了各项指标的权重相同,但在实际的评价中指标都是有各自的权重,因此应该用权重对公式进行修正,修正后的公式如下, ω \omega ω 代表权重。
D i + = ∑ j = 1 m ω j ( Z j + − z i j ) 2 , D i − = ∑ j = 1 m ω j ( Z j − − z i j ) 2 D_i^+=\sqrt{\sum_{j=1}^m\omega_j(Z_j^+-z_{ij})^2},D_i^-=\sqrt{\sum_{j=1}^m\omega_j(Z_j^--z_{ij})^2} Di+=j=1∑mωj(Zj+−zij)2,Di−=j=1∑mωj(Zj−−zij)2