层次分析法

引入

生活中有很多决策问题,需要依据一定的标准选择某一种方案。比如,买衣服一般依据质量、颜色、价格、款式等因素选择。

以一个例子引入:

物品因素1因素2因素3因素4
A6000w106.525
B3400w68.146
C5500w87.531

如何综合这几个因素,以某种标准,选出A、B、C三者的最优?

显然,直接相加不可取,因为这样因素1掩盖了另外三个,成为决定性因素。因此我们想到,要化为同一数量级,且保证在同一个指标下,差距不变。

可以考虑归一化处理:指标的数组[a,b,c]\Rightarrow [\frac{a}{a+b+c},\frac{b}{a+b+c},\frac{c}{a+b+c}]

物品因素1因素2因素3因素4评分
A0.40.420.290.251.36
B0.230.250.370.451.30
C0.370.330.340.301.35

实际上,这里的评分栏是简单相加,没有考虑每种因素可能有不同权重,还不够全面,下面加入对加权的考虑。 

物品因素1(0.4)因素2(0.3)因素3(0.2)因素4(0.1)评分
A0.40.420.290.250.365
B0.230.250.370.450.293
C0.370.330.340.300.342

这里的权重是随便设置的,不同的权重占比会很大程度上影响排名,实际上这种设置具有很大的主观性,很影响对数据的分析,那么如何科学设置权重

层次分析法(AHP)

        是对一些较为复杂、较为模糊的问题做出决策的简易方法,它特别适用那些难于完全定量分析的问题。

 原理

        首先把问题条理化、层次化,构造出一个有层次的结构模型。复杂问题被分解为元素的组成部分。这些元素按其属性及其关系形成若干层。上层元素支配下层元素。层次分为三类:

  • 最高层:只有一个元素,一般是分析问题的预定目标或理想结果。(例子中选出最优物品)
  • 中间层:包含了为实现目标所设计的中间环节,可以由若干层次组成,包括所需的准则、子准则。(例子中各种判断优劣的指标)
  • 最底层:包括了为实现目标可供选择的各种措施、决策方案。(A、B、C三个物品)

运用步骤

  • 建立递阶层次结构模型
  • 构造出各层次中的所有判断矩阵(对指标的重要性进行两两比较,构造判断矩阵,从而科学求出权重;矩阵中元素a_{ij}的意义是,第i个指标相对于第j个指标的重要程度)

判断矩阵标度

标度含义
1两因素具有同样重要性
3一个比另一个稍微重要
5一个比另一个明显重要
7一个比另一个强烈重要
9一个比另一个极端重要
2,4,6,8相邻判断的中值
  • 一致性检验

        由于构造矩阵时,我们每次都是两两决定重要程度,当变量多了,就容易出现矛盾(因为是人为构造),因此要进行一致性检验。

        正互反矩阵:每个元素大于0且a_{ij}\times a_{ji}=1

        一致矩阵:满足a_{ik}\times a_{kj}=a_{ij}的正互反矩阵

        一致性检验步骤:

计算一致性指标CI

查找对应的平均随机一致性指标RI

计算一致性比例CR:CR=\frac{CI}{RI}=\left\{\begin{matrix} 0 & is \ a \ Consistent\ matrix\\ <0.1& is \ consistent \\ \ge 0.1& is \ not \ consistent \end{matrix}\right.

  • 求权重后进行评价

求权重步骤

        算数平均法

  1.         判断矩阵按照列归一化
  2.         归一化的各列相加
  3.         相加后得到的向量中每个元素除以n

        几何平均法

  1.         判断矩阵按照行相乘得到新的列向量
  2.         新向量每个分量开n次方
  3.         对该列向量进行归一化

        特征值法

  1.         求出矩阵A的最大特征值以及对应的特征向量
  2.         对求出的特征向量归一化

Python代码 

import numpy as np


class AHP:
    def __init__(self, array):
        # 记录矩阵相关信息
        self.array = array
        # 记录矩阵大小
        self.n = array.shape[0]
        # 初始化RI值,用于一致性检验
        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,
                        1.59]
        # 矩阵的特征值和特征向量
        self.eig_val, self.eig_vector = np.linalg.eig(self.array)
        # 矩阵的最大特征值
        self.max_eig_val = np.max(self.eig_val)
        # 矩阵最大特征值对应的特征向量
        self.max_eig_vector = self.eig_vector[:, np.argmax(self.eig_val)].real
        # 矩阵的一致性指标CI
        self.CI_val = (self.max_eig_val - self.n) / (self.n - 1)
        # 矩阵的一致性比例CR
        self.CR_val = self.CI_val / (self.RI_list[self.n - 1])

    def test_consist(self):
        # 打印矩阵的一致性指标CI和一致性比例CR
        print("判断矩阵的CI值为:" + str(self.CI_val))
        print("判断矩阵的CR值为:" + str(self.CR_val))
        # 进行一致性检验判断
        if self.n == 2:  # 当只有两个子因素的情况
            print("仅包含两个子因素,不存在一致性问题")
        else:
            if self.CR_val < 0.1:  # CR值小于0.1,可以通过一致性检验
                print("判断矩阵的CR值为" + str(self.CR_val) + ",通过一致性检验")
                return True
            else:  # CR值大于0.1, 一致性检验不通过
                print("判断矩阵的CR值为" + str(self.CR_val) + "未通过一致性检验")
                return False

    def cal_weight_by_arithmetic_method(self):
        # 求矩阵的每列的和
        col_sum = np.sum(self.array, axis=0)
        # 将判断矩阵按照列归一化
        array_normed = self.array / col_sum
        # 计算权重向量
        array_weight = np.sum(array_normed, axis=1) / self.n
        # 打印权重向量
        print("算术平均法计算得到的权重向量为:\n", array_weight)
        # 返回权重向量的值
        return array_weight

    def cal_weight__by_geometric_method(self):
        # 求矩阵的每列的积
        col_product = np.product(self.array, axis=0)
        # 将得到的积向量的每个分量进行开n次方
        array_power = np.power(col_product, 1 / self.n)
        # 将列向量归一化
        array_weight = array_power / np.sum(array_power)
        # 打印权重向量
        print("几何平均法计算得到的权重向量为:\n", array_weight)
        # 返回权重向量的值
        return array_weight

    def cal_weight__by_eigenvalue_method(self):
        # 将矩阵最大特征值对应的特征向量进行归一化处理就得到了权重
        array_weight = self.max_eig_vector / np.sum(self.max_eig_vector)
        # 打印权重向量
        print("特征值法计算得到的权重向量为:\n", array_weight)
        # 返回权重向量的值
        return array_weight


if __name__ == "__main__":
    # 给出判断矩阵
    b = np.array([[1, 1 / 3, 1 / 8], [3, 1, 1 / 3], [8, 3, 1]])
    # 一致性检验
    AHP(b).test_consist()
    # 算术平均法求权重
    weight1 = AHP(b).cal_weight_by_arithmetic_method()
    # 几何平均法求权重
    weight2 = AHP(b).cal_weight__by_geometric_method()
    # 特征值法求权重
    weight3 = AHP(b).cal_weight__by_eigenvalue_method()

 

  • 19
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值