矩陣:如何使用矩陣操作進行 PageRank 計算?
內容選自《程式設計師的數學基礎課》
你好,我是黃申。今天我來說說矩陣。
矩陣由多個長度相等的向量組成,其中的每列或者每行就是一個向量。從資料結構的角度來看,我們可以把向量看作一維陣列,把矩陣看作二維陣列。
具有了二維陣列的特性,矩陣就可以表達二元關係了,例如圖中結點的鄰接關係,或者是使用者對物品的評分關係。而通過矩陣上的各種運算操作,我們就可以挖掘這些二元關係,在不同的應用場景下達到不同的目的。今天我就從圖的鄰接矩陣出發,展示如何使用矩陣計算來實現PageRank演算法。
回顧PageRank連結分析演算法
在講馬爾科夫模型的時候,我已經介紹了PageRank連結分析演算法。所以,在展示這個演算法和矩陣操作的關係之前,我們快速回顧一下它的核心思想。
PageRank是基於馬爾科夫鏈的。它假設了一個“隨機衝浪者”模型,衝浪者從某張網頁出發,根據Web圖中的連結關係隨機訪問。在每個步驟中,衝浪者都會從當前網頁的鏈出網頁中,隨機選取一張作為下一步訪問的目標。此外,PageRank還引入了隨機的跳轉操作,這意味著衝浪者不是按Web圖的拓撲結構走下去,只是隨機挑選了一張網頁進行跳轉。
基於之前的假設,PageRank的公式定義如下:
其中,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的公式就簡化為:
這個公式只包含了原公式中的Σ(PR(pj)/L(pj))部分。我們再來對比看看矩陣點乘的計算公式。
以上兩個公式在形式上是基本一致的。因此,我們可以把Σ(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。
為了方便你理解,我用下面這個拓撲圖作為例子給你詳細解釋。
基於上面這個圖,原始矩陣為:
其中第i行、第j列的元素值表示從結點i到j是不是存在連結。如果是,那麼這個值為1;否則就為0。
按照每一行的和,分別對每一行進行歸一化之後的矩陣就變為:
有了上述這個鄰接矩陣,我們就可以開始最簡單的PageRank計算。PageRank的計算是取樣迭代法實現的。這裡我把初始值都設為1,並把第一次計算的結果列在這裡。
好了,我們已經成功邁出了第一步,但是還需要考慮隨機跳轉的可能性。
考慮隨機跳轉
經過上面的步驟,我們已經求得Σ(PR(pj)/L(pj))部分。不過,PageRank引入了隨機跳轉的機制。這一部分其實也是可以通過矩陣的點乘來實現的。我們把Σ(PR(pj)/L(pj))部分用A表示,那麼完整的PageRank公式就可以表示為:
於是,我們可以把上述公式分解為如下兩個矩陣的點乘:
我們仍然使用前面的例子,來看看經過隨機跳轉之後,PageRank值變成了多少。這裡α取0.9。
我們前面提到,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均值聚類演算法時,就提到了需要計算某個資料點向量、其他資料點向量之間的距離或者相似度,以及使用多個資料點向量的平均值來獲得質心點的向量,這些都可以通過矩陣操作來完成。
另外,在協同過濾的推薦中,我們可以使用矩陣點乘,來實現多個使用者或者物品之間的相似程度,以及聚集後的相似程度所導致的最終推薦結果。下一節,我會使用矩陣來表示使用者和物品的二元關係,並通過矩陣來計算協同過濾的結果。
相關文章
- 矩陣計算矩陣
- 計算矩陣的秩矩陣
- 基於勝率矩陣的PageRank排序矩陣排序
- 巨大的矩陣(矩陣加速)矩陣
- 鄰接矩陣、度矩陣矩陣
- 奇異矩陣,非奇異矩陣,偽逆矩陣矩陣
- 資料結構:陣列,稀疏矩陣,矩陣的壓縮。應用:矩陣的轉置,矩陣相乘資料結構陣列矩陣
- 矩陣矩陣
- 頭條號矩陣運營工具,運營矩陣進行多賬號管理矩陣
- 求任意矩陣的伴隨矩陣矩陣
- 怎樣用python計算矩陣乘法?Python矩陣
- matlab計算含有未知數的矩陣Matlab矩陣
- NYOJ 1409 快速計算【矩陣連乘】矩陣
- c語言中實現4行3列矩陣和3行4列矩陣的運算C語言矩陣
- 矩陣和陣列矩陣陣列
- 機器學習二——利用numpy庫對矩陣進行操作機器學習矩陣
- Numpy中的矩陣運算矩陣
- 矩陣乘法矩陣
- 螺旋矩陣矩陣
- 8.6 矩陣?矩陣
- 找矩陣矩陣
- 海浪矩陣矩陣
- 矩陣相乘矩陣
- 稀疏矩陣矩陣
- 矩陣分解矩陣
- 理解矩陣矩陣
- 深度學習中需要的矩陣計算深度學習矩陣
- excel如何做共詞矩陣?excel做共詞矩陣教程Excel矩陣
- 快手矩陣管理平臺,矩陣管理有方法矩陣
- 雜項——矩陣加速(進階)矩陣
- 【numpy學習筆記】矩陣操作筆記矩陣
- 機器學習中的矩陣向量求導(五) 矩陣對矩陣的求導機器學習矩陣求導
- pytorch基礎七(矩陣運算)PyTorch矩陣
- 演算法學習:矩陣快速冪/矩陣加速演算法矩陣
- python 計算矩陣的相關演算法Python矩陣演算法
- 計算機圖形學之矩陣變換計算機矩陣
- 高效能運算&CUDA | 使用numba對三維矩陣在gpu上進行運算矩陣GPU
- 矩陣求逆矩陣