TOPSIS法详细讲解+Python代码实现

news2024/12/24 21:07:19

🤵‍♂️ 个人主页:@艾派森的个人主页

✍🏻作者简介:Python学习者
🐋 希望大家多多支持,我们一起进步!😄
如果文章对你有帮助的话,
欢迎评论 💬点赞👍🏻 收藏 📂加关注+


目录

问题的提出

TOPSIS法

基本概念

模型原理

基本步骤

①原始矩阵正向化

②正向化矩阵标准化

③计算得分并归一化

Python代码实现


问题的提出

生活中我们常常要进行评价,上一篇文章我们讲到了层次分析法,通过确定各指标的权重,来进行打分,但层次分析法决策层不能太多,而且构造判断矩阵相对主观。哪有没有别的方法呢?

研究问题:明星A在当选微博之星后想找个对象,但喜欢他的人太多,不知道怎么选,经过层层考察,留下三个候选人。

从表中可以看出,候选人A颜值最高,但是脾气不好,一个月吵10次架,平均三天一次;候选人B颜值略微低于A,但是脾气要稍微好点;候选人C颜值虽然相比前两位较差,但是脾气是最好最稳定的。 

理想情况下:

  • 最好的对象应该是颜值9,脾气3
  • 最差的对象应该是颜值6,脾气10

思考:那怎么衡量A、B、C和最好、最差的距离呢?

  • 把(9,3),(6,10)作为二维平面的一个点
  • 距离最好点最近或者距离最差点最远的的就是综合条件最好的

在上图中红色的点就是最好的对象,蓝色的点就是最差的对象,三个黑点代表三位候选人,可以看出(6,3)距离红色点最近,距离蓝色点最远,可以说是综合条件最好的。

TOPSIS法

基本概念

        C.L.Hwang和K.Yoon于1981年首次提出 TOPSIS (Technique for 0rder Preference bySimilarity to an Ideal Solution),可翻译为逼近理想解排序法,国内常简称为优劣解距离法,。

        TOPSIS法是一种常用的综合评价方法,能充分利用原始数据的信息,其结果能精确地反映各评价方案之间的差距。TOPSIS法引入了两个基本概念:

  • 理想解:设想的最优的解(方案),它的各个属性值都达到各备选方案中的最好的值;
  • 负理想解:设想的最劣的解(方案),它的各个属性值都达到各备选方案中的最坏的值。

        方案排序的规则是把各备选方案与理想解和负理想解做比较,若其中有一个方案最接近理想解,而同时又远离负理想解,则该方案是备选方案中最好的方案。TOPSIS通过最接近理想解且最远离负理想解来确定最优选择。

模型原理

        TOPSIS法是一种理想目标相似性的顺序选优技术,在多目标决策分析中是一种非常有效的方法它通过归一化后(去量纲化)的数据规范化矩阵,找出多个目标中最优目标和最劣目标(分别用理归想一解化和反理想解表示),分别计算各评价目标与理想解和反理想解的距离,获得各目标与理想解的贴近度,按理想解贴近度的大小排序,以此作为评价目标优劣的依据。贴近度取值在0~1之间,该值愈接近1,表示相应的评价目标越接近最优水平;反之,该值愈接近0,表示评价目标越接近最劣水平。

基本步骤

1.将原始矩阵正向化:将原始矩阵正向化,就是要将所有的指标类型统一转化为极大型指标,因为有些指标并不是越大越好,它是越小越好,比如前面我们提到的吵架的次数。

2.正向矩阵标准化:标准化的方法有很多种,其主要目的就是去除量纲的影响,保证不同评价指标在同一数量级,且数据大小排序不变。

3.计算得分并归一化

S_{i}\doteq \frac{D_{i}^{-}}{D_{i}^{+}+D_{i}^{-}} 其中S_{i}为得分,D_{i}^{+}为评价对象与最大值的距离,D_{i}^{-}为评价对象与最小值的距离。

我们回到给明星A找对象这件事上

明星A考虑了一下觉得光靠颜值和脾气可能考虑的还不够全面,就又加上了身高和体重两个指标,而且他认为身高165是最好,体重在90-100斤是最好。

①原始矩阵正向化

在原始矩阵正向化之前,我们需要先知道都有哪些类型的指标,指标一共有如下四种:

将原始矩阵正向化,就是要将所有的指标类型统一转化为极大型指标。四种指标转化公式如下:

在了解了指标正向化的公式后,我们将原始指标进行正向化:

②正向化矩阵标准化

