Topsis优劣解距离法python代码实现
positive_transform.py
#positive_transform.py
import numpy as np
import pandas as pd
#positive_transform模块
#作用:将指标正向化,支持的指标类型:极小型、中间型、区间型
#x:numpy.ndarray pandas.Series
#极小型指标转极大型
def min2max(x):
return (max(x)-x).values
#中间型指标转极大型
def mid2max(x,mid): #mid:中间最优值
M=max(abs(x-mid))
return (1-(abs(x-mid)/M)).values
#区间型指标转极大型 #[a,b]最优区间
def interval2max(x,a,b):
M=max(abs(min(x)-a),abs(max(x)-b))
x_pos=[]
for i in x:
if i<a:
i=1-abs(a-i)/M
elif i>b:
i=1-abs(i-b)/M
else:
i=1
x_pos.append(i)
return x_pos
#正向化
def positive(data):
indexes=data.columns
data_pos = data.copy()
ques1 = int(input('是否有极小化指标:1是,0否'))
if ques1:
min_cols = input('输入极小化指标所在列索引{用,分隔}:')
min_cols = min_cols.split(',')
for col in min_cols:
col = int(col.strip())
data_pos[indexes[col]] = min2max(data_pos[indexes[col]])
ques2 = int(input('是否有中间型指标:1是,0否'))
if ques2:
mid_cols = input('输入中间型指标所在列索引{用,分隔}:')
mid_cols = mid_cols.split(',')
for col in mid_cols:
col = int(col.strip())
mid = int(input(f'对于{indexes[col]}列,输入中间值:'))
data_pos[indexes[col]] = mid2max(data_pos[indexes[col]], mid)
ques3 = int(input('是否有区间化指标:1是,0否'))
if ques3:
interval_cols = input('输入区间型指标所在列索引{用,分隔}:')
interval_cols = interval_cols.split(',')
for col in interval_cols:
col = int(col.strip())
a = int(input(f'对于{indexes[col]}列,输入区间最小值:'))
b = int(input(f'对于{indexes[col]}列,输入区间最大值:'))
data_pos[indexes[col]] = interval2max(data_pos[indexes[col]], a, b)
return data_pos
Topsis.py
import numpy as np
import pandas as pd
import positive_transform as pt
import 层次分析法.JudgeMatrix as JM
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
#1、导入数据,示例water_condition.xlsx
data=pd.read_excel('water_condition.xlsx',sheet_name='Sheet1')
data=data.set_index('河流')
indexes=data.columns
print(data)
#2、正向化
print('正在进行正向化:')
data_pos=pt.positive(data)
print(f'正向化结果:\n{data_pos}')
#3、标准化
data_pos_standard=data_pos/np.linalg.norm(data_pos,axis=0)
print(f'标准化结果:\n{data_pos_standard}')
#4、计算最大值向量与最小值向量
min_V=data_pos_standard.min(axis=0)
max_V=data_pos_standard.max(axis=0)
flag=int(input('是否给各指标确定权重[1-是,0-否]:'))
#计算指标权重向量(默认等权)
Weights=[1/len(indexes)]*len(indexes)
if flag:
opt1=int(input('是否直接输入权重向量[1-是,0-否]:'))
if opt1:
Weight_str=input('直接输入权重向量[数字用,分隔]:')
Weight_list=Weight_str.split(',')
Weights=[float(i.strip()) for i in Weight_list]
else:
opt2 = int(input('是否直接判断矩阵确定权重向量[1-是,0-否]:'))
if opt2:
Weights=JM.Judge_Matrix_Weight()
print(f'权重向量为{Weights}')
#5、Topsis算法计算各向量与最值向量距离
D_P=np.sqrt(((data_pos_standard.subtract(max_V,axis=1))**2).multiply(Weights,axis=1).sum(axis=1))#计算每一个向量与最大值向量距离
D_N=np.sqrt(((data_pos_standard.subtract(min_V,axis=1))**2).multiply(Weights,axis=1).sum(axis=1))#计算每一个向量与最小值向量距离
#6、计算各评价对象得分并归一化
S=D_N/(D_P+D_N)
S=S/S.sum()
result=pd.Series(data=S,index=data.index)
print('最终得分为:')
print(result)
result_sorted=result.sort_values(ascending=False)
print('根据得分降序排列为:')
print(result_sorted)
#7、绘制条形图
plt.barh(result_sorted.index,result_sorted.values)
plt.xlabel('评分')
plt.ylabel('河流')
plt.title('河流评分排序')
plt.show()
原文地址:https://blog.csdn.net/2301_79376014/article/details/140684780
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!