【学习笔记】Matlab和python双语言的学习(层次分析法)


前言

通过模型算法,熟练对Matlab和python的应用。
学习视频链接:

https://www.bilibili.com/video/BV1EK41187QF?p=1&vd_source=67471d3a1b4f517b7a7964093e62f7e6

一、模型算法----层次分析法

判断不同方案的可行性时,不同因素在方案中所占比重不同,需要人为决定,所以受主观因素的影响较大,需要以一定客观的方法来合理化不同因素的权重,最终选出最合适的方案。
层次分析法(Analytic Hierarchy Process,简称AHP)是一种用于决策分析的技术,由美国运筹学家托马斯·萨蒂(Thomas L. Saaty)在20世纪70年代提出。这种方法通过将复杂的决策问题分解为多个层次的子问题,并通过对这些子问题的逐一比较,最终综合得出一个最佳决策。这种方法适用于那些难于完全定量分析的问题。

层次分析法的主要步骤包括:

  1. 构建层次结构:将决策问题分解成目标、准则(或标准)和备选方案等不同层次的结构。最高层是决策目标,中间层是各个准则,最底层是备选方案。

  2. 构造判断矩阵:通过成对比较的方法,构造出判断矩阵。专家或决策者根据经验或数据,对每两个元素进行比较,判断其相对重要性,通常使用1到9的尺度进行评分。

  3. 一致性检验:检验判断矩阵的一致性,以确保比较结果的可靠性。如果一致性指标(CI)和一致性比率(CR)超过一定阈值,需要重新调整判断矩阵。

  4. 计算权重:通过对判断矩阵进行归一化处理和特征向量计算,得到各个元素的权重。权重反映了各元素相对于上层目标的重要性。

  5. 综合评估:将各层次的权重逐层传递,最后综合各个备选方案的得分,得出最终的排序或决策结果。
    视频中江北老师列举了选择微博之星的例子:

    下面我们按照层次分析法的主要步骤依次进行分析。

1.构建层次结构

层次结构包括:最高层(目标层),中间层(准则层)和最底层(方案层)。
在这里插入图片描述
构建层次结构模型如下:
在这里插入图片描述

2.构造判断矩阵

对明星粉丝数、颜值、作品质量、作品数量这几个影响因素,两两进行比较,构造判断矩阵。
矩阵中元素 aij 的意义是,第 i 个指标相对于第 j 个指标的重要程度。
我们按照不同的重要程度,人为地进行比较。

(图中"2"指的一个因素比另一个因素稍微重要的程度轻一些,比同样重要程度重一些,“4”、“6”、"8"也是同样的)
一个因素与自己相比较,是同样重要的,所以矩阵的对角元素都为 1 。
一个明星的粉丝数肯定比作品数量明显重要(粉丝数多的影响力越大),所以标度选择 5 。
两两进行比较后得到矩阵 A 。
在这里插入图片描述

3.一致性检验

因为刚才的因素重要性是两两进行判断的,所以得出的判断矩阵不一定合理,比如 a34 = 1/2,说明作品质量重要性 < 作品数量,显然是不合理的,所以我们需要对判断矩阵进行一致性检验。
在这里插入图片描述
由上式我们可以得到 aij = aik * akj,并且矩阵的各行各列均成倍数关系(例如:aik = j/k * aij),满足这两个条件,该矩阵才为一致性矩阵。
一致性矩阵满足的条件:
(1)矩阵为正互反矩阵,即若矩阵中每个元素 aij > 0,且满足 aij * aji = 1,则我们称该矩阵为正互反矩阵。在层次分析法中,我们构造的判断矩阵均是正互反矩阵。
(2)aij = aik * akj。
一致性矩阵检验的目的:
检验构造的矩阵和判断矩阵是否有太大差别。差别较小,则继续计算权重;差别太大,则需要对判断矩阵中的元素进行调整。
江北老师给出了如何判断构造的矩阵和判断矩阵是否有太大差别的证明过程,此处不再赘述。
在这里插入图片描述
所以,我们只需求出构造矩阵的最大特征值 λmax 与 n 的差距即可。
一致性检验的步骤:
(1)计算一致性指标CI:
在这里插入图片描述
(2)查找对应随机一致性指标RI:
在这里插入图片描述
注:RI 只需要会查表即可,不用管怎么来的。在实际运用中,n很少超过10,如果指标的个数大于10,则可考虑建立二级指标体系,或使用其他模糊综合评价模型。
(3)计算一致性比例CR:
在这里插入图片描述
当前判断矩阵的 λmax = 4.68,n = 4,求得 CI = 0.227,查表 RI = 0.89,得 CR = 0.255 CR ≥ 0.1,需修改判断矩阵。
新矩阵如下:
在这里插入图片描述
当前判断矩阵的 λmax = 4.1128,n=4,求得 CI = 0.227,查表 RI = 0.89,得 CR = 0.0418
CR < 0.1,通过一致性检验。