标准化的目的是消除不同指标量纲的影响。

假设有n个要评价的对象,m个评价指标(已正向化)构成的正向化矩阵如下:

那么,对其标准化的矩阵记为Z,Z中的每一个元素:

标准化后,还需给不同指标加上权重,采用的权重确定方法有层次分析法、熵权法、Delphi法
对数最小二乘法等。在这里认为各个指标的权重相同。将正向化矩阵标准化后如下:

③计算得分并归一化

上一步得到标准化矩阵Z

那么,我们可以计算得出第i(i= 1,2,…,n)个评价对象未归一化的得分:S_{i}\doteq \frac{D_{i}^{-}}{D_{i}^{+}+D_{i}^{-}}

很明显0≤S_{i}≤1,且S_{i}越大D_{i}^{+}越小,即越接近最大值。

我们可以将得分归一化并换成百分制:

首先对于前面的标准化矩阵计算得分:

然后再进行归一化并换算为百分制:

最后可以看出候选人B以微弱的优势胜出,所有最终明星A选择了候选人B作为对象。

Python代码实现

实现方法一:手动输入数据

import numpy as np #导入numpy库,用于选行科学计算
# 从用户输入中接收参评效目和指标数目,并将输入的字符事转换为数值
n = int(input("请输入参评数目:")) # 接收参评数目
m = int(input("请输入指标数目:")) # 接收指标数目
# 接收用户输入的类型矩阵,该矩阵指示了每个指标的类型(极大型、极小型等)
kind = input("请输入类型矩阵(1:极大型,2:极小型,3:中间型,4:区间型):").split(" ") # 将输入的字符串按空格分割,形成列表
# 接收用户输入的矩阵并转换为numpy数组
print("请输入矩阵:")
A = np.zeros(shape=(n,m)) #初 始化一个n行m列的全零矩阵A
for i in range(n):
    A[i] = input().split(" ") # 接收每行输入的数据
    A[i] = list(map(float, A[i])) # 将接收到的字符串列表转换为浮点数列表
print("输入矩阵为:\n{}".format(A)) # 打印输入的矩阵A

# 极小型指标转化为极大型指标的函数
def minTomax(maxx,x):
    x = list(x) # 将输入的指标效据转换为列表
    ans = [[(maxx-e)] for e in x]  # 计算最大值与每个指标值的差,并将其放入新列表中
    return np.array(ans) # 将列表转换为numpy数组并返回

# 中间型指标转化为极大型指标的函数
def midTomax(bestx,x):
    x = list(x) # 将输入的指标效据转换为列表
    h = [abs(e-bestx)for e in x] # 计算每个指标值与最优值之间的绝对差
    M = max(h) # 找到最大的差值
    if M == 0:
        M = 1 # 防止最大差值为0的情况
    ans = [[(1-e/M)]for e in h] # 计算每个差值占最大差值的比例,并从1中减去,得到新指标值
    return np.array(ans) # 返回处理后的numpy数组

# 区间型指标转化为极大型指标的函数
def regTomax(lowx,highx,x):
    x = list(x) # 将输入的指标效据转换为列表
    M = max(lowx-min(x),max(x)-highx) # 计算指标值超出区间的最大距高
    if M == 0:
        M = 1 # 防止最大距离为0的情况
    ans = []
    for i in range(len(x)):
        if x[i]<lowx:
            ans.append([(1-(lowx-x[i])/M)]) # 如果指标值小于下限,则计算其与下限的距离比例
        elif x[i]>highx:
            ans.append([(1-(x[i]-highx)/M)]) # 如果指标值大于上限,则计算其与上限的距离比例
        else:
            ans.append([1]) # 如果指标值在区间内,则直接职为1
    return np.array(ans) #返回处理后的numpy数组

# 统一指标类型,将所有指标转化为极大型指标
X = np.zeros(shape=(n,1))
for  i in range(m):
    if kind[i]=="1": # 如果当前指标为极大型,则直接使用原值
        v= np.array(A[:,i])
    elif kind[i]=="2": # 如果当前指标为极小型,调用minTomax函数转换
        maxA = max(A[:,i])
        v = minTomax(maxA,A[:,i])
    elif kind[i]=="3": # 如果当前指标为中间型,调用midTomax函数转换
        bestA = float(eval(input("【类型三】请输入最优值:")))
        v = midTomax(bestA,A[:,i])
    elif kind[i]=="4": #如果当前指标为区间型,调用regTomax的数转换
        lowA = float(eval(input("【类型四】请输入区间[a,b]值a:")))
        highA = float(eval(input("【类型四】请输入区间[a,b]值b:")))
        v = regTomax(lowA, highA, A[:,i])
    if i==0:
        X = v.reshape(-1,1) # 如果是第一个指标,直接替换X数组
    else:
        X= np.hstack([X,v.reshape(-1,1)]) # 如果不是第一个指标,则将新指标列拼接到X敬组上
