天天看點

資料挖掘十大算法(六):PageRank算法原理與Python實作參考.PageRank算法--從原理到實作零. PageRank算法簡介一、PageRank算法原理二、PageRank值的計算方法三、Python實作

參考

.PageRank算法--從原理到實作

零. PageRank算法簡介

PageRank算法,即網頁排名算法,由Google創始人Larry Page在斯坦福上學的時候提出來的。該算法用于對網頁進行排名,排名高的網頁表示該網頁被通路的機率高。

該算法的主要思想有兩點:

a. 如果多個網頁指向某個網頁A,則網頁A的排名較高。

b. 如果排名高A的網頁指向某個網頁B,則網頁B的排名也較高,即網頁B的排名受指向其的網頁的排名的影響。

一、PageRank算法原理

1. 簡單的PageRank算法

如圖是一個4個網頁之間的連結情況:

資料挖掘十大算法(六):PageRank算法原理與Python實作參考.PageRank算法--從原理到實作零. PageRank算法簡介一、PageRank算法原理二、PageRank值的計算方法三、Python實作

假設網頁X的排名用PR(X)表示,則A的排名為PR(A),由圖可知,網頁B和C指向了網頁A,那麼網頁A的排名可以表示為:

資料挖掘十大算法(六):PageRank算法原理與Python實作參考.PageRank算法--從原理到實作零. PageRank算法簡介一、PageRank算法原理二、PageRank值的計算方法三、Python實作

網頁C隻指向了A,不指向其他網頁,然而網頁B不僅指向了A,還指向了D,是以上面的公式更合理地修改為:

資料挖掘十大算法(六):PageRank算法原理與Python實作參考.PageRank算法--從原理到實作零. PageRank算法簡介一、PageRank算法原理二、PageRank值的計算方法三、Python實作

意思是,B的PageRank值被分給了A和D,而C的PageRank值全都給了A。

2. 考慮沒有出邊(outlink)的網頁

有的網頁,沒有指向其他網頁,如下圖中的C網頁。

資料挖掘十大算法(六):PageRank算法原理與Python實作參考.PageRank算法--從原理到實作零. PageRank算法簡介一、PageRank算法原理二、PageRank值的計算方法三、Python實作

那麼,假設網頁C的PageRank值被均分為到圖中的所有網頁(4個網頁),那麼A網頁的PageRank值可以表示為:

資料挖掘十大算法(六):PageRank算法原理與Python實作參考.PageRank算法--從原理到實作零. PageRank算法簡介一、PageRank算法原理二、PageRank值的計算方法三、Python實作

3. 網頁連結中存在環

資料挖掘十大算法(六):PageRank算法原理與Python實作參考.PageRank算法--從原理到實作零. PageRank算法簡介一、PageRank算法原理二、PageRank值的計算方法三、Python實作

圖中網頁C指向網頁C,不指向其他網頁。現實中,網頁自己指向自己的情況可能不太常見,但是有可能的情況是:若幹個頁面形成一個環,那麼使用者在進入其中某個網頁的時候,就陷入這個循環中。

假設當一個使用者,遇上這種情況時,以某個機率α随機指向其他任意一個網頁,每個網頁的機率相等。是以上圖中的網頁A的PageRank值可以表示為:

資料挖掘十大算法(六):PageRank算法原理與Python實作參考.PageRank算法--從原理到實作零. PageRank算法簡介一、PageRank算法原理二、PageRank值的計算方法三、Python實作

上面這個公式可以解釋為:α表示使用者從網頁B以機率α連結到網頁A,後面的(1-α)表示使用者從網頁C以機率(1-α)連結到網頁A。

即:

網頁B的PageRank值配置設定情況為:α*1/2給A, α*1/2給D,(1-α)/4分别給4個網頁。

網頁C的PageRank值配置設定情況為:α*1給自己C(1-α)*1/4分别給其他網頁。

4. 更一般的PageRank公式

綜合上面的論述,一般的PageRank計算公式為:

資料挖掘十大算法(六):PageRank算法原理與Python實作參考.PageRank算法--從原理到實作零. PageRank算法簡介一、PageRank算法原理二、PageRank值的計算方法三、Python實作

其中S(X)表示,指向網頁X的所有網頁的集合,n_i表示網頁Y_i的出邊數量,N表示所有網頁總數,α一般取0.85。

二、PageRank值的計算方法

1. 疊代法

利用前面得到的公式,進行疊代,直到疊代前後兩次的內插補點在允許的門檻值範圍内,疊代結束。

當然,可以将疊代過程寫成矩陣形式。推導過程如下:

針對前面的最後一個網絡圖,可以分别得到各個網頁的PageRank值得計算公式,如下:

資料挖掘十大算法(六):PageRank算法原理與Python實作參考.PageRank算法--從原理到實作零. PageRank算法簡介一、PageRank算法原理二、PageRank值的計算方法三、Python實作

寫成矩陣的形式為:

資料挖掘十大算法(六):PageRank算法原理與Python實作參考.PageRank算法--從原理到實作零. PageRank算法簡介一、PageRank算法原理二、PageRank值的計算方法三、Python實作

