PageRank算法以及Python实现(简洁版)
簡述
PageRank有點被神化了,其實公式很簡單。
文章目錄
- 簡述
- 算法
- 模型定義
- Flow版本
- Google Formula
- 實現
算法
主要是分為兩種:
- The ‘Flow’ formula
- The Google formula
模型定義
很多個網頁,直接存在鏈路關系,設為G,N*N的矩陣
這里先只考慮有向無權無環圖,即邊有方向,且權重都一樣,且沒有自己到自己的邊(環)。
- N為節點數或者是網頁數
- G[i][j] = 1表示,i->j有條邊
Flow版本
ri=∑(j=1)and(j?>i)Nrjdjr_i = \sum_{(j=1) and (j -> i)}^N{\frac{r_j}{d_j}}ri?=(j=1)and(j?>i)∑N?dj?rj??
一個很好是數學寫法就是:
r=M?rr = M * rr=M?r
- 如果有i->j, M[j][i] = 1/dj,否者為0
算法流程:
-
也就是,隨機初始化每個點的分數
-
然后,迭代:
- 每個點的分數,由所有 指向他的節點的分數 除以 這個節點的出度數 求和所替代
-
Flow版本會出現兩個重要的問題;
- Dead End:例如只有兩個點,然后邊為A->B,B就是一個Dead END。即到這時候的分數就出不去了。
- Spider Traps:循環指向,例如A->B->A。那么這個分數就會這之間打轉
Google Formula
剛剛說的兩個問題在Google Formula上得到很好的改進:
- 提出了一個叫做Teleport的概念,也稱之為意念轉移。
很簡單,就是說,每個節點有一定的概率發生隨機跳轉到任意一個點的情況。再結合MapReduce的概念,Google就這樣發家了emmmm
ri=β?∑(j=1)and(j?>i)Nrjdj+(1?β)?1Nr_i = \beta * \sum_{(j=1) and (j -> i)}^N{\frac{r_j}{d_j}} + (1 - \beta) * \frac{1}{N}ri?=β?(j=1)and(j?>i)∑N?dj?rj??+(1?β)?N1?
直接的數學表達:
r=A?rA=β?M+(1?β)?[1N]N?Nr = A * r \\ A = \beta * M + (1-\beta) * [\frac{1}{N}]_{N*N}r=A?rA=β?M+(1?β)?[N1?]N?N?
Google簡化后的數學表達:
r=β?M?r+[1N]Nr = \beta * M * r + [\frac{1}{N}]_Nr=β?M?r+[N1?]N?
- 如果有i->j, M[j][i] = 1/dj,否者為0
存在的問題:
- 雖然直接的數學表達會更簡潔,但是多出來的A一定會是稠密矩陣使得空間消耗為O(N^2)了,這樣的在網站達到數億的情況下,這個東西就不太現實了。
- 而Google簡化的版本中就只需要記錄同樣稀疏的M即可,1/N是一個數,只需要讓r這個向量的每個元素都加上即可(簡單的數學變形,在工業上的產生的價值就很大的不一樣了。真的佩服研究數學的哥們)
實現
實現同樣做兩個不同的版本的:
但有些共同的模型:
導入包:
import numpy as np import random創造數據:
def create_data(N, alpha=0.5): # random > alpha, then here is a edge.G = np.zeros((N, N))for i in range(N):for j in range(N):if i == j:continueif random.random() < alpha:G[i][j] = 1return G G = create_data(10)GtoM:
def GtoM(G, N):M = np.zeros((N, N))for i in range(N):D_i = sum(G[i])if D_i == 0:continuefor j in range(N):M[j][i] = G[i][j] / D_i # watch out! M_j_i instead of M_i_jreturn M M = GtoM(G, 10)- Flow版本的PageRank
測試下:
values = PageRank(M, 10, T=2000) values輸出:
array([0.09972576, 0.09193927, 0.07843151, 0.09125886, 0.08925602,0.10407245, 0.09623654, 0.13851257, 0.13086464, 0.07970237])- Google Formula
同樣的數據測試下:
測試下:
values = PageRank(M, 10, T=2000) values輸出:
array([0.09815807, 0.09250429, 0.08376235, 0.09300133, 0.09324628,0.10108776, 0.09855127, 0.13019363, 0.12458992, 0.0849051 ])總結
以上是生活随笔為你收集整理的PageRank算法以及Python实现(简洁版)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python过滤掉numpy.array
- 下一篇: SVD理论以及Python实现