Topsis法
Topsis法是一种常用的综合评价方法,能充分利用原始数据的信息,其结果能精确反映各评价方案之间的差距。该方法对数据分布及样本含量没有严格限制,数据计算简单易行。
基本过程为先将原始数据矩阵统一指标类型(一般正向化处理)得到正向化的矩阵,再对正向化的矩阵进行标准化处理以消除各指标量纲的影响,并找到有限方案中的最优方案和最劣方案,然后分别计算各评价对象与最优方案和最劣方案间的距离,获得各评价对象与最优方案的相对接近程度,以此作为评价优劣的依据。
步骤
第一步 原始矩阵正向化
常见的四种指标:
指标名称 | 指标特点 | 例子 |
极大型(效益型)指标 | 越大(多)越好 | 成绩、GDP增速、企业利润 |
极小型(成本型)指标 | 越小(少)越好 | 费用、污染程度、坏品率 |
中间型指标 | 越接近某个值越好 | 水质量评估时的PH值 |
区间型指标 | 落在某个区间最好 | 体温、水中植物性营养物量 |
将原始矩阵正向化就是要将所有的指标类型统一转化为极大型指标。
转化公式:
(1)极小型->极大型:
(2)中间型->极大型:{}是一组中间型指标序列,最佳的数值为,正向化公式为
,
(3)区间型->极大型:{}是一组中间型指标序列,最佳的区间为[a,b],正向化公式为
当时,
当时,
当时,
第二步 正向化矩阵标准化
标准化后矩阵=(正向化矩阵每个元素/sqrt(其所在列的元素的平方和))
第三步 计算得分并归一化
标准化后矩阵Z,定义最大值Z+、最小值Z-。
定义第i个评价对象与最大值的距离
定义第i个评价对象与最小值的距离
我们可以计算出第i个评价对象未归一化的得分:
越大越小,即越接近最大值。
再对得分进行归一化,
Python代码实现
import numpy as np
# 数据输入
print('输入参评数目:')
n = int(input())
print('输入指标数目:')
m = int(input())
print('输入类型矩阵:1.极大型,2.极小型,3.中间型,4.区间型')
kind = input().split(" ")
# 输入矩阵转化为numpy数组
print('输入矩阵:')
A = np.zeros(shape=(n, m))
for i in range(n):
A[i] = input().split(" ")
A[i] = list(map(float, A[i]))
print('输入矩阵为:\n{}'.format(A))
# 原始矩阵正向化
# 极小型
def minTomax(maxx, x):
ans = maxx - x
return np.array(ans)
# 中间型
def midTomax(bestx, x):
M = max(abs(x - bestx))
if M == 0:
M = 1
ans = 1 - abs(x-bestx)/M
return np.array(ans)
# 区间型
def regTomax(a,b,x):
M = max(a-min(x), max(x)-b)
ans = []
for i in range(len(x)):
if x[i] < a:
ans.append(1-(a-x[i])/M)
elif x[i] > b:
ans.append(1-(x[i]-b)/M)
else:
ans.append([1])
return np.array(ans)
X = np.zeros(shape=(n,1))
for i in range(m):
if kind[i] == '1':
v = np.array(A[:, i])
elif kind[i] == '2':
maxx = max(A[:, i])
v = minTomax(maxx, A[:, i])
elif kind[i] == '3':
print('输入最优值:')
bestx = eval(input())
v = midTomax(bestx, A[:, i])
elif kind[i] == '4':
print('输入区间[a,b]中a的值:')
a = eval(input())
print('输入区间[a,b]中b的值:')
b = eval(input())
v = regTomax(a, b, A[:, i])
if i == 0:
X = v.reshape(-1, 1)
else:
X = np.hstack([X, v.reshape(-1, 1)])
print('统一指标后的矩阵为:\n{}'.format(X))
# 正向化矩阵标准化
X = X.astype('float')
for j in range(m):
X[:, j] = X[:, j]/np.sqrt(sum(X[:, j] ** 2))
print('标准化后的矩阵为:\n{}'.format(X))
# 计算得分并归一化
Zmax = np.max(X, 0)
Zmin = np.min(X, 0)
Dmax = np.sqrt(np.sum(np.square(np.tile(Zmax, (n, 1))-X), 1))
Dmin = np.sqrt(np.sum(np.square(np.tile(Zmin, (n, 1))-X), 1))
S = Dmin/(Dmax+Dmin)
score = 100 * S/sum(S)
for i in range(len(score)):
print(f"第{i+1}个标准化后百分制得分为:{score[i]}")
示例
结果:
标签:Topsis,Python,矩阵,建模,指标,print,ans,np,正向 From: https://blog.csdn.net/2301_76716143/article/details/140243069