当前位置:   article > 正文

数学建模(熵权法 python代码 例子)

数学建模(熵权法 python代码 例子)

目录

介绍: 

模板:

例子:择偶

极小型指标转化为极大型(正向化):

中间型指标转为极大型(正向化):

区间型指标转为极大型(正向化):

标准化处理:

公式:

熵权:

公式:

​​​完整代码:

结果:

介绍: 

熵权法是一种多属性决策方法,用于确定各个属性在决策中的重要程度。该方法的核心思想是通过计算属性的熵值,来评估属性的信息量和不确定性,进而确定属性的权重。

熵是信息论中的概念,表示一个随机变量的不确定性。在决策中,一个属性的熵越大,说明该属性对决策的贡献越大,因为它包含了更多的信息。熵权法通过计算属性的熵,然后将每个属性的熵除以总的熵,得到每个属性的权重。

具体步骤如下:

  1. 收集决策所涉及的属性数据。
  2. 计算每个属性的熵值,使用熵的计算公式:熵 = -Σ(p*log2(p)),其中p表示属性的概率。
  3. 计算所有属性的熵之和,得到总的熵。
  4. 计算每个属性的权重,使用该属性的熵除以总的熵。
  5. 最后可以根据属性的权重,进行决策或排序。

熵权法在多属性决策中具有一定的优势,能够考虑到不同属性的权重,提高决策的准确性和可靠性。但是,在实际应用中,需要注意属性数据的准确性和合理性,以及熵的计算方法的选择等问题。

 模板:

  1. import numpy as np
  2. # 定义计算熵的函数
  3. def entropy(data):
  4. # 计算每个属性的概率
  5. prob = np.array(data) / np.sum(data)
  6. # 计算熵
  7. entropy = -np.sum(prob * np.log2(prob))
  8. return entropy
  9. # 定义熵权法函数
  10. def entropy_weight(data):
  11. # 计算每个属性的熵
  12. entropies = [entropy(column) for column in data.T]
  13. # 计算总的熵
  14. total_entropy = np.sum(entropies)
  15. # 计算每个属性的权重
  16. weights = [entropy / total_entropy for entropy in entropies]
  17. return weights
  18. # 示例数据
  19. data = np.array([[10, 20, 30, 40], [40, 30, 20, 10]])
  20. # 计算权重
  21. weights = entropy_weight(data)
  22. print("属性权重:", weights)

例子:择偶

 极小型指标转化为极大型(正向化):

  1. # 公式:max-x
  2. if ('Negative' in name) == True:
  3. max0 = data_nor[columns_name[i + 1]].max()#取最大值
  4. data_nor[columns_name[i + 1]] = (max0 - data_nor[columns_name[i + 1]]) # 正向化
  5. # print(data_nor[columns_name[i+1]])

 中间型指标转为极大型(正向化):

  1. # 中间型指标正向化 公式:M=max{|xi-best|} xi=1-|xi-best|/M
  2. if ('Moderate' in name) == True:
  3. print("输入最佳值:")
  4. max = data_nor[columns_name[i + 1]].max()
  5. min = data_nor[columns_name[i + 1]].min()
  6. best=input()
  7. M=0
  8. for j in data_nor[columns_name[i + 1]]:
  9. if(M<abs(j-int(best))):
  10. M=(abs(j-int(best)))
  11. data_nor[columns_name[i + 1]]=1-(abs(data_nor[columns_name[i + 1]]-int(best))/M)
  12. #print(data_nor[columns_name[i + 1]])

 区间型指标转为极大型(正向化):

  1. # 区间型指标正向化
  2. if('Section' in name)==True:
  3. print()
  4. print("输入区间:")
  5. a=input()
  6. b=input()
  7. a=int(a)
  8. b=int(b)
  9. max = data_nor[columns_name[i + 1]].max()
  10. min= data_nor[columns_name[i + 1]].min()
  11. if(a-min>max-b):
  12. M=a-min
  13. else:
  14. M=max-b
  15. #print(data_nor[columns_name[i + 1]][0])
  16. cnt=0
  17. for j in data_nor[columns_name[i + 1]]:
  18. if(j<int(a)):
  19. data_nor[columns_name[i + 1]][cnt]=1-(a-j)/M
  20. elif (int(a)<= j <=int(b)):
  21. data_nor[columns_name[i + 1]][cnt]=1
  22. elif (j>b):
  23. data_nor[columns_name[i + 1]][cnt]=1-(j-b)/M
  24. #print(data_nor[columns_name[i + 1]][cnt])
  25. cnt+=1
  26. #print(data_nor[columns_name[i + 1]])
  27. '''公式:
  28. M = max{a-min{xi},max{xi}-b} xi<a,则xi=1-(a-xi)/M; a<=xi<=b,则xi=1; xi>b,则1-(xi-b)/M
  29. '''

