本文共 4906 字,大约阅读时间需要 16 分钟。
平时,我们常见的评价方法有:
今天我就来介绍一下Topsis优劣解距离评价法。
TOPSIS法(Technique for Order Preference by Similarity to ldeal Solution),简称为优劣解距离法,是一种常用的综合评价方法,其能充分利用原始数据的信息,其结果能精确地反映各评价方案之间的差距。
讲原理的过程中,我们举个例子会更好理解一些,比如某学校将进行老师综合素质评价,现有如下指标,计算哪个老师综合素质最高:
姓名 | 教学评分 | 请假次数 |
张三 | 88 | 3 |
李四 | 79 | 1 |
王五 | 90 | 0 |
彭六 | 93 | 5 |
平常常见的指标有:
指标名称 | 指标特点 | 例子 |
极大型(效益型)指标 | 越大(多)越好 | 成绩、GDP增速、企业利润 |
极小型(成本型)指标 | 越小(少)越好 | 费用、坏品率、污染程度 |
中间型指标 | 越接近某个值越好 | 水质量评估时的PH值 |
区间型指标 | 落在某个区间最好 | 体温、水中植物性营养物量 |
原始矩阵正向化,即将所有的指标类型统一转化为 极大型指标,但转化方法可以不同!
极小型指标→极大型指标: m a x − x max-x max−x
中间型指标→极大型指标:
{ x i } \lbrace x_i \rbrace { xi}是一组中间型指标序列,且最佳的数值为 x b e s t x_{best} xbest,则正向化公式为: M = m a x { ∣ x i − x b e s t ∣ } M=max{\lbrace| x_i-x_{best}| \rbrace} M=max{ ∣xi−xbest∣} x i = 1 − ∣ x i − x b e s t ∣ M x_i = 1-{| x_i-x_{best}| \over M} xi=1−M∣xi−xbest∣ 比如: 一组PH值PH值 | 5 | 7 | 6 | 8 | 9 |
x b e s t = 7 , M = m a x { ∣ 5 − 7 ∣ } x_{best}=7,M=max{\lbrace| 5-7| \rbrace} xbest=7,M=max{ ∣5−7∣}
区间型指标→极大型指标
{ x i } \lbrace x_i \rbrace { xi}是一组中间型指标序列,且最佳的区间为[a,b],则正向化公式为: x ~ = { 1 − a − x M , x < a 1 , a ≤ x ≤ b 1 − x − b M , x > b \widetilde{x}= \left\{ \begin{aligned} 1-{a-x\over M}, x<a \\ 1 , a \leq x \leq b\\ 1-{x-b\over M}, x>b \end{aligned} \right. x =⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧1−Ma−x,x<a1,a≤x≤b1−Mx−b,x>b 其中, M = m a x { a − m i n { x i } , m a x { x i } − b } M=max\{a-min\{x_i\}, max\{x_i\}-b\} M=max{ a−min{ xi},max{ xi}−b}正向化后的矩阵为:
X = [ X 11 X 12 . . . X 1 m X 21 X 22 . . . X 2 m . . . . . . . . . . . . X n 1 X n 2 . . . X n m ] X =\left[ \begin{matrix} X_{11} & X_{12} & ... & X_{1m}\\ X_{21} & X_{22} & ... & X_{2m}\\ ... & ... & ... & ...\\ X_{n1} & X_{n2} & ... & X_{nm}\\ \end{matrix} \right] X=⎣⎢⎢⎡X11X21...Xn1X12X22...Xn2............X1mX2m...Xnm⎦⎥⎥⎤将上一步得到的正向化矩阵进行标准化,标准化的矩阵记为Z,Z中的每一个元素:
Z i j = x i j ∑ i = 1 n x i j 2 Z_{ij} = {x_{ij} \over \sqrt{\sum\limits_{i=1}^n{x_{ij}^2}}} Zij=i=1∑nxij2xij 即 每 一 个 元 素 其 所 在 列 的 元 素 的 平 方 和 每一个元素\over \sqrt{其所在列的元素的平方和} 其所在列的元素的平方和每一个元素 得到标准化矩阵: Z = [ Z 11 Z 12 . . . Z 1 m Z 21 Z 22 . . . Z 2 m . . . . . . . . . . . . Z n 1 Z n 2 . . . Z n m ] Z =\left[ \begin{matrix} Z_{11} & Z_{12} & ... & Z_{1m}\\ Z_{21} & Z_{22} & ... & Z_{2m}\\ ... & ... & ... & ...\\ Z_{n1} & Z_{n2} & ... & Z_{nm}\\ \end{matrix} \right] Z=⎣⎢⎢⎡Z11Z21...Zn1Z12Z22...Zn2............Z1mZ2m...Znm⎦⎥⎥⎤定义最大值: Z + = ( Z 1 + , Z 2 + , . . . , Z m + ) Z^+=(Z^+_1, Z^+_2, ..., Z^+_m) Z+=(Z1+,Z2+,...,Zm+)
最小值 Z − = ( Z 1 − , Z 2 − , . . . , Z m − ) Z^-=(Z^-_1, Z^-_2, ..., Z^-_m) Z−=(Z1−,Z2−,...,Zm−)第i个评价对象与最大值距离为: D i + = ∑ j = 1 m ( Z j + − z i j ) 2 D_i^+= \sqrt{\sum\limits_{j=1}^m(Z_j^+-z_{ij})^2} Di+=j=1∑m(Zj+−zij)2
第i个评价对象与最小值距离为: D i − = ∑ j = 1 m ( Z j − − z i j ) 2 i = 1 , 2 , . . . , n D_i^-= \sqrt{\sum\limits_{j=1}^m(Z_j^--z_{ij})^2} \quad i=1,2,...,n Di−=j=1∑m(Zj−−zij)2i=1,2,...,n 可以计算得到,第i个评价对象未归一化得分为: S i = D i − D i − + D i + S_i = {D_i^- \over {D_i^-+D_i^+}} Si=Di−+Di+Di− 最后归一化: S i ′ = S i − S m i n S m a x − S m i n S_i ^{'} = {S_i - S_{min} \over {S_{max} - S_{min}}} Si′=Smax−SminSi−Smin最后得到的 S i ′ S_i ^{'} Si′就是需要的得分!
# TOPSIS计算公司发展水平class TOPSIS: # 初始化 def __init__(self, df, feature_list): self.df = df # 输入dataframe,这份用来下面算法操作 self.df_copy = df.copy() # 备份,因为操作的时候回改变原始数据,所以这份数据用来储存计算结果 self.feature_list = feature_list # 要作为评价特征的特征 self.features_num = len(feature_list) # 特征个数 self.features_length = df.shape[0] # 样本数量 # 标准化 def standardization(self): for f in self.feature_list: self.df[f] = self.df[f] / np.sqrt(sum(np.power(self.df[f], 2))) # 计算D+, D- def D_calculation(self): self.standardization() self.df_copy['D+'] = 0 self.df_copy['D-'] = 0 for i in range(self.features_length): self.df_copy['D+'].iloc[i] = np.sqrt(sum([(self.df[feature].iloc[i]-np.max(self.df[feature]))**2 for feature in self.feature_list])) self.df_copy['D-'].iloc[i] = np.sqrt(sum([(self.df[feature].iloc[i]-np.min(self.df[feature]))**2 for feature in self.feature_list])) return self.df # 计算未归一化得分 def non_normalized_score(self): self.D_calculation() self.df_copy['score_unnormalized'] = self.df_copy['D-'] / (self.df_copy['D+'] + self.df_copy['D-']) # 计算归一化得分 def normalized_score(self): self.non_normalized_score() self.df_copy['score_normalized'] = (self.df_copy['score_unnormalized'] - min(self.df_copy['score_unnormalized'])) \ / (max(self.df_copy['score_unnormalized'])-min(self.df_copy['score_unnormalized'])) return self.df_copy
代码实操:
我随机编撰了一段数据,通过TOPSIS来计算数据中公司的发展情况,v1、v2、v3指的是能代表该公司发展状况的特征:# 计算data = pd.read_excel(r'.\topsis_test.xlsx')features = ['v1', 'v2', 'v3']data = TOPSIS(data, features).normalized_score()data
得到结果为:
可以看到计算结果中有距离结果、也有未归一化、归一化得分。 从归一化得分可以看出company1发展情况最好!转载地址:http://ydiwi.baihongyu.com/