print("统一指标后矩阵为:\n{}".format(X)) # 打印处理后的矩阵X

# 对统一指标后的矩阵X进行标准化处理
X = X.astype(float)
for j in range(m):
    X[:,j] = X[:,j]/np.sqrt(sum(X[:,j]**2)) # 对每一列数据进行归一化处理,即除以该列的欧几里得范效
print("标准化矩阵为:\n{}".format(X)) # 打印标准化后的矩阵X

# 最大值最小值距离的计算
x_max = np.max(X,axis=0) # 计算标准化矩阵每列的最大值
x_min= np.min(X,axis=0) # 计算标准化矩阵每列的最小值
d_z = np.sqrt(np.sum(np.square((X- np.tile(x_max,(n,1)))),axis=1)) # 计算每个参评对象与最优情况的距离d+
d_f = np.sqrt(np.sum(np.square((X- np.tile(x_min,(n,1)))),axis=1)) # 计算每个参评对象与最劣情况的距离d-
print('每个指标的最大值:',x_max)
print('每个指标的最小值:',x_min)
print('d+向量:',d_z)
print('d-向量:',d_f)

# 计算每个参评对象的得分排名
s = d_f/(d_z+d_f) # 根据d+和d-计算得分s,其中s接近于1则表示较优,接近于0则表示较劣
Score = 100*s/sum(s) # 将得分s转换为百分制,便于比较
for i in range(len(Score)):
    print(f"第{i+1}个标准化后百分制得分为:{Score[i]}") # 打印每个参评对象的得分

运行上面代码后,我们以前面的问题为例进行输入数据(明星A认为身高165是最好,体重在90-100斤是最好)。其中,参评数目就是三个候选人;指标数目就是颜值、吵架次数、身高、体重四个指标;类型矩阵颜值是极大型,吵架次数是极小型,身高是中间型,体重是区间型,所以对应输入为1 2 3 4 用空格隔开;在输入矩阵的时候,每行分别输入三个候选者的四个指标,用空格隔开,输入完一个候选者的指标后按回车键开启下一行;因为身高是类型三中间型,所有我们需要输入165;体重是区间型,依次输入90和100即可。

在输入上面的数据后,运行结果如下: 

从结果可以看出,第二个参评对象的得分最高为45.65,也就对应着候选人B。

实现方法二:导入外部文件数据

import numpy as np # 导入numpy包并将其命名为np

# 定义正向化的函数
def positivization(x,type,i):
    # x:需要正向化处理的指标对应的原始向量
    # type:指标类型(1:极小型,2:中间型,3:区间型)
    # i:正在处理的是原始矩阵的哪一列
    if type == 1:  #极小型
        print("第",i,"列是极小型,正向化中...")
        posit_x = x.max(0)-x
        print("第",i,"列极小型处理完成!")
        print("--------------------------分隔--------------------------")
        return posit_x
    elif type == 2:  #中间型
        print("第",i,"列是中间型")
        best = int(input("请输入最佳值:"))
        m = (abs(x-best)).max()
        posit_x = 1-abs(x-best)/m
        print("第",i,"列中间型处理完成!")
        print("--------------------------分隔--------------------------")
        return posit_x
    elif type == 3:  #区间型
        print("第",i,"列是区间型")
        a,b = [int(l) for l in input("按顺序输入最佳区间的左右界,并用逗号隔开:").split(",")]
        m = (np.append(a-x.min(),x.max()-b)).max()
        x_row = x.shape[0]  #获取x的行数
        posit_x = np.zeros((x_row,1),dtype=float)
        for r in range(x_row):
            if x[r] < a:
               posit_x[r] = 1-(a-x[r])/m
            elif x[r] > b:
               posit_x[r] = 1-(x[r]-b)/m
            else:
               posit_x[r] = 1
        print("第",i,"列区间型处理完成!")
        print("--------------------------分隔--------------------------")
        return posit_x.reshape(x_row)


## 第一步:从外部导入数据
# 推荐使用csv格式文件
x_mat = np.loadtxt('data.csv', encoding='UTF-8-sig', delimiter=',',skiprows=1)  

