一、层次分析法

1.1 基本思想

基本思想:
层次分析法是定性与定量结合的多准则决策、评价方法。将决策的有关元素分解成目标层、准则层和方案层,并通过人们的判断对决策方案的优劣进行排序,在此基础上进行定性和定量分析。它把人的思维过程层次化、数量化,并用数学为分析、决策、评价、预报和控制提供定量的依据。
在这里插入图片描述

1.2 基本步骤

基本步骤:
1、构建层次结构模型;
2、构建成对比较判断矩阵;
3、一致性检验;
4、计算权重;
5、求解得分。

1.3 下面以一道例题为例进行分析:

小明同学想出去旅游,在查阅了网上的攻略后,他初步选择了苏杭,北戴河,桂林三个地方。

请你确定评价指标,形成评价体系为小明同学选择最佳的方案。

第一步:确定模型

题中出现“确定评价指标,形成评价体系”这类词眼,确定这是一道层次分析题。

第二步:建立层次结构模型

我们从三个问题入手:
1.我们评价的目标是什么?
答:为小明选择最佳的旅游景点。
2.我们为了达到这个目标有哪几种可选的方案?
答:三种。分别是去苏杭,去北戴河,去桂林。
3.评价的准则或者说指标是什么?
答:景色,花费,居住,饮食,交通。
第三个的答案我们可以根据题目中的背景材料,常识,以及网上(知网,百度学术,虫部落-快搜)搜索到的参考资料进行结合,从中筛选合适的指标。

第三步:构建权重表格

我们最终的目标就是要填满这个权重矩阵!!!(同颜色的单元格和为1)

在这里插入图片描述
重要性表

标度含义
1同等重要性
3稍微重要
5明显重要
7强烈重要
9极端重要
2,4,6,8上述两相邻判断的中值
倒数A和B相比:如果标度为3,那么B和A相比就是1/3

**(1)构建指标之间的判断矩阵:**两个指标两个指标进行比较,根据重要性表填写两两比较的结果
1.比较景色和花费的重要程度

    答:花费比景色略微重要(景色:花费 = 1:2)

2.比较景色和居住的重要程度

    答:景色比居住要重要一点(景色:居住 = 4 :1)

…………

总共需要比较C_{5}^{2}\textrm{}次

判断矩阵:在这里插入图片描述
上面的矩阵就是层次分析法中的正互反矩阵(我们需要知道正互反矩阵的特点)

    (1)aij表示:与 j 相比,i 的重要程度(例如:和居住相比,景色的重要程度是4)

    (2)当 i = j 时,两个指标相同,同等重要记为1

    (3)aij > 0 && aij x aji = 1

(2)构建每个指标下,方案之间的判断矩阵
1.比较苏杭的花费和北戴河的花费的多少程度

    答:北戴河的花销要比苏杭的花销要稍多(北戴河:苏杭 = 3 :1)

2.比较苏杭的花费和桂林的花费的多少程度

    答:桂林的花销要比苏杭的花销要贵的多得多(桂林:苏杭 = 8 :1)

3.比较北戴河的花花费和桂林的花费的多少程度

    答:桂林的花销要比北戴河要稍多(桂林 : 北戴河 = 3 :1)

……

判断矩阵:
在这里插入图片描述
第四步:对判断矩阵一致性检验 (如果判断矩阵已经是一致矩阵,那么就没必要进行一致性检验)
首先介绍一下一致矩阵

    在判断矩阵的前提下,如果各行成比例且各列成比例,那么该矩阵就是一致矩阵

第一步:计算判断矩阵的最大特征值 在这里插入图片描述
及一致性指标CI

第二步:根据n的大小,按照下表查找平均随机一致性指标RI,计算一致性比例CR
在这里插入图片描述

在这里插入图片描述
第三步:判断判断矩阵的一致性是否小于0.1

结论:如果CR < 0.1, 则可认为判断矩阵的一致性可以接受;否则需要对判断矩阵进行修正。修正的方法:往一致矩阵上去凑(各行各列成比例)

第五步:计算判断矩阵的权重(算术平均法,几何平均法,特征值法三种最好都用上)
(1)算术平均法求权重

    第一步:将判断矩阵按照列归一化(每个元素除以其所在列的和)

    第二步:将归一化的各列相加(按行求和)

    ​​​​​第三步:将相加后得到的向量中的每个元素除以n即可得到权重向量

(2)几何平均法求权重

    第一步:将判断矩阵按行相乘得到一个新的列向量

    第二步:将该列向量中的每个元素开n方

    第三步:对开方后的列向量进行归一化处理(列向量中的每个元素除以该列的和)

(3)特征值法求权重

    第一步:求出矩阵的最大特征值以及对应的特征向量

    第二步:对最大特征值对应的的特征向量进行归一化处理即可得到我们的权重  

第六步:构建最终的权重表,将特征值法计算出的结果填入对应的颜色项中
在这里插入图片描述
第七步:计算得分
苏杭得分 = 0.26360.5954 + 0.47580.0819 + 0.05380.4286 + 0.09810.6337 + 0.1087*0.1667 = 0.29926

