Python实现的综合评价系统TOPSIS法代码详解

一、引言

        在许多实际应用场景中,我们需要对多个项目基于多个指标进行综合评价。例如在企业对不同产品的性能评估、学校对学生综合能力的评价等。本文将详细介绍一个用 Python 编写的综合评价系统代码,该代码通过一系列数据处理和计算步骤,能够对输入的项目指标数据进行统一化、标准化处理,并最终得出每个项目的综合得分。

二、代码整体结构

        代码定义了一个EvaluationSystem类,类中包含多个方法,分别负责输入矩阵数据、统一指标类型、标准化矩阵以及计算项目得分等功能。

三、代码详细解释

(一)类的初始化

class EvaluationSystem:
    def __init__(self):
        self.n = None
        self.m = None
        self.a = None
        self.kind = None
        self.unified_matrix = None
        self.standardized_matrix = None
        self.scores = None

        在__init__方法中,初始化了类的多个属性。n用于存储参评的项目数,m用于存储参评指标数,a用于存储输入的矩阵数据,kind用于存储每个指标的类型,unified_matrix用于存储统一指标后的矩阵,standardized_matrix用于存储标准化后的矩阵,scores用于存储每个项目的最终得分。

(二)极小值指标转化为极大值指标

@staticmethod
def min_to_max(max_x, x):
    x_list = list(x)
    h = [abs(max_x - i) for i in x_list]
    return np.array(h)

         这个静态方法min_to_max的作用是将极小值指标转化为极大值指标。它接收两个参数,max_x是当前指标中的最大值,x是包含该指标所有数据的数组。通过计算每个数据与最大值的差值的绝对值,将极小值指标转化为极大值指标形式,以便后续统一处理。

(三)中间值指标转化为极大值指标

@staticmethod
def mid_to_max(best_x, x):
    x_list = list(x)
    h = [abs(best_x - i) for i in x_list]
    m = max(h)
    if m == 0:
        m = 1
    ans = [1 - i / m for i in h]
    return np.array(ans)

   mid_to_max方法用于将中间值指标转化为极大值指标。它接收best_x(该指标的最优中间值)和x(指标数据数组)作为参数。首先计算每个数据与最优中间值的差值的绝对值,然后找出这些差值绝对值中的最大值m。如果m为 0(表示所有数据都等于最优中间值),则将m设为 1。最后通过公式1 - i / m计算转化后的值,得到转化为极大值指标形式的数据。

(四)区间性指标转化为极大值指标

@staticmethod
def reg_to_max(min_x, max_x, x):
    x_list = list(x)
    m = max(min_x - min(x_list), max(x_list) - max_x)
    if m == 0:
        m = 1
    for i in range(len(x_list)):
        if x_list[i] < min_x:
            x_list[i] = 1 - (min_x - x_list[i]) / m
        elif x_list[i] > max_x:
            x_list[i] = 1 - (x_list[i] - max_x) / m
        else:
            x_list[i] = 1
    return np.array(x_list)

    reg_to_max方法处理区间性指标转化为极大值指标。它接收min_x(区间最小值)、max_x(区间最大值)和x(指标数据数组)作为参数。首先计算数据与区间边界差值的最大值m,如果m为 0 则设为 1。然后遍历数据数组,对于小于区间最小值的数据,通过公式1 - (min_x - x_list[i]) / m进行转化;对于大于区间最大值的数据,通过公式1 - (x_list[i] - max_x) / m进行转化;在区间内的数据则直接设为 1。最终返回转化后的数组。

(五)输入矩阵数据

def input_matrix(self):
    print('请输入参评的项目数:')
    self.n = int(input())
    print('请输入参评指标数:')
    self.m = int(input())
    print('请输入矩阵(用","分隔):')
    np_array = np.zeros(shape=(self.n, self.m))
    for i in range(self.n):
        try:
            row = input().split(',')
            if len(row) != self.m:
                print(f"输入的第 {i + 1} 行元素数量不正确,请输入 {self.m} 个元素。")
                return None
            np_array[i] = [float(num) for num in row]
        except ValueError:
            print(f"输入的第 {i + 1} 行包含非数字元素,请重新输入。")
            return None
    print('输入的矩阵为:\n{}'.format(np_array))
    self.a = np_array
    return np_array

   input_matrix方法用于获取用户输入的项目指标矩阵。首先提示用户输入参评项目数n和参评指标数m。然后创建一个全零的numpy数组np_array,其形状为(n, m)。通过循环,逐行获取用户输入的数据,将输入的字符串以逗号分隔并转换为浮点数列表,赋值给np_array的对应行。如果输入的行元素数量不正确或包含非数字元素,会给出相应提示并返回None。最后将输入的矩阵打印出来,并赋值给类属性a,同时返回该矩阵。

(六)统一指标类型

