矩陣:如何使用矩陣操作進行 PageRank 計算?

weixin_34253539發表於2019-03-21

內容選自《程式設計師的數學基礎課》

你好,我是黃申。今天我來說說矩陣。

矩陣由多個長度相等的向量組成,其中的每列或者每行就是一個向量。從資料結構的角度來看,我們可以把向量看作一維陣列,把矩陣看作二維陣列。

具有了二維陣列的特性,矩陣就可以表達二元關係了,例如圖中結點的鄰接關係,或者是使用者對物品的評分關係。而通過矩陣上的各種運算操作,我們就可以挖掘這些二元關係,在不同的應用場景下達到不同的目的。今天我就從圖的鄰接矩陣出發,展示如何使用矩陣計算來實現PageRank演算法。

回顧PageRank連結分析演算法

在講馬爾科夫模型的時候,我已經介紹了PageRank連結分析演算法。所以,在展示這個演算法和矩陣操作的關係之前,我們快速回顧一下它的核心思想。

PageRank是基於馬爾科夫鏈的。它假設了一個“隨機衝浪者”模型,衝浪者從某張網頁出發,根據Web圖中的連結關係隨機訪問。在每個步驟中,衝浪者都會從當前網頁的鏈出網頁中,隨機選取一張作為下一步訪問的目標。此外,PageRank還引入了隨機的跳轉操作,這意味著衝浪者不是按Web圖的拓撲結構走下去,只是隨機挑選了一張網頁進行跳轉。

基於之前的假設,PageRank的公式定義如下:

\"image\"

其中,pi表示第i張網頁,Mi是pi的入連結集合,pj是Mi集合中的第j張網頁。PR(pj)表示網頁pj的PageRank得分,L(pj)表示網頁pj的出連結數量,1/L(pj)就表示從網頁pj跳轉到pi的概率。α是使用者不進行隨機跳轉的概率,N表示所有網頁的數量。

PageRank的計算是取樣迭代法實現的:一開始所有網頁結點的初始PageRank值都可以設定為某個相同的數,例如1,然後我們通過上面這個公式,得到每個結點新的PageRank值。每當一張網頁的PageRank發生了改變,它也會影響它的出連結所指向的網頁,因此我們可以再次使用這個公式,迴圈地修正每個網頁結點的值。由於這是一個馬爾科夫過程,所以我們能從理論上證明,所有網頁的PageRank最終會達到一個穩定的數值。整個證明過程很複雜,這裡我們只需要知道這個迭代計算的過程就行了。

簡化PageRank公式

那麼,這個計算公式和矩陣操作又有什麼聯絡呢?為了把問題簡化,我們暫時不考慮隨機跳轉的情況,而只考慮使用者按照網頁間連結進行隨機衝浪。那麼PageRank的公式就簡化為:

\"image\"

這個公式只包含了原公式中的Σ(PR(pj)/L(pj))部分。我們再來對比看看矩陣點乘的計算公式。

\"image\"

以上兩個公式在形式上是基本一致的。因此,我們可以把Σ(PR(pj)/L(pj))的計算,分解為兩個矩陣的點乘。一個矩陣是當前每張網頁的PageRank得分,另一個矩陣就是鄰接矩陣。所謂鄰接矩陣,其實就是表示圖結點相鄰關係的矩陣。

假設xi,j是矩陣中第i行、第j列的元素,那麼我們就可以使用xi,j表示從結點i到結點j的連線,放到PageRank的應用場景,xi,j就表示網頁pi到網頁pj的連結。最原始的鄰接矩陣所包含的元素是0或1,0表示沒有連結,而1表示有連結。

考慮到PageRank裡乘積是1/L(pj),我們可以對鄰接矩陣的每一行進行歸一化,用原始的值(0或1)除以L(pj),而L(pj)表示有某張網頁pj的出連結,正好是矩陣中pj這一行的和。所以,我們可以對原始的鄰接矩陣,進行基於行的歸一化,這樣就能得到每個元素為1/L(pj)的矩陣,其中j表示矩陣的第j行。注意,這裡的歸一化是指讓所有元素加起來的和為1。

為了方便你理解,我用下面這個拓撲圖作為例子給你詳細解釋。

\"image\"

基於上面這個圖,原始矩陣為:

\"image\"

其中第i行、第j列的元素值表示從結點i到j是不是存在連結。如果是,那麼這個值為1;否則就為0。

按照每一行的和,分別對每一行進行歸一化之後的矩陣就變為:

\"image\"

有了上述這個鄰接矩陣,我們就可以開始最簡單的PageRank計算。PageRank的計算是取樣迭代法實現的。這裡我把初始值都設為1,並把第一次計算的結果列在這裡。

\"image\"

好了,我們已經成功邁出了第一步,但是還需要考慮隨機跳轉的可能性。

考慮隨機跳轉

經過上面的步驟,我們已經求得Σ(PR(pj)/L(pj))部分。不過,PageRank引入了隨機跳轉的機制。這一部分其實也是可以通過矩陣的點乘來實現的。我們把Σ(PR(pj)/L(pj))部分用A表示,那麼完整的PageRank公式就可以表示為:

