• 【数学建模】层次分析(Matlab&Python代码实现)


    目录

    1 概述

    2 AHP的基本步骤

     3 简单入门算例

    4 升级入门算例

    4.1 算例

    4.2 Matlab代码实现

    5 Python代码实现


    1 概述

    适用于解决多个备选方案决策以及在选择过程中各个因素的重要性比较,比如要选择旅游地,有3个选择方案,苏杭、北戴河和桂林。选择过程需要考虑多个因素,比如景色、费用、居住、饮食和旅途。

    AHP对人们的主观判断加以形式化地表达和处理,逐步剔除主观性,从而尽可能地转化成客观描述。其正确与成功.取决于客观成分能否达到足够合理的地步。由于理论研究的遍历与工程实现的采样之间总是存在着(或大或小,往往又是巨大的}差距.在借助于判断矩阵计算出相对权重后,欲克服两两相比未能穷尽的不足,对判断矩阵做一致性检验,成为不可或缺的环节。

    2 AHP的基本步骤

    运用AHP方法解决问题,大体可按如下步骤进行:

    1)将问题分解.建立层次结构;
    2)构造两两比较判断矩阵:
    3)由判断矩阵计算比较元素的相对权重:

    4)计算各层元素的组合权重。

    现举例说明上述过程。 

     

     3 简单入门算例

    参考:(1条消息) 层次分析法详解(matlab)_黑脉金的博客-CSDN博客_层次分析法matlab程序

     在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    4 升级入门算例

    4.1 算例

     银行在国家经济社会发展过程中扮演者重要的决策,银行的破产会对企业和个人造成众多不利的影响。相比国内的银行,国际银行的倒闭频次更高,因此国际银行倒闭原因的分析与预测受到众多管理者与学术研究者的广泛关注。附件1中提供了波兰2017年至2021年的现存或倒闭银行的64项指标数据,各项数据指标具有对应的解释。

    请你从这64项数据中整理出适合的投入产出数据,并对各银行的效率展开对应评价,同时提供银行倒闭效率的分界线;

     思路:使用二分类的类值

    • ·0 - 在预测期内没有破产的公司
    • 1 - 破产公司

    4.2 Matlab代码实现

    1. clear
    2. clc
    3. %% 加载数据
    4. %load data.txt
    5. load data.txt
    6. X=data(:,3:end); %第一列和第二列:X1净利润/总资产 ;X2 总负债/总资产
    7. %% 归一化
    8. X=mapminmax(X',0,1)';
    9. mapping.mean = mean(X, 1);
    10. C = cov(X);%协方差矩阵
    11. C(isnan(C)) = 0;
    12. C(isinf(C)) = 0;
    13. [M, lambda] = eig(C);%求C矩阵特征向量及特征值
    14. [lambda, ind] = sort(diag(lambda), 'descend');%排序
    15. lambda=lambda./sum(lambda);%特征值归一化
    16. a=lambda;
    17. lambda=cumsum(lambda);%累计贡献率
    18. mapping.lambda = lambda;
    19. M=M(:,ind);
    20. Z=[];
    21. A=[];
    22. %% 第一列和第二列净利润/总资产 ;X2 总负债/总资产
    23. for i=1:size(M,2)
    24. [~,z]=max(abs(M(:,i)));
    25. if length(find(Z==z))==0
    26. Z=[Z,z];
    27. A=[A,a(i)];
    28. end
    29. end
    30. %% 五年
    31. Z=Z(1:5);
    32. W=A(1:5)./sum(A(1:5));
    33. %% 确定主要指标
    34. disp('主要指标序号')
    35. disp(Z)%指标序号
    36. disp('权重')
    37. disp(W)
    38. %% 评价值
    39. P=[data(:,1:2),X(:,Z)*W'];
    40. %检验
    41. disp('整体在预测期内没有破产的公司和破产公司的分别求平均值')
    42. [mean(P(find(P(:,2)==0),3)),mean(P(find(P(:,2)==1),3))]
    43. disp('2017年在预测期内没有破产的公司和破产公司的分别求平均值')
    44. [mean(P(find(P(find(P(:,2)==0),1)==2017),3)),mean(P(find(P(find(P(:,2)==1),1)==2017),3))]
    45. disp('2018年在预测期内没有破产的公司和破产公司的分别求平均值')
    46. [mean(P(find(P(find(P(:,2)==0),1)==2018),3)),mean(P(find(P(find(P(:,2)==1),1)==2018),3))]
    47. disp('2019年在预测期内没有破产的公司和破产公司的分别求平均值')
    48. [mean(P(find(P(find(P(:,2)==0),1)==2019),3)),mean(P(find(P(find(P(:,2)==1),1)==2019),3))]
    49. disp('20120年在预测期内没有破产的公司和破产公司的分别求平均值')
    50. [mean(P(find(P(find(P(:,2)==0),1)==2020),3)),mean(P(find(P(find(P(:,2)==1),1)==2020),3))]
    51. disp('2021年在预测期内没有破产的公司和破产公司的分别求平均值')
    52. [mean(P(find(P(find(P(:,2)==0),1)==2021),3)),mean(P(find(P(find(P(:,2)==1),1)==2021),3))]
    53. %检验通过后,接下来就是求分界线,其实就是依次分类统计下均值在取个中间值就好了
    54. %求每个主要指标的
    55. M=[];
    56. for i=1:length(Z);
    57. M(i,:)=[mean(X(find(data(:,2)==0),Z(i))),mean(X(find(data(:,2)==1),Z(i)))];
    58. end
    59. disp('主要指标分界点')
    60. M=mean(M,2)

     结果:

    1. 主要指标序号
    2. 29 33 34 3 16
    3. 权重
    4. 0.6047 0.1617 0.1008 0.0720 0.0608
    5. 整体class=01的分别求平均值
    6. ans =
    7. 0.4434 0.4181
    8. 2017class=01的分别求平均值
    9. ans =
    10. 0.4503 0.4703
    11. 2018class=01的分别求平均值
    12. ans =
    13. 0.4464 0.4689
    14. 2019class=01的分别求平均值
    15. ans =
    16. 0.4362 0.4706
    17. 20120class=01的分别求平均值
    18. ans =
    19. 0.4371 0.4543
    20. 2021class=01的分别求平均值
    21. ans =
    22. 0.4502 0.4360
    23. 主要指标分界点
    24. M =
    25. 0.5462
    26. 0.0411
    27. 0.1593
    28. 0.8765
    29. 0.2415
    30. >>

    本部分来源于我的男神川川,参考链接点这里:川川


    5 Python代码实现

    1. import numpy as np
    2. class AHP:
    3. """
    4. 相关信息的传入和准备
    5. """
    6. def __init__(self, array):
    7. ## 记录矩阵相关信息
    8. self.array = array
    9. ## 记录矩阵大小
    10. self.n = array.shape[0]
    11. # 初始化RI值,用于一致性检验
    12. self.RI_list = [0, 0, 0.52, 0.89, 1.12, 1.26, 1.36, 1.41, 1.46, 1.49, 1.52, 1.54, 1.56, 1.58,
    13. 1.59]
    14. # 矩阵的特征值和特征向量
    15. self.eig_val, self.eig_vector = np.linalg.eig(self.array)
    16. # 矩阵的最大特征值
    17. self.max_eig_val = np.max(self.eig_val)
    18. # 矩阵最大特征值对应的特征向量
    19. self.max_eig_vector = self.eig_vector[:, np.argmax(self.eig_val)].real
    20. # 矩阵的一致性指标CI
    21. self.CI_val = (self.max_eig_val - self.n) / (self.n - 1)
    22. # 矩阵的一致性比例CR
    23. self.CR_val = self.CI_val / (self.RI_list[self.n - 1])
    24. """
    25. 一致性判断
    26. """
    27. def test_consist(self):
    28. # 打印矩阵的一致性指标CI和一致性比例CR
    29. print("判断矩阵的CI值为:" + str(self.CI_val))
    30. print("判断矩阵的CR值为:" + str(self.CR_val))
    31. # 进行一致性检验判断
    32. if self.n == 2: # 当只有两个子因素的情况
    33. print("仅包含两个子因素,不存在一致性问题")
    34. else:
    35. if self.CR_val < 0.1: # CR值小于0.1,可以通过一致性检验
    36. print("判断矩阵的CR值为" + str(self.CR_val) + ",通过一致性检验")
    37. return True
    38. else: # CR值大于0.1, 一致性检验不通过
    39. print("判断矩阵的CR值为" + str(self.CR_val) + "未通过一致性检验")
    40. return False
    41. """
    42. 算术平均法求权重
    43. """
    44. def cal_weight_by_arithmetic_method(self):
    45. # 求矩阵的每列的和
    46. col_sum = np.sum(self.array, axis=0)
    47. # 将判断矩阵按照列归一化
    48. array_normed = self.array / col_sum
    49. # 计算权重向量
    50. array_weight = np.sum(array_normed, axis=1) / self.n
    51. # 打印权重向量
    52. print("算术平均法计算得到的权重向量为:\n", array_weight)
    53. # 返回权重向量的值
    54. return array_weight
    55. """
    56. 几何平均法求权重
    57. """
    58. def cal_weight__by_geometric_method(self):
    59. # 求矩阵的每列的积
    60. col_product = np.product(self.array, axis=0)
    61. # 将得到的积向量的每个分量进行开n次方
    62. array_power = np.power(col_product, 1 / self.n)
    63. # 将列向量归一化
    64. array_weight = array_power / np.sum(array_power)
    65. # 打印权重向量
    66. print("几何平均法计算得到的权重向量为:\n", array_weight)
    67. # 返回权重向量的值
    68. return array_weight
    69. """
    70. 特征值法求权重
    71. """
    72. def cal_weight__by_eigenvalue_method(self):
    73. # 将矩阵最大特征值对应的特征向量进行归一化处理就得到了权重
    74. array_weight = self.max_eig_vector / np.sum(self.max_eig_vector)
    75. # 打印权重向量
    76. print("特征值法计算得到的权重向量为:\n", array_weight)
    77. # 返回权重向量的值
    78. return array_weight
    79. if __name__ == "__main__":
    80. # 给出判断矩阵
    81. b = np.array([[1, 1 / 3, 1 / 8], [3, 1, 1 / 3], [8, 3, 1]])
    82. # 算术平均法求权重
    83. weight1 = AHP(b).cal_weight_by_arithmetic_method()
    84. # 几何平均法求权重
    85. weight2 = AHP(b).cal_weight__by_geometric_method()
    86. # 特征值法求权重
    87. weight3 = AHP(b).cal_weight__by_eigenvalue_method()

  • 相关阅读:
    【数据结构初阶】顺序表
    《web课程设计》使用HTML+CSS制作大学生校园二手交易网站
    【React篇】组件错误边界处理(组件错误引起的页面白屏)
    基于Golang实现的GoFrame+Vue+ElementUI大数据分析管理系统
    09.Json语法
    Redis.
    Python ArcPy批量计算多时相遥感影像的各像元平均值
    通过Geth搭建私有以太坊网络
    华为od机考真题-高矮个子排队,算法第九讲-高频真题解析 II
    数据结构与算法第一课
  • 原文地址:https://blog.csdn.net/weixin_46039719/article/details/126923087