## 第二步:判断是否需要正向化
n, m = x_mat.shape
print("共有", n, "个评价对象", m, "个评价指标")
judge = int(input("指标是否需要正向化处理(需要请输入1,不需要则输入0):"))
if judge == 1:
    position = np.array([int(i) for i in input("请输入需要正向化处理的指标所在的列(例如第1、3、4列需要处理,则输入1,3,4):").split(',')])
    position = position-1
    typ = np.array([int(j) for j in input("请按照顺序输入这些列的指标类型(1:极小型,2:中间型,3:区间型)格式同上:").split(',')])
    for k in range(position.shape[0]):
        x_mat[:, position[k]] = positivization(x_mat[:, position[k]], typ[k], position[k])
    print("正向化后的矩阵:\n", x_mat)

## 第三步:对正向化后的矩阵进行标准化
tep_x1 = (x_mat * x_mat).sum(axis=0)  # 每个元素平方后按列相加
tep_x2 = np.tile(tep_x1, (n, 1))  # 将矩阵tep_x1平铺n行
Z = x_mat / ((tep_x2) ** 0.5)  # Z为标准化矩阵
print("标准化后的矩阵为:\n", Z)

## 第四步:计算与最大值和最小值的距离,并算出得分
tep_max = Z.max(0)  # 得到Z中每列的最大值
tep_min = Z.min(0)  # 每列的最小值
tep_a = Z - np.tile(tep_max, (n, 1))  # 将tep_max向下平铺n行,并与Z中的每个对应元素做差
tep_i = Z - np.tile(tep_min, (n, 1))  # 将tep_max向下平铺n行,并与Z中的每个对应元素做差
D_P = ((tep_a ** 2).sum(axis=1)) ** 0.5  # D+与最大值的距离向量
D_N = ((tep_i ** 2).sum(axis=1)) ** 0.5
S = D_N / (D_P + D_N)  # 未归一化的得分
std_S = S / S.sum(axis=0)
sorted_S = np.sort(std_S, axis=0)
print('标准化后的得分:',std_S)  # 打印标准化后的得分
## std_S.to_csv(std_S.csv)  结果输出到std_S.csv文件

在运行上面代码之前,需要准备csv格式的数据文件,同时需要注意文件路径,本实验代码与数据文件在同一目录下,本实验csv数据文件如下(还是以前面的问题为例):

代码运行后,系统会根据数据文件打印有多少个评价对象和评价指标,接着输入0或1表示是否需要正向化处理;然后输入需要正向化处理的列,这里吵架次数、身高、体重需要处理,对应着第2,3,4列,用英文逗号隔开;指标类型的话按照要求输入,1,2,3;输入中间型的最佳值165;输入区间型的左右界,90,100。

最后输入完,运行结果如下: 

可以看出结果与方法一得出的一致。

实现方法三:增加权重

前面两个方法中,我们是没有加上权重的,即默认权重都一样。那么假如现在我们在前面的问题中,分别给颜值、炒架次数、身高、体重赋上0.4、0.3、0.2、0.1的权重。那么我们就需要在正向矩阵标准化之后乘以对应的权重,代码如下:

import numpy as np #导入numpy库,用于选行科学计算
# 从用户输入中接收参评效目和指标数目,并将输入的字符事转换为数值
n = int(input("请输入参评数目:")) # 接收参评数目
m = int(input("请输入指标数目:")) # 接收指标数目
# 接收用户输入的类型矩阵,该矩阵指示了每个指标的类型(极大型、极小型等)
kind = input("请输入类型矩阵(1:极大型,2:极小型,3:中间型,4:区间型):").split(" ") # 将输入的字符串按空格分割,形成列表
# 接收用户输入的矩阵并转换为numpy数组
print("请输入矩阵:")
A = np.zeros(shape=(n,m)) #初 始化一个n行m列的全零矩阵A
for i in range(n):
    A[i] = input().split(" ") # 接收每行输入的数据
    A[i] = list(map(float, A[i])) # 将接收到的字符串列表转换为浮点数列表
print("输入矩阵为:\n{}".format(A)) # 打印输入的矩阵A

# 极小型指标转化为极大型指标的函数
def minTomax(maxx,x):
    x = list(x) # 将输入的指标效据转换为列表
    ans = [[(maxx-e)] for e in x]  # 计算最大值与每个指标值的差,并将其放入新列表中
    return np.array(ans) # 将列表转换为numpy数组并返回

