Topsis综合评价分析2021年C题第1问——python实现

2021年数学建模C题,解决其第一问

一、问题分析:

1.1问题:

根据附件 1,对 402 家供应商的供货特征进行量化分析,建立反映保障企业生产重要性的数学模型,在此基础上确定 50 家最重要的供应商,并在论文中列表给出结果。

1.2分析:

显而易见这是评价类问题,题目没有给出具体评价指标,我们自主构建,这里选取四个指标——供货强度、完成率、订单率和风险作为指标对供应商的重要性进行评估。

1.3指标构建:

                 供货强度:240周总供货量(第二个表每一行的总计)

                 完成率:240周总供货量/240周总订货量(2表每行总计/1表每行总计)

                 订单率:订单量大于10的周数/240

                 风险:供货量标准差(2表每行标准差)

二、Topsis:

前提条件:指标由数值衡量,稍后我们将对指标进行评分

2.1指标分类——原始矩阵正向化:

    

风险为极小型指标,这样处理!!!

完成率为中间型指标这样处理!!!

当然别忘了还有一种区间型指标,本题没用到

 2.2消除量纲的影响:

标准化还有很多方法,如Z-score 标准化,最小-最大归一化,均值归一化,正则化等,大家可以多多尝试,本文使用的是L2 正则化。

2.3构造计算评分的公式:

单指标:

                               

不足:最大和最小值永远都是1和0。

多指标:

注意:!不要纠结欧氏距离还是曼哈顿距离,都可以的,图片中是欧氏距离。

拓:指标权重,可以根据指标的重要性赋予一定的权重系数

哦豁,最后有一个小惊喜,我还以为上一篇看的那个层次分析法用不到了,没想到可以用在这里给指标确定权重,不错不错nice。

2.4归一化:

(比较简单,略)

三、具体代码:

3.1每一步代码解释:

1.首先导入数据,并计算出我们的四个指标,构成新的df。

import numpy as np
import pandas as pd

# 指定 Excel 文件的路径
path = "附件1 近5年402家供应商的相关数据.xlsx"

# 读取两个表
sheet1 = pd.read_excel(path, sheet_name='企业的订货量(m³)')
sheet2 = pd.read_excel(path, sheet_name='供应商的供货量(m³)')

# 计算每一行的总订货量和总供货量
total_order = sheet1.sum(axis=1)
total_supply = sheet2.sum(axis=1)

# 计算完成率
completion_rate = total_supply / total_order

# 创建一个新的 DataFrame 来存储结果
df = pd.DataFrame({
    'Total_Supply': total_supply,
    'Completion_Rate': completion_rate
})

# 计算订单率:订单量大于10的周数 / 240
orders_above_10 = (sheet1.iloc[:, 2:] > 10).sum(axis=1)
df['Order_Rate'] = orders_above_10 / 240

# 计算供货量的标准差
df['Supply_StdDev'] = sheet2.std(axis=1)

2.指标正向化

 风险为极小型指标,这样处理!!!(具体公式见前面)

#对极小型风险指标正向化处理
max_value = df['Supply_StdDev'].max()
df['Supply_StdDe'] = df['Supply_StdDev'].apply(lambda x: max_value - x)

完成率为中间型指标这样处理!!!(具体公式见前面)

max_distance = (df['Completion_Rate'] - 1).abs().max()
df['Normalized_Completion_Rate'] = ((df['Completion_Rate'] - 1).abs() / max_distance).apply(lambda x: 1 - x)

3.消除量纲影响

# 使用 L2 正则化对每一列进行处理
df = df.apply(lambda x: x / np.sqrt(np.sum(np.square(x))))

4.计算得分

# 定义最大值和最小值矩阵
Z_plus = df.max()
Z_minus = df.min()

# 计算每个评价对象与最大值的距离 D^+
D_plus = np.sqrt(((df - Z_plus) ** 2).sum(axis=1))

# 计算每个评价对象与最小值的距离 D^-
D_minus = np.sqrt(((df - Z_minus) ** 2).sum(axis=1))