4.求权重

(1)算术平均法求权重
第一步:将判断矩阵按照列归一化(每一个元素除以其所在列的和)
第二步:将归一化的各列相加(按行求和)
第三步:将相加后得到的向量中每个元素除以n即可得到权重向量
在这里插入图片描述
(2)几何平均法求权重
第一步:将判断矩阵的元素按照行相乘得到一个新的列向量
第二步:将新的向量的每个分量开n次方
第三步:对该列向量进行归一化即可得到权重向量
在这里插入图片描述
(3)特征值法求权重
第一步:求出矩阵的最大特征值以及其对应的特征向量
第二步:对求出的特征向量进行归一化即可得到我们的权重

5.综合评估

最后按照权重计算不同明星的综合评分。
由于一开始的数据中,粉丝数量是以万为单位,数量级较大,对最后的评分影响也较大,不能直接将 原有数据 * 权重 处理,我们应该先对不同明星的同一因素归一化处理。
归一化的主要目的是消除不同特征间由于尺度不同而带来的影响,使得各特征对模型的贡献具有相同的尺度,进而提升模型的性能和稳定性。
在这里插入图片描述
归一化处理结果为:
在这里插入图片描述

二、代码实现----Matlab

1.处理原始数据代码

% 处理原始数据(归一化)
Z = [60000000 10 6.5 25;34000000 6 8.1 46;55000000 8 7.5 31];
Zsum = sum(Z,1);
Zsumr = repmat(Zsum,3,1);
Z_Nl = Z ./ Zsumr;

2.一致性检验代码

% 代码一致性检验
% A=[1 2 3 5;1/2 1 1/2 2;1/3 2 1 1/2;1/5 1/2 2 1];   %修改前
% A=[1 2 3 5;1/2 1 1/2 2;1/3 2 1 2;1/5 1/2 1/2 1];   %修改后
A = input('判断矩阵A=');  %输入判断矩阵
[n,n] = size(A);
% 求出最大特征值对应的特征向量
[V,D] = eig(A);            %V是特征向量 D是特征值构成的对角矩阵
Max_eig = max(max(D));     %先求出每一列的最大值,再求最大列中元素的最大值
CI = (Max_eig - n)/(n - 1);      %计算一致性指标CI
RI = [0 0.0001 0.52 0.89 1.12 1.26 1.36 1.41 1.46 1.49];    %平均随机一致性指标
%RI最多支持 n=15
%这里 n=2 时,一定是一致性矩阵,所以CI=0,为了避免分母为0,将这里的第二个元素改为0.0001
CR = CI/RI(n);            %计算一致性比例
disp('一致性指标CI=');disp(CI);
disp('一致性指标CR=');disp(CR);
if CR < 0.1
    disp('因为CR<0.10,所以该判断矩阵A的一致性可以接受!');
else
    disp('注意:CR>=0.10,因此该判断矩阵A需要进行修改!');
end

3.求权重代码

(1)算术平均法求权重

% 输入样例:
% A=[1 2 3 5;1/2 1 1/2 2;1/3 2 1 2;1/5 1/2 1/2 1];
A = input('判断矩阵A=');   %输入判断矩阵
[n,n] = size(A);    %获取判断矩阵的行和列的个数
Asum = sum(A,1);    %将判断矩阵每列求和   %sum(a,b) a:矩阵, b=1:按列求和; b=2:按行求和
Ar = repmat(Asum,n,1);   %复制Asum n行1列为Ar矩阵   (在行维度上复制n次,列维度上复制1次)
Stand_A = A./Ar;      %归一化,矩阵点除:对应元素点除
Asumr = sum(Stand_A,2);     %将各列相加到同一行
disp(Asumr/n);

(2)几何平均法求权重

% 输入样例:
% A=[1 2 3 5;1/2 1 1/2 2;1/3 2 1 2;1/5 1/2 1/2 1];
A = input('判断矩阵A=');   %输入判断矩阵
Aprod = prod(A,2);        %将判断矩阵的元素按照行相乘
[n,n] = size(A);
A_nthroot = nthroot(Aprod,n);   %将列向量的每个分量开n次方
Asumr = sum(A_nthroot,1);       %将列向量的分量加到同一行
% Ar = repmat(Asumr,4,1);         %复制,方便归一化
Stand_A = A_nthroot./Asumr;        %归一化,得到权重
disp(Stand_A);

(3)特征值法求权重

