TOPSIS方法简介
TOPSIS法(Technique for Order Preference by Similarity to Ideal Solution),通常也称为优劣解距离法。TOPSIS 法是一种常用的综合评价方法,其能充分利用原始数据的信息,其结果能精确地反映各评价方案之间的差距。它用于解决的问题是:给出n个对象,以及n个对象关于m个指标的各项数据,根据这些数据对n个对象进行综合评价并打分,此分数能反映这n个对象的综合排名
实现过程
1.将数据正向化
我们通常将数据指标分为四种:极大型、极小型、中间型、区间型,具体区别如下表:
极大型
数据值越大越好,比如成绩、利润等
极小型
数据值越小越好,比如损失、挂科率等
中间型
数据值接近某个值时最好,比如某些情况下的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∗组成一组极大型指标
2.将正向化矩阵标准化
设待评价的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
之所以进行标准化,是因为各个指标的量纲不同,进行标准化是为了消除量纲差异
3.计算得分并归一化
标准化矩阵为
[
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