# 中间型指标转化为极大型指标的函数
def midTomax(bestx,x):
    x = list(x) # 将输入的指标效据转换为列表
    h = [abs(e-bestx)for e in x] # 计算每个指标值与最优值之间的绝对差
    M = max(h) # 找到最大的差值
    if M == 0:
        M = 1 # 防止最大差值为0的情况
    ans = [[(1-e/M)]for e in h] # 计算每个差值占最大差值的比例,并从1中减去,得到新指标值
    return np.array(ans) # 返回处理后的numpy数组

# 区间型指标转化为极大型指标的函数
def regTomax(lowx,highx,x):
    x = list(x) # 将输入的指标效据转换为列表
    M = max(lowx-min(x),max(x)-highx) # 计算指标值超出区间的最大距高
    if M == 0:
        M = 1 # 防止最大距离为0的情况
    ans = []
    for i in range(len(x)):
        if x[i]<lowx:
            ans.append([(1-(lowx-x[i])/M)]) # 如果指标值小于下限,则计算其与下限的距离比例
        elif x[i]>highx:
            ans.append([(1-(x[i]-highx)/M)]) # 如果指标值大于上限,则计算其与上限的距离比例
        else:
            ans.append([1]) # 如果指标值在区间内,则直接职为1
    return np.array(ans) #返回处理后的numpy数组

# 统一指标类型,将所有指标转化为极大型指标
X = np.zeros(shape=(n,1))
for  i in range(m):
    if kind[i]=="1": # 如果当前指标为极大型,则直接使用原值
        v= np.array(A[:,i])
    elif kind[i]=="2": # 如果当前指标为极小型,调用minTomax函数转换
        maxA = max(A[:,i])
        v = minTomax(maxA,A[:,i])
    elif kind[i]=="3": # 如果当前指标为中间型,调用midTomax函数转换
        bestA = float(eval(input("【类型三】请输入最优值:")))
        v = midTomax(bestA,A[:,i])
    elif kind[i]=="4": #如果当前指标为区间型,调用regTomax的数转换
        lowA = float(eval(input("【类型四】请输入区间[a,b]值a:")))
        highA = float(eval(input("【类型四】请输入区间[a,b]值b:")))
        v = regTomax(lowA, highA, A[:,i])
    if i==0:
        X = v.reshape(-1,1) # 如果是第一个指标,直接替换X数组
    else:
        X= np.hstack([X,v.reshape(-1,1)]) # 如果不是第一个指标,则将新指标列拼接到X敬组上
print("统一指标后矩阵为:\n{}".format(X)) # 打印处理后的矩阵X
# 对统一指标后的矩阵X进行标准化处理
X = X.astype(float)
for j in range(m):
    X[:,j] = X[:,j]/np.sqrt(sum(X[:,j]**2)) # 对每一列数据进行归一化处理,即除以该列的欧几里得范效
print("标准化矩阵为:\n{}".format(X)) # 打印标准化后的矩阵X

# 给标准化后的矩阵加上权重
weights = [0.4,0.3,0.2,0.1]
temp_list = []
for i,j in zip(X.T,weights):
    temp_list.append(i*j)
import pandas as pd
new_X = pd.DataFrame(data=temp_list).T.to_numpy()
print("加上权重后的标准化矩阵为:\n{}".format(X)) # 打印加上权重后的标准化后的矩阵new_X

# 最大值最小值距离的计算
x_max = np.max(new_X,axis=0) # 计算标准化矩阵每列的最大值
x_min= np.min(new_X,axis=0) # 计算标准化矩阵每列的最小值
d_z = np.sqrt(np.sum(np.square((new_X- np.tile(x_max,(n,1)))),axis=1)) # 计算每个参评对象与最优情况的距离d+
d_f = np.sqrt(np.sum(np.square((new_X- np.tile(x_min,(n,1)))),axis=1)) # 计算每个参评对象与最劣情况的距离d-
print('每个指标的最大值:',x_max)
print('每个指标的最小值:',x_min)
print('d+向量:',d_z)
print('d-向量:',d_f)

# 计算每个参评对象的得分排名
s = d_f/(d_z+d_f) # 根据d+和d-计算得分s,其中s接近于1则表示较优,接近于0则表示较劣
Score = 100*s/sum(s) # 将得分s转换为百分制,便于比较
for i in range(len(Score)):
    print(f"第{i+1}个标准化后百分制得分为:{Score[i]}") # 打印每个参评对象的得分

代码运行结果如下:

