文章目录
- 1、TOPSIS算法
- 2、TOPSIS算法流程
- 2.1、极大型转化
- 2.1.1 极大型
- 2.1.2 中间型
- 2.1.3 极小型
- 2.1.4 区间型
- 2.2 计算每项指标的权重
- 2.3 正向矩阵标准化
- 2.4 计算得分
- 3、实例
- 4、参考资料
1、TOPSIS算法
TOPSIS方法是基于数据对样本进行排序的一种方法,其基本思想是根据样本数据构造一个理想化的目标。主要找到每一列(指标)的最大值让它们构成一个向量和每一列(指标)的最小值构成一个向量
。只要找到这两个向量,后面的事情就好办了。
2、TOPSIS算法流程
2.1、极大型转化
将不同指标转化为极大型指标,指标常见四种类型,极大型,中间型,极小型,范围型。
四种类型的指标处理方法如下
2.1.1 极大型
无需处理
2.1.2 中间型
2.1.3 极小型
2.1.4 区间型
2.2 计算每项指标的权重
本文采用的是熵权法,在我之前的文章有讲,点击这里
2.3 正向矩阵标准化
将标准化以后的矩阵每列都乘以W[i](上一步已经把每一列的权重都算出来了)。
2.4 计算得分
3、实例
注:这里使用的是2021年华数杯C题附件一数据
import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
import math
# 极小型指标 -> 极大型指标
def dataDirection_1(datas):
return np.max(datas) - datas # 套公式
# 中间型指标 -> 极大型指标
def dataDirection_2(datas, x_best):
temp_datas = datas - x_best
M = np.max(abs(temp_datas))
answer_datas = 1 - abs(datas - x_best) / M # 套公式
return answer_datas
# 区间型指标 -> 极大型指标
def dataDirection_3(datas, x_min, x_max):
M = max(x_min - np.min(datas), np.max(datas) - x_max)
answer_list = []
for i in datas:
if (i < x_min):
answer_list.append(1 - (x_min - i) / M) # 套公式
elif (x_min <= i <= x_max):
answer_list.append(1)
else:
answer_list.append(1 - (i - x_max) / M)
return np.array(answer_list)
# 正向化矩阵标准化
def Scaler(datas,weight):
K = pow(np.sum(pow(datas,2),axis=1),0.5)
print(K)
for i in range(datas.shape[1]):
for j in range(0, datas[i].size):
datas[i, j] = datas[i, j] / K[i] # 套用矩阵标准化的公式
for i in range(datas.shape[1]):
datas[i] = datas[i]*weight[i]
return datas
def Score(datas):
list_max = []
for i in range(datas.shape[1]):
list_max.append(np.max(datas[:,i]))
list_min = []
for i in range(datas.shape[1]):
list_min.append(np.min(datas[:, i]))
max_list = [] # 存放第i个评价对象与最大值的距离
min_list = [] # 存放第i个评价对象与最小值的距离
answer_list = [] # 存放评价对象的得分
for k in range(datas.shape[0]):
max_sum = 0
min_sum = 0
for q in range(datas.shape[1]):
max_sum += pow(datas[k,q]-list_max[q], 2)
min_sum += pow(datas[k,q]-list_min[q], 2)
max_list.append(pow(max_sum, 0.5))
min_list.append(pow(min_sum, 0.5))
answer_list.append(min_list[k] / (min_list[k] + max_list[k]))
result = np.array(answer_list)
return result
def main():
data = pd.read_excel('2.xlsx')
data = data.iloc[:,2:10]
"""
for i in range(data.shape[1]):
if 极大型
data[i] = data[i] #或者continue
elif 中间型
data[i] = dataDirection_2(data[i],mid)
elif 极小型
data[i] = dataDirection_1(data[i])
else 范围型
data[i] = dataDirection_3(data[i],min,max)
"""
After_Large = np.array(data)
# 计算每个元素的权重
weight = cal_weight(data)
After_Scaler = Scaler(After_Large,weight)
Final_Score = Score(After_Scaler)
data = pd.DataFrame(Final_Score)
writer = pd.ExcelWriter('34.xlsx')
data.to_excel(writer,float_format='%.5f')
writer.save()
writer.close()
def cal_weight(x):
x = MinMaxScaler().fit_transform(x)
# 求k
rows = x.shape[0] # 行
cols = x.shape[1] # 列
k = 1.0 / math.log(rows)
# 矩阵计算--
# 信息熵
# p=array(p)
x = np.array(x)
lnf = [[None] * cols for i in range(rows)]
lnf = np.array(lnf)
for i in range( rows):
for j in range(cols):
if x[i][j] == 0:
lnfij = 0.0
else:
p = x[i][j] / x.sum(axis=0)[j]
lnfij = math.log(p) * p * (-k)
lnf[i][j] = lnfij
lnf = pd.DataFrame(lnf)
E = lnf
# 计算冗余度
d = 1 - E.sum(axis=0)
# 计算各指标的权重
w = np.zeros((x.shape[1]))
for j in range(cols):
wj = d[j] / sum(d)
w[j] = wj
# 计算各样本的综合得分,用最原始的数据
return np.array(w)
if __name__ == '__main__':
main()
注:TOPSIS对异常值比较敏感,使用TOPSIS算法之前一定要去除异常值
标签:TOPSIS,min,max,list,算法,np,评价,data,datas From: https://blog.51cto.com/u_14597003/5989164