标准化处理

公式:

  1. def normalization(data_nor):
  2. data_nors = data_nor.values
  3. data_nors = np.delete(data_nors, 0, axis=1)#去掉第一行
  4. squere_A = data_nors * data_nors#矩阵相乘
  5. # print(squere_A)
  6. sum_A = np.sum(squere_A, axis=0)#按列求和
  7. sum_A = sum_A.astype(float)
  8. stand_A = np.sqrt(sum_A)#平方根
  9. columns_name = data_nor.columns.values
  10. cnt=0
  11. for i in columns_name[1:]:
  12. #print(data_nor[i])
  13. data_nor[i]=data_nor[i]/stand_A[cnt]
  14. cnt+=1
  15. #print(data_nor)
  16. return data_nor

熵权:

公式:

  1. # 定义计算熵权方法
  2. def entropy_weight(data_nor):
  3. columns_name = data_nor.columns.values
  4. n = data_nor.shape[0]
  5. E = []
  6. for i in columns_name[1:]:
  7. # 计算信息熵
  8. # print(i)
  9. data_nor[i] = data_nor[i] / sum(data_nor[i])
  10. data_nor[i] = data_nor[i] * np.log(data_nor[i])
  11. data_nor[i] = data_nor[i].where(data_nor[i].notnull(), 0)
  12. # print(data_nor[i])
  13. Ei = (-1) / (np.log(n)) * sum(data_nor[i])
  14. E.append(Ei)
  15. # print(E)
  16. # 计算权重
  17. W = []
  18. for i in E:
  19. wi = (1 - i) / ((len(columns_name) - 1) - sum(E))
  20. W.append(wi)
  21. # print(W)
  22. return W

 ​​​​完整代码:

  1. #coding=gbk
  2. import pandas as pd
  3. import numpy as np
  4. import re
  5. import warnings
  6. # 定义文件读取方法
  7. def read_data(file):
  8. file_path = file
  9. raw_data = pd.read_excel(file_path, header=0)
  10. # print(raw_data)
  11. return raw_data
  12. # 定义数据正向化
  13. def data_normalization(data):
  14. data_nor = data.copy()
  15. columns_name = data_nor.columns.values
  16. #print(columns_name)
  17. for i in range((len(columns_name) - 1)):
  18. name = columns_name[i + 1]
  19. print("输入这一类数据类型(Positive、Negative、Moderate、Section:)")
  20. name=input()
  21. # 极小型指标正向化
  22. if ('Negative' in name) == True:
  23. max0 = data_nor[columns_name[i + 1]].max()#取最大值
  24. data_nor[columns_name[i + 1]] = (max0 - data_nor[columns_name[i + 1]]) # 正向化
  25. # print(data_nor[columns_name[i+1]])
  26. # 中间型指标正向化
  27. if ('Moderate' in name) == True:
  28. print("输入最佳值:")
  29. max = data_nor[columns_name[i + 1]].max()#取最大值
  30. min = data_nor[columns_name[i + 1]].min()#取最小值
  31. best=input()
  32. M=0
  33. for j in data_nor[columns_name[i + 1]]:
  34. if(M<abs(j-int(best))):
  35. M=(abs(j-int(best)))
  36. data_nor[columns_name[i + 1]]=1-(abs(data_nor[columns_name[i + 1]]-int(best))/M)
  37. #print(data_nor[columns_name[i + 1]])
  38. # 区间型指标正向化
  39. if('Section' in name)==True:
  40. print("输入区间:")
  41. a=input()
  42. b=input()
  43. a=int(a)
  44. b=int(b)
  45. max = data_nor[columns_name[i + 1]].max()
  46. min= data_nor[columns_name[i + 1]].min()
  47. if(a-min>max-b):
  48. M=a-min
  49. else:
  50. M=max-b
  51. #print(data_nor[columns_name[i + 1]][0])
  52. cnt=0
  53. for j in data_nor[columns_name[i + 1]]:
  54. if(j<int(a)):
  55. data_nor[columns_name[i + 1]][cnt]=1-(a-j)/M
  56. elif (int(a)<= j <=int(b)):
  57. data_nor[columns_name[i + 1]][cnt]=1
  58. elif (j>b):
  59. data_nor[columns_name[i + 1]][cnt]=1-(j-b)/M
  60. cnt+=1
  61. #print(data_nor[columns_name[i + 1]])
  62. # print(data_nor)
  63. return data_nor
  64. def normalization(data_nor):
  65. data_nors = data_nor.values
  66. data_nors = np.delete(data_nors, 0, axis=1)
  67. squere_A = data_nors * data_nors#矩阵相乘
  68. # print(squere_A)
  69. sum_A = np.sum(squere_A, axis=0)#按列求和
  70. sum_A = sum_A.astype(float)
  71. stand_A = np.sqrt(sum_A)#开平方
  72. columns_name = data_nor.columns.values
  73. cnt=0
  74. for i in columns_name[1:]:
  75. data_nor[i]=data_nor[i]/stand_A[cnt]#每个元素除以相对应的平方根
  76. cnt+=1
  77. #print(data_nor)
  78. return data_nor
  79. # 定义计算熵权方法
  80. def entropy_weight(data_nor):
  81. columns_name = data_nor.columns.values
  82. n = data_nor.shape[0]
  83. E = []
  84. for i in columns_name[1:]:
  85. # 计算信息熵
  86. # print(i)
  87. data_nor[i] = data_nor[i] / sum(data_nor[i])
  88. data_nor[i] = data_nor[i] * np.log(data_nor[i])
  89. data_nor[i] = data_nor[i].where(data_nor[i].notnull(), 0)
  90. # print(data_nor[i])
  91. Ei = (-1) / (np.log(n)) * sum(data_nor[i])
  92. E.append(Ei)
  93. # print(E)
  94. # 计算权重
  95. W = []
  96. for i in E:
  97. wi = (1 - i) / ((len(columns_name) - 1) - sum(E))
  98. W.append(wi)
  99. # print(W)
  100. return W
  101. # 计算得分
  102. def entropy_score(data, w):
  103. data_s = data.copy()
  104. columns_name = data_s.columns.values
  105. for i in range((len(columns_name) - 1)):
  106. name = columns_name[i + 1]
  107. data_s[name] = data_s[name] * w[i]
  108. return data_s
  109. if __name__ == "__main__":
  110. file = 'filepath' # 声明数据文件地址
  111. data = read_data(file) # 读取数据文件
  112. data_nor = data_normalization(data) # 数据正向化,生成后的数据data_nor
  113. print("\n正向化后的数据:")
  114. print(data_nor)
  115. data_nor=normalization(data_nor)
  116. print("\n标准化后的数据:")
  117. print(data_nor)
  118. W = entropy_weight(data_nor) # 计算熵权权重
  119. data_s = entropy_score(data, W) # 计算赋权后的得分,使用原数据计算
  120. #data_nor_s = entropy_score(data_nor, W)
  121. print("\n权值:",W)
  122. print("\n赋权后的得分:")
  123. print(data_s)
  124. #print(data_nor_s)

结果: 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/280730
推荐阅读
相关标签
  

闽ICP备14008679号