% 输入样例:
% A=[1 2 3 5;1/2 1 1/2 2;1/3 2 1 2;1/5 1/2 1/2 1];
A = input('判断矩阵A=');   %输入判断矩阵
[V,D] = eig(A);           %求判断矩阵的特征值和特征向量
% (1)方法一
lambda = diag(D);         %取出特征值
[D_max,i] = max(lambda);  %得到最大的特征值
V_max = V(:,i);           %得到最大的特征值对应的特征向量
V_maxr = sum(V_max);
Stand_A = V_max./V_maxr;  %归一化
disp(Stand_A);

% (2)方法二
Max_eig = max(max(D));    %求出最大的特征向量
[r,c] = find(Max_eig == D,1);   %找到最大特征值对应的特征向量
disp(V(:,c)./sum(V(:,c)));      %:代表取出全部的行,c代表取出第c列,所以本行代码表示取出第c列

4.综合评估代码

以特征值法求得的权重为例:

score = Z_Nl .* repmat(Stand_A .',3,1);
mark = sum(score,2);

三、代码实现----python

1.处理原始数据代码

# 处理原始数据
Z = np.array([[60000000, 10, 6.5, 25],[34000000, 6, 8.1, 46],[55000000, 8, 7.5, 31]])

# 归一化
Zsum = np.sum(Z,0)

Zsumr = np.tile(Zsum,(3,1))

Z_Nl = Z / Zsumr

2.一致性检验代码

import numpy as np

# 一致性检验
# A = np.array([[1, 2, 3, 5],[1/2, 1, 1/2, 2],[1/3, 2, 1, 1/2],[1/5, 1/2, 2, 1]])   #修改前
# A = np.array([[1, 2, 3, 5],[1/2, 1, 1/2, 2],[1/3, 2, 1, 2],[1/5, 1/2, 1/2, 1]])   #修改后

A = np.array([[1, 2, 3, 5],[1/2, 1, 1/2, 2],[1/3, 2, 1, 1/2],[1/5, 1/2, 2, 1]]) 

# D为特征值,V为特征向量
D,V = np.linalg.eig(A)     
# 求出最大的特征值
D_max = max(D) 

# 获取矩阵形状
n,n = A.shape   

# 计算一致性指标
CI = (D_max-n)/(n-1)    

# 平均随机一致性指标
RI = (0, 0.0001, 0.52, 0.89, 1.12, 1.26, 1.36, 1.41, 1.46, 1.49)   

# 计算一致性比例
CR = CI/RI[n-1]

if CR < 0.1:
    print("因为CR<0.1,所以该判断矩阵A的一致性可以接受!")
else:
    print("注意:CR>=0.10,因此该判断矩阵A需要进行修改!")

3.求权重代码

(1)算术平均法求权重

import numpy as np

A = np.array([[1, 2, 3, 5],
              [1/2, 1, 1/2, 2],
              [1/3, 2, 1, 2],
              [1/5, 1/2, 1/2, 1]])

# 获取矩阵的形状
n,n = A.shape

# 矩阵按列求和
Asum = np.sum(A,axis=0)

"""
output = np.tile(data, (m,n))

其中:
data 表示待复制的矩阵;

m 表示沿着行的方向复制m次矩阵;

n 表示沿着列的方向复制n次矩阵;
"""
# 矩阵沿着行复制4次,为归一化做准备
Ar = np.tile(Asum,(4,1))

# 归一化
Stand_A = A / Ar

# 将归一化的各列相加(按行求和)
Asumr = np.sum(Stand_A,axis=1)

# 每个元素除n得到权重向量
print(Asumr/n)

(2)几何平均法求权重

import numpy as np

A = np.array([[1, 2, 3, 5],
                    [1/2, 1, 1/2, 2],
                    [1/3, 2, 1, 2],
                    [1/5, 1/2, 1/2, 1]])

# 获取矩阵的形状
n,n = A.shape

# 将矩阵按行相乘
Aprod = np.prod(A, axis=1)

# 对矩阵的每个元素进行开n次方操作
A_power = np.power(Aprod, 1/n)

# 对该列向量归一化,得到权重向量
Stand_A = A_power / sum(A_power)

print(Stand_A)

(3)特征值法求权重

# 3.特征值法求权重
import numpy as np

A = np.array([[1, 2, 3, 5],
              [1/2, 1, 1/2, 2],
              [1/3, 2, 1, 2],
              [1/5, 1/2, 1/2, 1]])

# D为特征值,V为特征向量
D,V = np.linalg.eig(A) 

# 求出最大的特征值的索引
D_max_index= np.argmax(D)

# 求出最大特征值对应的特征向量
V_max = V[:,D_max_index]

# 特征向量归一化
Stand_A = V_max / sum(V_max)

print(Stand_A)

4.综合评估代码

以特征值法求得的权重为例:

# 计算得分
score = Z_Nl * np.tile(Stand_A,(3,1))

mark = np.sum(score,1)

总结

本文介绍了层次分析法的使用,并分别使用Matlab和python进行代码编写。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值