def unify_matrix(self):
    if self.a is None:
        self.a = self.input_matrix()
    if self.a is None:
        print("矩阵输入有误,程序退出。")
        return None
    print('请依次输入每一个参评指标的类型(用","分隔):1 极大型,2 极小型,3 中立型,4 区间型')
    self.kind = input().split(',')
    if len(self.kind) != self.m:
        print("类型矩阵的长度与指标数不匹配,程序退出。")
        return None
    x = np.zeros(shape=(self.n, 1))
    for i in range(self.m):
        if self.kind[i] == '1':
            v = np.array(self.a[:, i])
        elif self.kind[i] == '2':
            max_x = max(self.a[:, i])
            v = self.min_to_max(max_x, self.a[:, i])
        elif self.kind[i] == '3':
            try:
                best_x = float(input('请输入第{}个指标的最优值:'.format(i + 1)))
                v = self.mid_to_max(best_x, self.a[:, i])
            except ValueError:
                print("输入的最优值不是有效的数字,程序退出。")
                return None
        elif self.kind[i] == '4':
            try:
                min_x = float(input('请输入第{}个指标的最小值:'.format(i + 1)))
                max_x = float(input('请输入第{}个指标的最大值:'.format(i + 1)))
                v = self.reg_to_max(min_x, max_x, self.a[:, i])
            except ValueError:
                print("输入的最小值或最大值不是有效的数字,程序退出。")
                return None
        else:
            print('输入的指标类型错误,程序退出。')
            return None
        if i == 0:
            x = v.reshape(-1, 1)
        else:
            x = np.hstack([x, v.reshape(-1, 1)])
    print('统一指标后的矩阵为:\n{}'.format(x))
    self.unified_matrix = x
    return x

   unify_matrix方法用于将不同类型的指标统一为极大值指标类型。首先检查类属性a是否为None,如果是则调用input_matrix方法获取矩阵数据。如果获取矩阵数据失败,打印错误信息并退出程序。接着提示用户输入每个指标的类型,将输入的字符串以逗号分隔存储在kind列表中。检查kind列表的长度是否与指标数m一致,如果不一致则打印错误信息并退出程序。通过循环遍历每个指标,根据指标类型调用相应的转化方法(极大型指标直接使用原数据,极小型、中间值型、区间型指标分别调用对应的转化方法)。将转化后的数据逐列合并成一个新的矩阵x,最后打印统一指标后的矩阵,并赋值给类属性unified_matrix,同时返回该矩阵。

(七)标准化矩阵

def standardize_matrix(self):
    if self.unified_matrix is None:
        self.unify_matrix()
    if self.unified_matrix is None:
        return None
    col_sums = np.sum(self.unified_matrix**2, axis=0)
    self.standardized_matrix = self.unified_matrix / np.sqrt(col_sums)
    print('标准化后的矩阵:\n', self.standardized_matrix)
    return self.standardized_matrix

   standardize_matrix方法用于对统一指标后的矩阵进行标准化处理。首先检查类属性unified_matrix是否为None,如果是则调用unify_matrix方法获取统一指标后的矩阵。如果获取失败,返回None。然后计算统一指标后矩阵每列元素平方和col_sums,通过将统一指标后的矩阵除以每列元素平方和的平方根,得到标准化后的矩阵。打印标准化后的矩阵,并赋值给类属性standardized_matrix,同时返回该矩阵。

(八)计算项目得分

def calculate_scores(self):
    if self.standardized_matrix is None:
        self.standardize_matrix()
    if self.standardized_matrix is None:
        return None
    max_x = np.max(self.standardized_matrix, axis=0)
    min_x = np.min(self.standardized_matrix, axis=0)
    d_positive = np.sqrt(np.sum(np.square((self.standardized_matrix - np.tile(max_x, (self.standardized_matrix.shape[0], 1)))), axis=1))
    d_negative = np.sqrt(np.sum(np.square((self.standardized_matrix - np.tile(min_x, (self.standardized_matrix.shape[0], 1)))), axis=1))
    score = d_negative / (d_positive + d_negative)
    score = 100 * score / sum(score)
    for i in range(len(score)):
        print(f'第{i + 1}个项目的得分为:{score[i]}')
    self.scores = score
    return score

   calculate_scores方法用于计算每个项目的最终得分。首先检查类属性standardized_matrix是否为None,如果是则调用standardize_matrix方法获取标准化后的矩阵。如果获取失败,返回None。然后找出标准化矩阵每列的最大值max_x和最小值min_x。通过计算每个项目与最大值向量和最小值向量的欧氏距离,分别得到正理想解距离d_positive和负理想解距离d_negative。根据公式计算每个项目的得分score,并将得分进行归一化处理(乘以 100 并除以所有得分之和)。最后打印每个项目的得分,并赋值给类属性scores,同时返回得分数组。

(九)运行系统

def run(self):
    self.calculate_scores()

   run方法是整个评价系统的入口,它调用calculate_scores方法开始执行评价流程,最终计算并输出每个项目的得分。

四、代码使用示例

        在if __name__ == '__main__':代码块中,创建了EvaluationSystem类的实例system,并调用system.run()启动评价系统。用户按照提示依次输入参评项目数、参评指标数、项目指标矩阵以及每个指标的类型等信息,系统会逐步进行数据处理并输出每个项目的最终得分。

五、总结

        本文详细介绍的 Python 评价系统代码,通过一系列有序的步骤实现了对多个项目基于多个不同类型指标的综合评价。从数据输入、指标类型统一、矩阵标准化到最终得分计算,每个环节都有清晰的逻辑和功能实现。该代码具有一定的通用性和扩展性,可根据实际需求进一步优化和完善,应用于更多的综合评价场景中。

作者:狗蛋不是狗

物联沃分享整理
物联沃-IOTWORD物联网 » Python实现的综合评价系统TOPSIS法代码详解

发表回复