从结果可以看出,如果给指标加上权重,最后的得分明显会不一样,此时候选人C得分最高。

实战案例

某一教育评估机构对5个研究生院进行评估。该机构选取了4个评价指标:人均专著、生师比、科研经费、逾期毕业率。

解释:人均专著和科研经费是效益性指标,逾期毕业率是成本型指标,生师比是区间型指标,最优范围是[5,6]。4个指标权重采用专家打分的结果,分别为0.2,0.3,0.40.1

代码如下:

import numpy as np # 导入numpy包并将其命名为np

# 定义正向化的函数
def positivization(x,type,i):
    # x:需要正向化处理的指标对应的原始向量
    # type:指标类型(1:极小型,2:中间型,3:区间型)
    # i:正在处理的是原始矩阵的哪一列
    if type == 1:  #极小型
        print("第",i,"列是极小型,正向化中...")
        posit_x = x.max(0)-x
        print("第",i,"列极小型处理完成!")
        print("--------------------------分隔--------------------------")
        return posit_x
    elif type == 2:  #中间型
        print("第",i,"列是中间型")
        best = int(input("请输入最佳值:"))
        m = (abs(x-best)).max()
        posit_x = 1-abs(x-best)/m
        print("第",i,"列中间型处理完成!")
        print("--------------------------分隔--------------------------")
        return posit_x
    elif type == 3:  #区间型
        print("第",i,"列是区间型")
        a,b = [int(l) for l in input("按顺序输入最佳区间的左右界,并用逗号隔开:").split(",")]
        m = (np.append(a-x.min(),x.max()-b)).max()
        x_row = x.shape[0]  #获取x的行数
        posit_x = np.zeros((x_row,1),dtype=float)
        for r in range(x_row):
            if x[r] < a:
               posit_x[r] = 1-(a-x[r])/m
            elif x[r] > b:
               posit_x[r] = 1-(x[r]-b)/m
            else:
               posit_x[r] = 1
        print("第",i,"列区间型处理完成!")
        print("--------------------------分隔--------------------------")
        return posit_x.reshape(x_row)


## 第一步:从外部导入数据
# 推荐使用csv格式文件
x_mat = np.loadtxt('TOPSIS案例.csv', encoding='UTF-8-sig', delimiter=',',skiprows=1,usecols=[1,2,3,4])  

## 第二步:判断是否需要正向化
n, m = x_mat.shape
print("共有", n, "个评价对象", m, "个评价指标")
judge = int(input("指标是否需要正向化处理(需要请输入1,不需要则输入0):"))
if judge == 1:
    position = np.array([int(i) for i in input("请输入需要正向化处理的指标所在的列(例如第1、3、4列需要处理,则输入1,3,4):").split(',')])
    position = position-1
    typ = np.array([int(j) for j in input("请按照顺序输入这些列的指标类型(1:极小型,2:中间型,3:区间型)格式同上:").split(',')])
    for k in range(position.shape[0]):
        x_mat[:, position[k]] = positivization(x_mat[:, position[k]], typ[k], position[k])
    print("正向化后的矩阵:\n", x_mat)

## 第三步:对正向化后的矩阵进行标准化
tep_x1 = (x_mat * x_mat).sum(axis=0)  # 每个元素平方后按列相加
tep_x2 = np.tile(tep_x1, (n, 1))  # 将矩阵tep_x1平铺n行
Z = x_mat / ((tep_x2) ** 0.5)  # Z为标准化矩阵
print("标准化后的矩阵为:\n", Z)

# 给标准化后的矩阵加上权重
weights = [0.2,0.3,0.4,0.1]
temp_list = []
for i,j in zip(Z.T,weights):
    temp_list.append(i*j)
import pandas as pd
new_Z = pd.DataFrame(data=temp_list).T.to_numpy()
print("加上权重后的标准化矩阵为:\n{}".format(new_Z)) # 打印加上权重后的标准化后的矩阵new_X

## 第四步:计算与最大值和最小值的距离,并算出得分
tep_max = new_Z.max(0)  # 得到Z中每列的最大值
tep_min = new_Z.min(0)  # 每列的最小值
tep_a = new_Z - np.tile(tep_max, (n, 1))  # 将tep_max向下平铺n行,并与Z中的每个对应元素做差
tep_i = new_Z - np.tile(tep_min, (n, 1))  # 将tep_max向下平铺n行,并与Z中的每个对应元素做差
D_P = ((tep_a ** 2).sum(axis=1)) ** 0.5  # D+与最大值的距离向量
D_N = ((tep_i ** 2).sum(axis=1)) ** 0.5
S = D_N / (D_P + D_N)  # 未归一化的得分
std_S = S / S.sum(axis=0)
sorted_S = np.sort(std_S, axis=0)
print('标准化后的得分:',[x*100 for x in std_S])  # 打印标准化后的得分

