基于熵权法的topsis法的python实现

推荐一个学习的地方,详细易懂:

清风数学建模学习之TOPSIS法_lemontree_____的博客-CSDN博客

topsis法python代码实现,推荐:

Python实现TOPSIS分析法(优劣解距离法)_XHHP-CSDN博客

基于上述两个博客,对暑假建模训练题给出了基于熵权法的topsis法的python代码实现:

import numpy as np
import  xlrd
import pandas as pd
def read(file):
    wb = xlrd.open_workbook(filename=file)  #打开文件
    sheet = wb.sheet_by_index(0)  #通过索引获取表格
    rows = sheet.nrows    # 获取行数
    all_content = []        #存放读取的数据
    for j in range(1, 10):       #取第1~第9列对的数据
        temp = []
        for i in range(1,rows) :
            cell = sheet.cell_value(i, j)   #获取数据
            temp.append(cell)
        all_content.append(temp)    #按列添加到结果集中
        temp = []
    return np.array(all_content)

def entropy(data0):
    # 返回每个样本的指数
    # 样本数,指标个数
    n, m = np.shape(data0)
    # 一列一个样本,一行一个指标
    # 下面是归一化
    maxium = np.max(data0, axis=1)
    minium = np.min(data0, axis=1)
    data1=data0.copy()
    for i in range(0,9):
        data0[i]= (data0[i] - minium[i]) * 1.0 / (maxium[i] - minium[i])
    ##计算第j项指标,第i个样本占该指标的比重
    sumzb = np.sum(data0, axis=1)
    for i in range(0,9):
        data0[i] = data0[i] / sumzb[i]
    # 对ln0处理
    a = data0* 1.0
    a[np.where(data0== 0)] = 0.0001
    #    #计算每个指标的熵
    e = (-1.0 / np.log(m)) * np.sum(data0* np.log(a), axis=1)
    #    #计算权重
    w = (1 - e) / np.sum(1 - e)
    print(w)
    return w

# 极小型指标 -> 极大型指标
def dataDirection_1(datas):
    return (np.max(datas) - datas)  # 套公式


# 中间型指标 -> 极大型指标
def dataDirection_2(datas, x_best):
    temp_datas = datas - x_best
    M = np.max(abs(temp_datas))
    answer_datas = 1 - abs(datas - x_best) / M  # 套公式
    return answer_datas

# 区间型指标 -> 极大型指标
def dataDirection_3(datas, x_min, x_max):
    M = max(x_min - np.min(datas), np.max(datas) - x_max)
    answer_list = []
    for i in datas:
        if (i < x_min):
            answer_list.append(1 - (x_min - i) / M)  # 套公式
        elif (x_min <= i <= x_max):
            answer_list.append(1)
        else:
            answer_list.append(1 - (i - x_max) / M)
    return np.array(answer_list)

def temp2(datas):
    K = np.power(np.sum(pow(datas,2),axis =1),0.5)
    for i in range(0,K.size):
        for j in range(0,datas[i].size):
            datas[i,j] = datas[i,j] / K[i]      #套用矩阵标准化的公式
    return datas

def temp3(answer,w):
    list_max=[]
    for i in answer:
        list_max.append(np.max(i[:]))#获取每一列的最大值
    list_max=np.array(list_max)
    list_min =[]
    for i in answer:
        list_min.append(np.min(i[:]))#获取每一列的最小值
    list_min=np.array(list_min)
    max_list = []       #存放第i个评价对象与最大值的距离
    min_list = []       #存放第i个评价对象与最小值的距离
    answer_list=[]      #存放评价对象的未归一化得分
    for k in range(0,np.size(answer,axis = 1)):        #遍历每一列数据
        max_sum = 0
        min_sum = 0
        for q in range(0,9):                                #有四个指标
            max_sum +=w[q]*np.power(answer[q,k]-list_max[q],2)     #按每一列计算Di+
            min_sum +=w[q]*np.power(answer[q,k]-list_min[q],2)     #按每一列计算Di-
        max_list.append(pow(max_sum,0.5))
        min_list.append(pow(min_sum,0.5))
        answer_list.append(min_list[k]/ (min_list[k] + max_list[k]))    #套用计算得分的公式 Si = (Di-) / ((Di+) +(Di-))
        max_sum = 0
        min_sum = 0
    answer = np.array(answer_list)      #得分归一化
    return (answer / np.sum(answer))