\"image\"

於是,我們可以把上述公式分解為如下兩個矩陣的點乘:

\"image\"

我們仍然使用前面的例子,來看看經過隨機跳轉之後,PageRank值變成了多少。這裡α取0.9。

\"image\"

我們前面提到,PageRank演算法需要迭代式計算。為了避免計算後的數值越來越大甚至溢位,我們可以進行歸一化處理,保證所有結點的數值之和為1。經過這個處理之後,我們得到第一輪的PageRank數值,也就是下面這個行向量:
[0.37027027 0.24864865 0.37027027 0.00540541 0.00540541]

接下來,我們只需要再重複之前的步驟,直到每個結點的值趨於穩定就可以了。

使用Python進行實現

說到這裡,我已經把如何把整個PageRank的計算,轉換成多個矩陣的點乘這個過程講完了。這樣一來,我們就可以利用Python等科學計算語言提供的庫,來完成基於PageRank的連結分析。為了展示具體的程式碼,我以之前的拓撲圖為例,給你詳細講述每一步。

首先,我們要進行一些初始化工作,包括設定結點數量、確定隨機跳轉概率的α、代表拓撲圖的鄰接矩陣以及存放所有結點PageRank值的陣列。下面是一段示例程式碼,在程式碼中我提供了註釋供你參考。

import numpy as np# 設定確定隨機跳轉概率的alpha、網頁結點數alpha = 0.9N = 5# 初始化隨機跳轉概率的矩陣jump = np.full([2,1], [[alpha], [1-alpha]], dtype=float)# 鄰接矩陣的構建adj = np.full([N,N], [[0,0,1,0,0],[1,0,1,0,0],[1,0,0,0,0],[0,0,0,0,0],[0,1,0,0,0]], dtype=float)# 對鄰接矩陣進行歸一化row_sums = adj.sum(axis=1)      # 對每一行求和row_sums[row_sums == 0] = 0.1   # 防止由於分母出現0而導致的Nanadj = adj / row_sums[:, np.newaxis] # 除以每行之和的歸一化# 初始的PageRank值,通常是設定所有值為1.0pr = np.full([1,N], 1, dtype=float)

之後,我們就能採用迭代法來計算PageRank值。一般我們通過比較每個結點最近兩次計算的值是否足夠接近,來確定數值是不是已經穩定,以及是不是需要結束迭代。這裡為簡便起見,我使用了固定次數的迴圈來實現。如果你的拓撲圖比較複雜,需要更多次迭代,我把示例程式碼和註釋列在這裡。

# PageRank演算法本身是取樣迭代方式進行的,當最終的取值趨於穩定後結束。for i in range(0, 20):    # 進行點乘,計算Σ(PR(pj)/L(pj))    pr = np.dot(pr, adj)    # 轉置儲存Σ(PR(pj)/L(pj))結果的矩陣,並增加長度為N的列向量,其中每個元素的值為1/N,便於下一步的點乘。    pr_jump = np.full([N, 2], [[0, 1/N]])    pr_jump[:,:-1] = pr.transpose()    # 進行點乘,計算α(Σ(PR(pj)/L(pj))) + (1-α)/N)    pr = np.dot(pr_jump, jump)    # 歸一化PageRank得分    pr = pr.transpose()    pr = pr / pr.sum()    print(\u0026quot;round\u0026quot;, i + 1, pr)

如果成功執行了上述兩段程式碼,你就能看到每個結點最終獲得的PageRank分數是多少。

Python中還有一些很不錯的庫,提供了直接構建拓撲圖和計算PageRank的功能,例如networkx。你可以嘗試使用這種庫,構建樣例拓撲圖並計算每個結點的PageRank得分,最後和上述程式碼所計算的PageRank得分進行比較,驗證一下上述程式碼的結果是不是合理。

總結

我們可以把向量看作一維陣列,把矩陣看作二維陣列。矩陣的點乘,是由若干個向量的點乘組成的,所以我們可以通過矩陣的點乘操作,挖掘多組向量兩兩之間的關係。

今天我們講了矩陣的點乘操作在PageRank演算法中的應用。通過表示網頁的鄰接二元關係,我們可以使用矩陣來計算PageRank的得分。在這個應用場景下,矩陣點乘體現了多個馬爾科夫過程中的狀態轉移。

矩陣點乘和其他運算操作,還可以運用在很多其他的領域。例如,我在上一節介紹K均值聚類演算法時,就提到了需要計算某個資料點向量、其他資料點向量之間的距離或者相似度,以及使用多個資料點向量的平均值來獲得質心點的向量,這些都可以通過矩陣操作來完成。

另外,在協同過濾的推薦中,我們可以使用矩陣點乘,來實現多個使用者或者物品之間的相似程度,以及聚集後的相似程度所導致的最終推薦結果。下一節,我會使用矩陣來表示使用者和物品的二元關係,並通過矩陣來計算協同過濾的結果。

相關文章