可以将上面的列向量和矩陣分别記為一些符号,上式表示為:

資料挖掘十大算法(六):PageRank算法原理與Python實作參考.PageRank算法--從原理到實作零. PageRank算法簡介一、PageRank算法原理二、PageRank值的計算方法三、Python實作

還有更簡潔的記法,記

資料挖掘十大算法(六):PageRank算法原理與Python實作參考.PageRank算法--從原理到實作零. PageRank算法簡介一、PageRank算法原理二、PageRank值的計算方法三、Python實作

A是一個常數矩陣,那麼,就有疊代公式:

資料挖掘十大算法(六):PageRank算法原理與Python實作參考.PageRank算法--從原理到實作零. PageRank算法簡介一、PageRank算法原理二、PageRank值的計算方法三、Python實作

也可以根據這個公式,進行疊代。

2. 代數法

因為,PageRank算法最終收斂(這個結論可以證明,此文不證明),是以,收斂時刻的PageRank值組成的列向量P應當滿足:

資料挖掘十大算法(六):PageRank算法原理與Python實作參考.PageRank算法--從原理到實作零. PageRank算法簡介一、PageRank算法原理二、PageRank值的計算方法三、Python實作

是以有:

資料挖掘十大算法(六):PageRank算法原理與Python實作參考.PageRank算法--從原理到實作零. PageRank算法簡介一、PageRank算法原理二、PageRank值的計算方法三、Python實作

這個方法不用疊代,求出矩陣的逆,就可以求出PageRank值組成的列向量P(然而,計算大規模的矩陣的逆,也是個難題。是以,這個方法代碼簡單,但效率可能不如疊代方法高)

三、Python實作

下面僅僅實作疊代法,代碼如下,需要用到Python的numpy庫用于矩陣乘法:

# 輸入為一個*.txt檔案,例如
# A B
# B C
# B A
# ...表示前者指向後者

import numpy as np


if __name__ == '__main__':

    # 讀入有向圖,存儲邊
    f = open('input_1.txt', 'r')
    edges = [line.strip('\n').split(' ') for line in f]
    print(edges)

    # 根據邊擷取節點的集合
    nodes = []
    for edge in edges:
        if edge[0] not in nodes:
            nodes.append(edge[0])
        if edge[1] not in nodes:
            nodes.append(edge[1])
    print(nodes)

    N = len(nodes)

    # 将節點符号(字母),映射成阿拉伯數字,便于後面生成A矩陣/S矩陣
    i = 0
    node_to_num = {}
    for node in nodes:
        node_to_num[node] = i
        i += 1
    for edge in edges:
        edge[0] = node_to_num[edge[0]]
        edge[1] = node_to_num[edge[1]]
    print(edges)

    # 生成初步的S矩陣
    S = np.zeros([N, N])
    for edge in edges:
        S[edge[1], edge[0]] = 1
    print(S)

    # 計算比例:即一個網頁對其他網頁的PageRank值的貢獻,即進行列的歸一化處理
    for j in range(N):
        sum_of_col = sum(S[:,j])
        for i in range(N):
            S[i, j] /= sum_of_col
    print(S)

    # 計算矩陣A
    alpha = 0.85
    A = alpha*S + (1-alpha) / N * np.ones([N, N])
    print(A)

    # 生成初始的PageRank值,記錄在P_n中,P_n和P_n1均用于疊代
    P_n = np.ones(N) / N
    P_n1 = np.zeros(N)

    e = 100000  # 誤差初始化
    k = 0   # 記錄疊代次數
    print('loop...')

    while e > 0.00000001:   # 開始疊代
        P_n1 = np.dot(A, P_n)   # 疊代公式
        e = P_n1-P_n
        e = max(map(abs, e))    # 計算誤差
        P_n = P_n1
        k += 1
        print('iteration %s:'%str(k), P_n1)

    print('final result:', P_n)
           

輸入的input_1.txt文本内容為:

A B
A C
A D
B D
C E
D E
B E
E A
           

結果為:

資料挖掘十大算法(六):PageRank算法原理與Python實作參考.PageRank算法--從原理到實作零. PageRank算法簡介一、PageRank算法原理二、PageRank值的計算方法三、Python實作

最後的一個數組,分别為A, B, C, D, E的PageRank值,其中E最高, A第二高, B和C相同均最低。

我們再來看一下這個可視化的有向圖:

資料挖掘十大算法(六):PageRank算法原理與Python實作參考.PageRank算法--從原理到實作零. PageRank算法簡介一、PageRank算法原理二、PageRank值的計算方法三、Python實作

可以看出,有3條邊指向E。再看,指向A的這個點是E點,是以A的PageRank值也很高,可以說“A沾了E的光”。

上面的可視化代碼如下:

import networkx as nx
import matplotlib.pyplot as plt


if __name__ == '__main__':

    # 讀入有向圖,存儲邊
    f = open('input_1.txt', 'r')
    edges = [line.strip('\n').split(' ') for line in f]

    G = nx.DiGraph()
    for edge in edges:
        G.add_edge(edge[0], edge[1])
    nx.draw(G, with_labels=True)
    plt.show()
           

繼續閱讀