……

用excel进行计算:
在这里插入图片描述
B这一列一定要锁住(shift+f4),计算的才是正确的

结果:
在这里插入图片描述

1.4 优缺点

优点:

​ 它完全依靠主观评价做出方案的优劣排序,所需数据量少,决策花费的时间很短。从整体上看,AHP在复杂决策过程中引入定量分析,并充分利用决策者在两两比较中给出的偏好信息进行分析与决策支持,既有效地吸收了定性分析的结果,又发挥了定量分析的优势,从而使决策过程具有很强的条理性和科学性,特别适合在社会经济系统的决策分析中使用。

缺点:

​ 用AHP进行决策主观成分很大。当决策者的判断过多地受其主观偏好影响,而产生某种对客观规律的歪曲时,AHP的结果显然就靠不住了。

1.5 适用范围

适用范围:
尤其适合于人的定性判断起重要作用的、对决策结果难于直接准确计量的场合。要使AHP的决策结论尽可能符合客观规律,决策者必须对所面临的问题有比较深入和全面的认识。另外,当遇到因素众多,规模较大的评价问题时,该模型容易出现问题,它要求评价者对问题的本质、包含的要素及其相互之间的逻辑关系能掌握得十分透彻,否则评价结果就不可靠和准确。

1.6 改进方法

改进方法:
(1) 成对比较矩阵可以采用德尔菲法获得。

(2) 如果评价指标个数过多(一般超过9个),利用层次分析法所得到的权重就有一定的偏差,继而组合评价模型的结果就不再可靠。可以根据评价对象的实际情况和特点,利用一定的方法,将各原始指标分层和归类,使得每层各类中的指标数少于9个。

补充:

​ 德尔菲法,也称专家调查法,1946年由美国兰德公司创始实行,其本质是一种反馈匿名函询法,其大致流程是在对所要预测的问题征得专家的意见之后,进行整理、归纳、统计,在匿名反馈给各专家,再次征求意见,再集中,再反馈,直至得到一致的意见。在评价中目的:确立评价指标。

1.7 PYTHON代码

PYTHON代码:

import numpy as np  # 导入所需包并将其命名为np
A = [[1,1,4,1/3,3],
     [1,1,4,1/3,3],
     [1/2,1/4,1,1/3,1/2],
     [3,3,3,1,3],
     [1/3,1/3,2,1/3,1]]


def ConsisTest(X):  # 函数接收一个如上述A似的矩阵
    # 计算权重
    
    # 方法一:算术平均法
    ## 第一步:将判断矩阵按照列归一化(每个元素除以其所在列的和)
    X = np.array(X)  # 将X转换为np.array对象
    sum_X = X.sum(axis=0)  # 计算X每列的和
    (n, n) = X.shape  # X为方阵,行和列相同,所以用一个n来接收
    sum_X = np.tile(sum_X, (n, 1))  # 将和向量重复n行组成新的矩阵
    stand_X = X / sum_X  # 标准化X(X中每个元素除以其所在列的和)

    ## 第二步:将归一化矩阵每一行求和
    sum_row = stand_X.sum(axis=1)

    ## 第三步:将相加后得到的向量中每个元素除以n即可得到权重向量
    print("算数平均法求权重的结果为:")
    print(sum_row / n)

    # 方法二:特征值法
    ## 第一步:找出矩阵X的最大特征值以及其对应的特征向量
    V, E = np.linalg.eig(X)  # V是特征值,E是特征值对应的特征向量
    max_value = np.max(V)  # 最大特征值
    # print("最大特征值是:",max_value)
    max_v_index = np.argmax(V)  # 返回最大特征值所在位置
    max_eiv = E[:, max_v_index]  # 最大特征值对应的特征向量

    ## 第二步:对求出的特征向量进行归一化处理即可得到权重
    stand_eiv = max_eiv / max_eiv.sum()
    print("特征值法求权重的结果为:")
    print(stand_eiv)
    print("———————————————————————————————")
    # 一致性检验
    ## 第一步:计算一致性指标CI
    CI = (max_value - n) / (n - 1)
    ## 第二步:查找对应的平均随机一致性指标RI
    RI = np.array([15, 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])
    ## 第三步:计算一致性比例CR
    CR = CI / RI[n]
    if CR < 0.1:
        print("CR=", CR, ",小于0.1,通过一致性检验")
    else:
        print("CR=", CR, ",大于等于0.1,没有通过一致性检验,请修改判断矩阵")
    return None
ConsisTest(A)


二、熵权法(Entropy Weight Method)

2.1 熵权法介绍

层次分析法的权重带有很重的主管色彩,为了使权重更加客观,我们利用原始数据的某些特性来确定权重。

一列数据的方差越小,指标的变异程度越小,所反映的信息量也越少,那么此时其权重就应该越低。而一列数据所反映的信息量越少,其信息熵就越大。

所以指标的信息熵就是这样一个具有优良性质的特性。而且信息熵越大,权重就越低。(客观=数据本身就可以告诉我们的权重)

2.2 熵权法基本步骤

