天天看點

python實作層次分析法(AHP)

1 層次分析法簡介

層次分析法(Analytic Hierarchy Process,AHP)這是一種定性和定量相結合的、系統的、階層化的分析方法。

層次分析法根據問題的性質和要達到的總目标,将問題分解為不同的組成因素,并按照因素間的互相關聯影響以及隸屬關系将因素按不同的層次聚集組合,形成一個多層次的分析結構模型,進而最終使問題歸結為最低層(供決策的方案、措施等)相對于最高層(總目标)的相對重要權值的确定或相對優劣次序的排定。

2 層次分析法步驟

步驟如下圖所示:

python實作層次分析法(AHP)

1)建立層次結構模型

将複雜問題階層化:

  • 首先是目标層,即問題的最終目的;
  • 将影響問題決策的因素分為幾大類作為标準層;
  • 最後一層是方案層,即列出各種方案。

把問題按照各因素之間的隸屬關系或互相關聯度分層,形成自上而下的逐層支配關系,即遞階層次結構,如下圖所示:

python實作層次分析法(AHP)

2)建構判斷矩陣

采用1-9标度法形成判斷矩陣,方法是兩兩比較。

成對比較矩陣是表示本層所有因素針對上一層某一個因素(準側或目标)的相對重要性的比較。

成對比較矩陣的元素 表示的是第 i 個因素相對于第 j 個因素的比較結果,這個值使用的是Santy的1-9标度方法給出。

python實作層次分析法(AHP)

比如,上面的旅遊的例子,在旅遊問題中第二層A的各個因素對目标層Z的影響兩兩比較的結果如下圖:

python實作層次分析法(AHP)

比如 則表示的是景色因素比居住因素對于選擇旅遊地來說稍微重要。

3)計算分層權重及其一緻性檢驗

a. 計算分層權重(層次單排序)

層次單排序:就是把一個層次上的因素相對上一層某個因素的重要性權重并歸一化。該權值對應判斷矩陣的最大特征值得特征向量的歸一化值。

比如,方案層B1/B2/B3對A1\A2\A3\A4\A5的成對比較陣:

python實作層次分析法(AHP)
B1/B2/B3對A1的權重為:[0.595, 0.276, 0.128]
B1/B2/B3對A2的權重為:[0.082, 0.236 , 0.682]
B1/B2/B3對A3的權重為:[0.429, 0.429, 0.143]
B1/B2/B3對A4的權重為:[0.634, 0.192, 0.174]
B1/B2/B3對A5的權重為:[0.167, 0.167, 0.667]
A的權重:[0.264, 0.476, 0.054 , 0.099, 0.109]           

b. 一緻性檢驗

滿足下面關系式的正互反矩陣可以叫做一緻矩陣:

python實作層次分析法(AHP)

一緻矩陣具有以下屬性:

  1. 為正互反矩陣
  2. 轉置也是一緻陣;
  3. 各行成比例,則矩陣轉秩為1;
  4. 最大特征根(值)為 λ=n ,其餘的 n−1 個特征根均等于0;
  5. 任一列(行)都是對應于特征根 n 的特征向量, AW=nW ;

判斷矩陣的最大特征值λ=n時為一緻矩陣,且當判斷矩陣非一緻時,必有最大特征值λ>n,其中λ比n大得越多,判斷矩陣非一緻性越嚴重,則其對應的标準化特征向量就越不能反映出因素的影響。是以需要對矩陣進行一緻性檢驗,步驟如下:

  • 計算一緻性名額 。CI等于0時,有完全的一緻性;接近0,有滿意的一緻性;越大,不一緻性越嚴重。
  • 查找CI對應的平均随機一緻性名額RI:
python實作層次分析法(AHP)

RI的取值,不刻意的從[1-9]和[1-1/9]中,随便選擇數字組成正互反矩陣,以此形式直到得到500個随機樣本矩陣,然後計算出最大特征根的均值,并定義RI=(均值-n)/(n-1)。

  • 計算一緻性比例:
  • 當CR<0.1時,矩陣一緻性可以接受。

4)層次總排序及其一緻性檢驗

計算某一層次所有因素對于 最高層(總目标) 相對重要性的權值,稱為層次總排序。

python實作層次分析法(AHP)

層次結構總排序也需要一緻性測試,從上層到下層逐層進行。

設層的權值向量為,B層對的判斷矩陣的和為,B層對的判斷矩陣的和為,則:

至此,根據最下層(決策層)的層次總排序做出最後決策。

3 層次分析法優缺點

優點:

  • 充分考慮定性因素的影響作用,加強選擇依據的可靠性,減少判斷失誤。
  • 傳統方法模型複雜,AHP采用1-9标度法形成判斷矩陣,簡單易懂。
  • 将專家經驗和判斷融入遞階層次結構中,對問題綜合評判,彌補傳統方法片面注重量化資訊,缺乏柔性的不足。

缺點:

  • 當因素較多,判斷矩陣不易達到一緻性,且調整困難。
  • 不能較好地處理不确定性因素。
  • 各專家對于名額之間的重要度評判不同,易存在個人主觀片面性。

4 Python實作

# 參考:https://blog.csdn.net/lwq_0/article/details/107296446
def Eigenvalues_Feature_vector(phalanx):
    # 計算判斷矩陣的特征值和特征向量
    a, b = np.linalg.eig(phalanx)
    # print("特征值是\n", a)
    print("特征值實部:", a.real)  # 顯示特征值實部
    max_eigenvalue = max(a.real)
    print("最大特征值:", max_eigenvalue)
    num_shape = phalanx.shape
    CI = (max_eigenvalue - num_shape[0]) / (num_shape[0] - 1)
    print("---->> CI=", CI)
    if num_shape[0] == 2:
        RI = 0
    elif num_shape[0] == 3:
        RI = 0.52
    else:
        RI = 0.89

    if RI == 0 and CI == 0:
        CR = 0
        print("---->> CR=", CR)
    else:
        CR = CI / RI
        print("---->> CR=", CR)
    if CR < 0.1:
        print("---->> 一緻性比例可接受!")
    else:
        print("---->> 一緻性檢驗不通過!")
    print("\n")
    # print("特征向量是\n", b)  # numpy的特征向量是豎方向的,numpy輸出的特征向量是機關化後的向量
    print("特征向量實部:", b.real)
    return b

def Weight_vector(phalanx):
    # 計算判斷矩陣的權向量
    num = 0
    b = Eigenvalues_Feature_vector(phalanx)
    for i in range(len(b.real)):
        num += b.real[i][0]
    print("\n")
    print("名額權重是:")
    weight_list = []
    for j in range(len(b.real)):
        weight_num = b.real[j][0] / num
        weight_list.append(weight_num)
    print(weight_list)
    print("\n")
    return np.array([weight_list])
           

參考

1 https://zhuanlan.zhihu.com/p/38207837 2 https://blog.csdn.net/lwq_0/article/details/107296446

3 基于層次分析法的研學旅行綜合評價名額體系研究-金淼.