在导入数据文件的时候,我们需要选取指标所在列,故需要再np.loadtxt()函数中加上参数usecols=[1,2,3,4],注意在Python中索引是从0开始的,0列对应的就是研究生院。同时我们还需要再代码中添加权重weights = [0.2,0.3,0.4,0.1]。

代码运行结果:

从结果可以看出4号研究生院以得分22.73微弱的优势胜出。

资料获取,更多粉丝福利,关注下方公众号获取

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2113327.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构——双链表实现和注释浅解

关于双链表的基础部分增删查改的实现和一点理解&#xff0c;写在注释里~ 前言 浅记 1. 哨兵位的节点不能被删除&#xff0c;节点的地址也不能发生改变&#xff0c;所以是传一级指针 2. 哨兵位并不存储有效数据&#xff0c;所以它并不是有效节点 3. 双向链表为空时&#xff…

单点登录:cas单点登录实现原理浅析

cas单点登录实现原理浅析 一晃几个月没写博客了&#xff0c;今年多灾多难的一年。 安能摧眉折腰事权贵&#xff0c;使我不得开心颜&#xff01; 财富是对认知的补偿&#xff0c;不是对勤奋的嘉奖。勤奋只能解决温饱&#xff0c;要挣到钱就得预知风口&#xff0c;或者有独到见解…

探寻 IP 代理地址繁多之因

在当今的网络天地里&#xff0c;IP 代理服务随处可见&#xff0c;且令人称奇的是&#xff0c;它们常常手握海量的 IP 地址可供挑选。那么&#xff0c;究竟是什么原因使得 IP 代理拥有如此众多的地址呢&#xff1f;现在&#xff0c;就让我们一同深入探究这个神秘现象背后的缘由。…

Camunda调用子流程案例

调用子流程 调用子流程是指子流程在主流程的外面。子流程一般是多个流程可重用的流程&#xff0c;也可以独立调用子流程。 可以对比编程中的方法抽取。子流程运行时&#xff0c;主流程也是等待状态。子流程结束&#xff0c;主流程继续。 BPMN设计 主流程 全局配置 上传视频 处…

并查集基础与简单扩展应用

并查集 基础题目路径压缩 扩展应用扩展题目1扩展题目2 并查集的结构是一棵树 并查集有两种功能&#xff0c;一种是判断两个元素是否在同一集合&#xff0c;第二种是合并两个集合 并查集的实现需要记录每个节点的父亲节点 判断两个元素是否在同一集合&#xff0c;即判断两个元…

ARM编程模型、指令集、ARM汇编语言程序设计

一、编程模型 1.1数据和指令类型 在之后的演示当中&#xff0c;我们大多数将采用ARM指令集 1.2处理器工作模式 1.3ARM寄存器 1.3.1分类 &#xff08;1&#xff09; 31 个通用寄存器&#xff0c;包括 PC&#xff08;程序计数器&#xff09;在内&#xff0c;都是 32 位的寄存器…

实习项目|苍穹外卖|day7

缓存菜品 1.根据原型进行需求分析与设计&#xff08;接口文档&#xff09; 2.根据接口设计DTO&#xff08;redis数据类型选取&#xff09; 3.编码controller-》service-》mapper GetMapping("/list")ApiOperation("根据分类id查询菜品")public Result<…

51单片机-第十三节-直流电机驱动(PWM)

一、直流电机介绍&#xff1a; 直流电机是一种将电能转换为机械能的装置。 一般的直流电机有两个电极&#xff0c;电极正接&#xff0c;电机正转&#xff0c;电极反接&#xff0c;电机反转。 直流电机主要由永磁体&#xff08;定子&#xff09;、线圈&#xff08;转子&#…

GB35114 USC安防平台 中星微国密摄像机配置 流程

中星微国密摄像机配置介绍 如下以中星微VS-IPC8021S-Y-T4摄像机为例&#xff0c;需要先各自获取p10文件&#xff0c;并通过证书签发机构或者测试SM2证书签发获取证书。 网络配置如下: 摄像机的IP地址为192.168.1.108&#xff0c;国标ID为34020000001320000015 系统的IP地址…