def main():
    file = 'D:\\kong\\数学建模\\数据汇总.xlsx'
    answer1 = read(file)  # 读取文件
    answer2 = answer1.copy()
    for i in range(0,9):  # 按照不同的列,根据不同的指标转换为极大型指标,因为只有四列
        if i == 3:  # 中间型指标
            answer1[i] = dataDirection_2(answer1[i],0)
        elif i == 1 or i == 2 or i == 8:  # 极小型指标
            answer1[i] = dataDirection_1(answer1[i])
        else:# 本来就是极大型指标,不用转换
            answer1[i] = answer1[i]
    answer3 = temp2(answer1)  # 正向数组标准化
    w=entropy(answer2)#计算权重
    answer4 = temp3(answer3,w)  #topsis
    data = pd.DataFrame(answer4)  # 计算得分
    print(data)
    #将得分输出到excel表格中
    writer = pd.ExcelWriter('D:\\kong\\数学建模\\结果.xlsx')  # 写入Excel文件
    data.to_excel(writer, '得分', float_format='%.5f')  # ‘page_1’是写入excel的sheet名
    writer.save()
    writer.close()

if __name__=='__main__':
    main()

注意:我用的是pycharm,直接导入下载xlrd会出现pycharm no module named xlrd的问题

解决方法:

pycharm no module named xlrd的解决方案 - 简书

以下是使用熵权TOPSISPython代码示例: ```python import numpy as np import pandas as pd # 计算熵权 def entropyWeight(data): p = data / data.sum() entropy = (-p * np.log2(p)).sum() weight = (1 - entropy) / (len(data) - 1) return weight # 极小型指标转为极大型 def dataDirection_1(data): return 1 / data # 区间型指标转为极大型 def dataDirection_3(data, a, b, c, d): return (data - a) / (b - a) * (d - c) + c # 计算得分并排序(人工赋权重) def topsis(data, weight=None): Z = pd.DataFrame(\[data.max(), data.min()\], index=\['正理想解', '负理想解'\]) # 最优最劣方案(最大值Z^+ 和 最小值) weight = entropyWeight(data) if weight is None else np.array(weight) Result = data.copy() Result\['正理想解'\] = np.sqrt(((data - Z.loc\['正理想解'\]) ** 2 * weight).sum(axis=1)) # 评价对象与最大值的距离 Result\['负理想解'\] = np.sqrt(((data - Z.loc\['负理想解'\]) ** 2 * weight).sum(axis=1)) # 评价对象与最小值的距离 Result\['综合得分指数'\] = Result\['负理想解'\] / (Result\['负理想解'\] + Result\['正理想解'\]) # 综合得分指数 Result\['排序'\] = Result.rank(ascending=False)\['综合得分指数'\] return Result, Z, weight # 例题数据处理 data = pd.DataFrame({ '人均专著': \[0.1, 0.2, 0.4, 0.9, 1.2\], '生师比': \[5, 6, 7, 10, 2\], '科研经费': \[5000, 6000, 7000, 10000, 400\], '逾期毕业率': \[4.7, 5.6, 6.7, 2.3, 1.8\] }, index=\['院校' + i for i in list('ABCDE')\]) # 极小型指标转为极大型 minimum_list = dataDirection_1(data.loc\[:, "逾期毕业率"\]) minimum_array = np.array(minimum_list) minimum_4f = np.round(minimum_array, 6) # 区间型指标转为极大型 maximum_list = dataDirection_3(data.loc\[:, "生师比"\], 5, 6, 2, 12) maximum_array = np.array(maximum_list) maximum_4f = np.round(maximum_array, 6) # 指标正向化结果 index_Isotropy = pd.DataFrame() index_Isotropy\["人均专著"\] = data\["人均专著"\] index_Isotropy\["生师比"\] = maximum_4f index_Isotropy\["科研经费"\] = data\["科研经费"\] index_Isotropy\["逾期毕业率"\] = minimum_4f # 人工赋权重的结果 weight = \[0.2, 0.3, 0.4, 0.1\] Result, Z, weight = topsis(index_Isotropy, weight) ``` 这段代码实现了熵权TOPSIS的计算过程,包括指标转换、熵权计算、得分计算和排序。最终的结果存储在`Result`中,最优最劣方案存储在`Z`中,权重存储在`weight`中。 #### 引用[.reference_title] - *1* *2* *3* [TOPSIS(优劣解距离)【附Python实现代码及可视化代码】](https://blog.csdn.net/Michale_L/article/details/127832863)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值