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 极小型指标:期望指标值越小越好(如患病率、死亡率等)
为指标
可能取值的最大值
2.1.2 中间型指标:期望指标值既不要太大也不要太小,适当取中间值最好(如水质量评估 PH 值)
其中
为指标
的可能取值的最大值,
为指标
的可能取值的最小值
2.1.3 区间型指标:期望指标的取值最好落在某一个确定的区间最好(如体温)
其中
为指标
的最佳稳定区间,
为最大容忍区间
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 构造归一化初始矩阵
设共有
个待评价对象,每个对象都有
个指标(属性),则原始数据矩阵构造为:
构造加权规范矩阵,属性进行向量规范化,即每一列元素都除以当前列向量的范数(使用余弦距离度量)
由此得到归一化处理后的标准化矩阵
:
2.3 确定最优方案和最劣方案
最优方案
由
中每列元素的最大值构成:
最劣方案
由
中每列元素的最小值构成:
2.4 计算各评价对象与最优方案、最劣方案的接近程度
其中
为第
个属性的权重(重要程度),指标权重建议根据实际确定或使用专家评估方法。在本文第 4 部分也提供了两种常用的确定权重的方法及简要分析。
2.5 计算各评价对象与最优方案的贴近程度
表明评价对象越优。此处也可以将分子设置为
表示与最劣方案的贴近程度, 此时
表明评价对象越优
2.6 根据
大小进行排序,给出评价结果
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:权系数, 默认使用熵权法定权. 也可以传入指定权重列表. (熵权法代码见下文)
3 案例及程序调用实例
3.1 问题提出
为了客观地评价我国研究生教育的实际状况和各研究生院的教学质量,国务院学位委员会办公室组织过一次研究生院的评估。为了取得经验,先选5所研究生院,收集有关数据资料进行了试评估,下表是所给出的部分数据:
3.2 指标同向化处理人均专著、科研经费为效应型指标(越大越好)
逾期毕业率为成本型指标(越小越好)
生师比为区间型指标
3.3 构造归一化初始矩阵
以 "人均专著" 属性为例:
院校A:
院校B:
院校C:
院校D:
院校E:
3.4 确定最优方案和最劣方案
在每一列中分别选取最大值、最小值构成最优最劣方案:
3.5 计算各评价对象与最优方案的接近程度及最终得分,并进行排序
3.6 雷达图分析及上述过程代码调用图:评价结果雷达图(各属性值进行了变换,图中仅反映相对大小关系)
import pandas as pd
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))
data = pd.DataFrame(
{'人均专著': [0.1, 0.2, 0.4, 0.9, 1.2], '生师比': [5, 6, 7, 10, 2], '科研经费': [5000, 6000, 7000, 10000, 400],
'逾期毕业率': [4.7, 5.6, 6.7, 2.3, 1.8]}, index=['院校' + i for i in list('ABCDE')])
data['生师比'] = dataDirection_3(data['生师比'], 5, 6, 2, 12) # 师生比数据为区间型指标
data['逾期毕业率'] = 1 / data['逾期毕业率'] # 逾期毕业率为极小型指标
out = topsis(data, weight=[0.2, 0.3, 0.4, 0.1]) # 设置权系数
4 合理确定指标权重是应用 TOPSIS 综合评价的关键
4.1 基于信息论的熵值法(数据差异程度)
4.1.1 熵值法过程
基于信息论的熵值法是根据各指标所含信息有序程度的差异性来确定指标权重的客观赋权方法,仅依赖于数据本身的离散程度。
熵用于度量不确定性,指标的离散程度越大(不确定性越大)则熵值越大,表明指标值提供的信息量越多,则该指标的权重也应越大。主要计算步骤如下:
Step1 对原始数据矩阵 (4) 按列进行归一化处理(注意,这里不能是同向化后的矩阵,会损失原始信息),归一化方法不唯一,以下提供最简单的比值归一化,实际上也可以使用上文中的向量归一化方法
Step2计算各指标的熵值:
其中
与样本数量有关,常取
,此外,补充定义:若
,则令
Step3计算各指标的权系数:
熵权系数
越大,则该指标代表的信息量越大,表示其对综合评价的作用越大。
4.1.2 分析
上面的方法看着很高大上,但是直觉告诉我(们),从数据推出的权重,往往都不具有现实意义。那这个到底是什么意思呢?我们用第 3 部分的数据测试一下:原始数据比值归一化后的矩阵为:
计算各指标方差(衡量数据离散程度)
各指标的熵值和权系数为:
发现了吗?熵值、权系数、方差间的大小次序是相关的,如果对熵的概念较为陌生,那不妨换个角度想想:什么类型的数据会导致方差小?如人体体温变化,体温的变化都是在一个微小的范围内,这样就造成了这一属性的变异程度较小,使用熵权法(主成分分析法同理)进行计算时,获得的权系数较小,变得 "不那么重要"。但事实上即使构造了合理的权系数,在对数据做变换(如成本型指标取倒数),这种权系数的设置是否仍然合理都是个问题(数据分布情况发生了改变)。
一种减轻这种影响的方法是选择更合理的归一化方法去除指标的量纲。如变化范围较大的数据可以使用小数定标规范化、正态分布的数据使用 z 分数变换、均匀分布的数据使用离差标准化。通过这种方法,可以获得较为 "合理" 的指标权。但要注意的是合不合理都是相对的,事实上许多文献没有考虑到这种方法背后的意义,但其计算得到的结论很实用(滑动权值经验模式,未来在介绍其他评价方法时再做详细介绍),即衡量模型的优劣并不是看系数合不合理,而是效果好不好/符不符合实际。结论:评价结果、评价方法的好坏,本身就具有很强的主观性。马克思主义告诉我们“具体问题具体分析。在矛盾普遍性原理的指导下,具体分析矛盾的特殊性,并找出解决矛盾的正确方法。”。怎么在论文中将你的思想、选取方法的原则、指标选取、权重构造尽可能详尽的展示,才是方法应用成功与否的关键。
代码:
data = pd.DataFrame(
{'人均专著': [0.1, 0.2, 0.4, 0.9, 1.2], '生师比': [5, 6, 7, 10, 2], '科研经费': [5000, 6000, 7000, 10000, 400],
'逾期毕业率': [4.7, 5.6, 6.7, 2.3, 1.8]}, index=['院校' + i for i in list('ABCDE')])
import numpy as np
def entropyWeight(data):
data = np.array(data)
# 归一化
P = data / data.sum(axis=0)
# 计算熵值
E = np.nansum(-P * np.log(P) / np.log(len(data)), axis=0)
# 计算权系数
return (1 - E) / (1 - E).sum()
entropyWeight(data)
4.2 (AHP)层次分析法定权重
层次分析法是一种定性与定量相结合的决策分析方法,通过判断各衡量指标的相对重要程度,进而得到决策方案中每个指标的权重,熵权法是基于数据的定权方法,而层次分析法是基于经验的定权方法。
注意:层次分析法所提到的特征向量、特征值并不是矩阵中的概念,是重新定义的。
1) 构造指标成对比较矩阵
由于定性定权不免存在偏差,Santy 等人提出使用一致矩阵法,构造成对比较矩阵。设共有
个评价指标。
定义:
表示指标
和指标
的相对重要程度,如
表示指标
和指标
的相对重要程度为 1:3
(一般都是查阅文献,xx 比 xx 重要再人为设定相对重要程度,一般以 1、3、5、7 界定重要程度)
定义: 成对比较矩阵 A ,A 的每一个元素
且
2) 计算矩阵的特征值和特征向量
Step 1 : 先对成对比矩阵进行列归一化,即每个元素都除以当前列元素的和
Step 2: 将归一化矩阵按行求和,得到每一行的“特征向量”
Step 3: 将特征向量按列归一化,得到“指标权重”
Step 4: 成对比矩阵的每一列乘以“指标权重”中对应位置的元素得到
矩阵
Step 5: 将
矩阵按行求和,得到矩阵
:
Step 6: 将
进行标准化、并对所有元素求和,得到特征值:
3) 判断成对比较矩阵的一致性
定义: 一致性指标 CI 定义为
说明一致性越好,即成对比矩阵构造合理。但多“小”依旧是人为选取,因此引入 “一致性比率” 来衡量。
定义: 一致性比率 CR,其中 CI 是一致性指标,RI 是随机一致性指标(查表得到):
则说明矩阵 的不一致程度在容许范围内,可以用其特征向量作为权向量。
代码:
import numpy as np
RI = {1: 0, 2: 0, 3: 0.58, 4: 0.90, 5: 1.12, 6: 1.24, 7: 1.32, 8: 1.41, 9: 1.45, 10: 1.49, 11: 1.51}
def ahp(data):
data = np.array(data)
m = len(data)
# 计算特征向量
weight = (data / data.sum(axis=0)).sum(axis=1) / m
# 计算特征值
Lambda = sum((weight * data).sum(axis=1) / (m * weight))
# 判断一致性
CI = (Lambda - m) / (m - 1)
CR = CI / RI[m]
if CR < 0.1:
print(f'最大特征值:lambda ={Lambda}')
print(f'特征向量:weight ={weight}')
print(f'\nCI = {round(CI,2)}, RI ={RI[m]}\nCR = CI/RI = {round(CR,2)} < 0.1,通过一致性检验')
return weight
else:
print(f'\nCI = {round(CI,2)}, RI ={RI[m]}\nCR = CI/RI = {round(CR,2)} >= 0.1,不满足一致性')
例:
A = [[1,4,2,8,2],[1/4,1,1/2,2,1/2],[1/2,2,1,4,1],[1/8,1/2,1/4,1,1/4],[1/2,2,1,4,1]]
ahp(A)
5 与 TOPSIS 法极其相似的密切点法
5.1 密切点法
在密切点法中定义“接近程度”时,考虑了当前评价单元与最优最劣解的距离,以当前各评价对象距离最优解的最小距离、最劣解的最大距离作为参比,进行自身对照,综合评价其“接近程度”:
定义密切值如下:
越小,表明评价对象越优。
5.2 TOPSIS 与 密切值法区别
两种评价方法原理相似、方法相近,评价得出的结果也基本相同,在使用时没有较大区别,但由 TOPSIS 法得出的指标一定是正数,且相似度形式便于解释。
此外,由于密切值法需要对当前所有评价对象先进行距离度量,再选取度量值作为标准,意味着对于具有较大动态性数据的评价,若使用密切值法,在每一次更新数据时,都要重新对当前数据进行比对,极大地消耗计算资源。
由于密切值法相对于 TOPSIS 法没有明显优势,在评价方案 TOPSIS 法与密切值法中,建议使用 TOPSIS 法。
6 后记
综合评价相关内容:https://zhuanlan.zhihu.com/p/38209882zhuanlan.zhihu.com
在 TOPSIS 法中可以看出,构造的矩阵并没有涉及矩阵论(或者说线性代数)相关知识,只是利用到了矩阵中的元素及其简单的表达方式,计算过程十分简单。
常用的评价方法有层次分析法,RSR 秩和比综合评价法、优劣解距离法、模糊综合评价法、DEA 资料包络分析等,TOPSIS 在实现上是所有方法中最简单的,它完全依赖于现有数据的分布情况,能对现有数据进行充分利用,因此适合用来进行样本数据内部排序使用(如18年美赛C题中,就可以使用这种方法进行评价)。此外,在葡萄酒建模题中,也可以使用此方法,对多个专家评分结果进行综合。对于分类变量的处理不建议使用 TOPSIS 法。
作者:张柳彬
如有疑问,请联系QQ:965579168
转载请声明出处