# 计算未归一化的得分 S_i
S_i = D_minus / (D_plus + D_minus)

df['Score'] = S_i/S_i.sum(axis=0)

5.排序输出结果(在排序前将供应商编号设为索引,排序后即可根据索引看出得分对应的供应商编号)

df['ID']=sheet1.iloc[:, 0]
df.set_index('ID', inplace=True)

df= df.sort_values(by='Score')

df

由图可以看出,得分最高的为S083,最低的为S140(ps:本题没有缺失数据,不需要预处理)

3.2代码汇总:

import numpy as np
import pandas as pd

# 指定 Excel 文件的路径
path = "附件1 近5年402家供应商的相关数据.xlsx"

# 读取两个表
sheet1 = pd.read_excel(path, sheet_name='企业的订货量(m³)')
sheet2 = pd.read_excel(path, sheet_name='供应商的供货量(m³)')

# 计算每一行的总订货量和总供货量
total_order = sheet1.sum(axis=1)
total_supply = sheet2.sum(axis=1)

# 计算完成率
completion_rate = total_supply / total_order

# 创建一个新的 DataFrame 来存储结果
df = pd.DataFrame({
    'Total_Supply': total_supply,
    'Completion_Rate': completion_rate
})

# 计算订单率:订单量大于10的周数 / 240
orders_above_10 = (sheet1.iloc[:, 2:] > 10).sum(axis=1)
df['Order_Rate'] = orders_above_10 / 240

# 计算供货量的标准差
df['Supply_StdDev'] = sheet2.std(axis=1)

max_value = df['Supply_StdDev'].max()
df['Supply_StdDe'] = df['Supply_StdDev'].apply(lambda x: max_value - x)

max_distance = (df['Completion_Rate'] - 1).abs().max()
df['Normalized_Completion_Rate'] = ((df['Completion_Rate'] - 1).abs() / max_distance).apply(lambda x: 1 - x)

# 使用 L2 正则化对每一列进行处理
df = df.apply(lambda x: x / np.sqrt(np.sum(np.square(x))))

# 定义最大值和最小值矩阵
Z_plus = df.max()
Z_minus = df.min()

# 计算每个评价对象与最大值的距离 D^+
D_plus = np.sqrt(((df - Z_plus) ** 2).sum(axis=1))

# 计算每个评价对象与最小值的距离 D^-
D_minus = np.sqrt(((df - Z_minus) ** 2).sum(axis=1))

# 计算未归一化的得分 S_i
S_i = D_minus / (D_plus + D_minus)

df['Score'] = S_i/S_i.sum(axis=0)

df['ID']=sheet1.iloc[:, 0]
df.set_index('ID', inplace=True)

df= df.sort_values(by='Score')

df

四、番外:权重的确定

无数据用层次分析法,有数据用熵权法。

接下来主要介绍熵权法,层次分析法见另一篇文章——层次分析法AHP(评价类问题)-优快云博客

4.1熵权法:

原理:指标变异程度越小(可片面理解为方差),所反映信息量越少,所对应的权值越低。

通俗解释:如果所有方案的某一指标数值相同,则该指标对方案评价排名无作用,权值应该为0.

4.2基本概念:

信息量:概率越大,信息量越小

信息熵——某事件的信息量期望:根据期望公式和信息量公式结合可得

信息熵越大,信息量越小,信息熵最大值为lnn(证明见图)

信息熵与信息量成反比,所以我们引入信息效用值:1-信息熵,代表事件信息量大小

4.3计算步骤:

1.计算指标信息熵

利用topsis第一步正向化和第二步消除量纲后得到的矩阵,我们计算出每个指标对应的信息熵,从而确定每个指标对应的权重。

指标=事件,n种方案=事件可能发生的n种情况,每种方案对应概率=该方案指标数值/总方案指标数值,如图:

2.对信息熵归一化处理

除以lnn,因为信息熵最大值为lnn,所以可将所有信息熵数值映射到[0,1]区间。

 信息熵公式:

3.计算信息效用值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值