Robotframework框架基础

1.Robot Framework是开源的自动化测试框架&#xff0c;基于关键字驱动的测试方法2.它提供用于创建和执行自动化测试的工具和库&#xff0c;并支持使用不同的测试库和插件进行扩展 一.以下是Robot Framework框架的基础知识 1. 安装&#xff1a;通过pip安装Robot Framework和相…

打造可视化数字大屏供应链管理平台详解:从食堂采购系统源码开始

这篇文章将深入探讨直播美颜SDK与主播美颜工具的技术原理及其发展趋势&#xff0c;帮助开发者了解如何通过技术手段实现流畅、高效的实时美颜效果。 一、什么是直播美颜SDK&#xff1f; 直播美颜SDK是一种为开发者提供实时美颜功能的集成开发工具包。它通过对摄像头捕捉到的画…

现代计算机中数字的表示与浮点数、定点数

现代计算机中数字的表示与浮点数、定点数 导读&#xff1a;浮点数运算是一个非常有技术含量的话题&#xff0c;不太容易掌握。许多程序员都不清楚使用操作符比较float/double类型的话到底出现什么问题。这篇文章讲述了浮点数的来龙去脉&#xff0c;所有的软件开发人员都应该读…

轻松搞定用户认证:微搭低代码平台打造完美登录体验01用户登录

目录 1 创建数据源2 搭建后端API3 用户登录4 最终的代码总结 欢迎阅读我们的微搭低代码全栈开发课程&#xff0c;这是我们的第二篇。在第一篇中我们整体描述了小程序的功能结构&#xff0c;这一篇我们就进入实际的开发。 在开发小程序的时候&#xff0c;第一个需要考虑的就是用…

数据结构基础讲解(一)——线性表之顺序表专项练习

本文数据结构讲解参考书目&#xff1a; 通过网盘分享的文件&#xff1a;数据结构 C语言版.pdf 链接: https://pan.baidu.com/s/159y_QTbXqpMhNCNP_Fls9g?pwdze8e 提取码: ze8e 目录 前言 一.线性表的定义 二.线性表的基本操作 三.线性表的顺序存储和表示 四.顺序表中基本操作…

如何设置好看的电脑屏保?电脑屏保设置教程

如何设置好看的电脑屏保&#xff1f;电脑屏保设置教程。大家好&#xff0c;今天小编给大家带来了好看的电脑屏保&#xff0c;教大家如何设置一个好看的电脑屏保。屏保软件很多&#xff0c;今天我们介绍一款比较有特殊的屁屏保软件&#xff1a;芝麻时钟&#xff08;芝麻时钟 桌面…

【C++二分查找】1760. 袋子里最少数目的球

本文涉及的基础知识点 C二分查找 LeetCode1760. 袋子里最少数目的球 给你一个整数数组 nums &#xff0c;其中 nums[i] 表示第 i 个袋子里球的数目。同时给你一个整数 maxOperations 。 你可以进行如下操作至多 maxOperations 次&#xff1a; 选择任意一个袋子&#xff0c;并…

AMEsim和Simulink联合仿真生成新的.mexw64液压模型文件

AMEsim和Simulink进行联合仿真非常重要的就是AMEsim经过第四阶段Simulation会在相同文件下面生成一个与AMEsim液压模型相同名字的.mexw64文件&#xff0c;在Simulink进行联合仿真的S-Function需要找的也就是这个文件&#xff0c;只不过输入的时候除了液压模型名字之外&#xff…

形态学运算合集

圆形结构元素 禹晶、肖创柏、廖庆敏《数字图像处理&#xff08;面向新工科的电工电子信息基础课程系列教材&#xff09;》 禹晶、肖创柏、廖庆敏《数字图像处理》资源二维码

Post-Training有多重要?一文带你了解全部细节

1. 简介 随着LLM学界和工业界日新月异的发展&#xff0c;不仅预训练所用的算力和数据正在疯狂内卷&#xff0c;后训练&#xff08;post-training&#xff09;的对齐和微调方法也在不断更新。InstructGPT、WebGPT等较早发布的模型使用标准RLHF方法&#xff0c;其中的数据管理风…

Git撤销add

git要提交版本第一步是add&#xff0c;就算是文件本身已经存在只是修改&#xff0c;也需要添加&#xff0c;即添加到暂存区。其中最偷懒和也保险的命令是&#xff1a; git add . 即添加了本地&#xff08;多称工作目录&#xff09;所有文件。 撤销add有以下文章&#xff1a; …