1、数据标准化
由于每一列数据可能代表不同类别,不同单位的信息,所以为了方便比较,我们需要对数据进行标准化处理。
在这里插入图片描述

  • 这里采用极差标准化方法
  • 处理不同量纲大小带来的影响
  • 可以使得数据非负数(后面计算概率需要保证每一个权重非负)

2、计算信息熵
在这里插入图片描述

  • Pij的计算 保证了每一个指标所对应的概率和为1
  • 计算第j个指标下第i个样本所占的权重,并将其看作相对熵计算中用到的概率(连续性的占比)
  • 对于信息熵,Ej越大,信息熵越大,表面第j个指标得到的信息越少,信息效用值dj = (1-Ej)越大。离散程度越大。

3、计算指标权重
在这里插入图片描述

  • 计算每个指标的信息熵,并计算信息效用值,并归一化得到每个指标的熵权。

4、计算综合得分
在这里插入图片描述

PYTHON代码:

import pandas as pd
import numpy as np
import re
#定义文件读取方法
def read_data(file):
    file_path=file
    raw_data = pd.read_excel(file_path, header=0)
    #print(raw_data)
    return raw_data
 
#定义数据正向化、标准化方法
def data_normalization(data):
    data_nor=data.copy()
    columns_name=data_nor.columns.values
    for i in range((len(columns_name)-1)):
        name=columns_name[i+1]
        #print(name)
        #正向指标直接标准化
        if ('Positive' in name)==True:
            max=data_nor[columns_name[i+1]].max()
            min=data_nor[columns_name[i+1]].min()
            data_nor[columns_name[i+1]]=(data_nor[columns_name[i+1]]-min)/(max-min)
            #print(data_nor[columns_name[i+1]])
 
        #负向指标先正向化、在标准化
        if ('Negative' in name)==True:
            max0=data_nor[columns_name[i+1]].max()
            data_nor[columns_name[i+1]]=(max0-data_nor[columns_name[i+1]])#正向化
 
 
            max=data_nor[columns_name[i+1]].max()
            min=data_nor[columns_name[i+1]].min()
            data_nor[columns_name[i+1]]=(data_nor[columns_name[i+1]]-min)/(max-min)#标准化
            #print(data_nor[columns_name[i+1]])
 
        #适度指标先正向化、在标准化
        if ('Moderate' in name)==True:
            try:
                val_range= re.search(r'.*[\((](.*),(.*)[\))]',name)
                val_down= float(val_range.group(1))
                val_up= float(val_range.group(2))
                val_op=(val_up+val_down)/2
            except:
                val_range= re.search(r'.*[\((](.*)[\))]',name)
                val_op= float(val_range.group(1))
            #print(val_op)
            data_nor[columns_name[i + 1]] = 1-(abs(data_nor[columns_name[i + 1]]-val_op)/(abs(data_nor[columns_name[i + 1]]-val_op).max()))  #正向化
 
            max=data_nor[columns_name[i+1]].max()
            min=data_nor[columns_name[i+1]].min()
            data_nor[columns_name[i+1]]=(data_nor[columns_name[i+1]]-min)/(max-min)#标准化
            #print(data_nor[columns_name[i+1]])
 
    #print(data_nor)
    return data_nor
 
 
#定义计算熵权方法
def entropy_weight(data_nor):
    columns_name=data_nor.columns.values
    n=data_nor.shape[0]
    E=[]
    for i in columns_name[1:]:
 
        #计算信息熵
        #print(i)
        data_nor[i]=data_nor[i]/sum(data_nor[i])
 
        data_nor[i]=data_nor[i]*np.log(data_nor[i])
        data_nor[i]=data_nor[i].where(data_nor[i].notnull(),0)
        #print(data_nor[i])
        Ei=(-1)/(np.log(n))*sum(data_nor[i])
        E.append(Ei)
    #print(E)
    #计算权重
    W=[]
    for i in E:
        wi=(1-i)/((len(columns_name)-1)-sum(E))
        W.append(wi)
    #print(W)
    return W
 
#计算得分
def entropy_score(data,w):
    data_s=data.copy()
    columns_name=data_s.columns.values
    for i in range((len(columns_name)-1)):
        name=columns_name[i+1]
        data_s[name]=data_s[name]*w[i]
    return data_s
 
 
file='data.xls'#声明数据文件地址
data=read_data(file)#读取数据文件
data_nor=data_normalization(data)#数据标准化、正向化,生成标准化后的数据data_nor
W=entropy_weight(data_nor)#计算熵权权重
data_s=entropy_score(data,W)#计算赋权后的得分,使用原数据计算
data_nor_s=entropy_score(data_nor,W)
 
W.insert(0,'熵权法权重')#将结果保存为csv
W0=pd.DataFrame(W).T
data_s.to_csv('熵权法得分结果(原始数据).csv',index=0)
W0.to_csv('熵权法得分结果(原始数据).csv', mode='a', header=False,index=0)
data_nor_s.to_csv('熵权法得分结果(标准化数据).csv',index=0)
W0.to_csv('熵权法得分结果(标准化数据).csv', mode='a', header=False,index=0)

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