PageRank算法簡介及Map-Reduce實現

一、什麼是pagerank

PageRank的Page可是認爲是網頁,表示網頁排名,也可以認爲是Larry Page(google 產品經理),因爲他是這個算法的發明者之一,還是google CEO(^_^)。PageRank算法計算每一個網頁的PageRank值,然後根據這個值的大小對網頁的重要性進行排序。它的思想是模擬一個悠閒的上網者,上網者首先隨機選擇一個網頁打開,然後在這個網頁上呆了幾分鐘後,跳轉到該網頁所指向的鏈接,這樣無所事事、漫無目的地在網頁上跳來跳去,PageRank就是估計這個悠閒的上網者分佈在各個網頁上的概率。

二、最簡單pagerank模型

互聯網中的網頁可以看出是一個有向圖,其中網頁是結點,如果網頁A有鏈接到網頁B,則存在一條有向邊A->B,下面是一個簡單的示例:

201959072629566

 

這個例子中只有四個網頁,如果當前在A網頁,那麼悠閒的上網者將會各以1/3的概率跳轉到B、C、D,這裏的3表示A有3條出鏈,如果一個網頁有k條出鏈,那麼跳轉任意一個出鏈上的概率是1/k,同理D到B、C的概率各爲1/2,而B到C的概率爲0。一般用轉移矩陣表示上網者的跳轉概率,如果用n表示網頁的數目,則轉移矩陣M是一個n*n的方陣;如果網頁j有k個出鏈,那麼對每一個出鏈指向的網頁i,有M[i][j]=1/k,而其他網頁的M[i][j]=0;上面示例圖對應的轉移矩陣如下:

202015378717604

 

初試時,假設上網者在每一個網頁的概率都是相等的,即1/n,於是初試的概率分佈就是一個所有值都爲1/n的n維列向量V0,用V0去右乘轉移矩陣M,就得到了第一步之後上網者的概率分佈向量MV0,(nXn)*(nX1)依然得到一個nX1的矩陣。下面是V1的計算過程:

202114099185287

 

注意矩陣M中M[i][j]不爲0表示用一個鏈接從j指向i,M的第一行乘以V0,表示累加所有網頁到網頁A的概率即得到9/24。得到了V1後,再用V1去右乘M得到V2,一直下去,最終V會收斂,即Vn=MV(n-1),上面的圖示例,不斷的迭代,最終V=[3/9,2/9,2/9,2/9]’:

261719185728644

三、終止點問題

上述上網者的行爲是一個馬爾科夫過程的實例,要滿足收斂性,需要具備一個條件:

  • 圖是強連通的,即從任意網頁可以到達其他任意網頁:

互聯網上的網頁不滿足強連通的特性,因爲有一些網頁不指向任何網頁,如果按照上面的計算,上網者到達這樣的網頁後便走投無路、四顧茫然,導致前面累計得到的轉移概率被清零,這樣下去,最終的得到的概率分佈向量所有元素幾乎都爲0。假設我們把上面圖中C到A的鏈接丟掉,C變成了一個終止點,得到下面這個圖:

fclkjfljaljfldkjglksajglasgj1

對應的轉移矩陣爲:

fclajsdfkdjsaglkjsdglsajg2

連續迭代下去,最終所有元素都爲0:

fclakjsgflkgjlsajgsajg3

四、陷阱問題

另外一個問題就是陷阱問題,即有些網頁不存在指向其他網頁的鏈接,但存在指向自己的鏈接。比如下面這個圖:

ljlajkjasglkjsdgkjsgla1

上網者跑到C網頁後,就像跳進了陷阱,陷入了漩渦,再也不能從C中出來,將最終導致概率分佈值全部轉移到C上來,這使得其他網頁的概率分佈值爲0,從而整個網頁排名就失去了意義。如果按照上面圖對應的轉移矩陣爲:

fclajsdfkdjsaglkjsdglsajg2

不斷的迭代下去,就變成了這樣:

202136578712805

 

五、解決終止點問題和陷阱問題

上面過程,我們忽略了一個問題,那就是上網者是一個悠閒的上網者,而不是一個愚蠢的上網者,我們的上網者是聰明而悠閒,他悠閒,漫無目的,總是隨機的選擇網頁,他聰明,在走到一個終結網頁或者一個陷阱網頁(比如兩個示例中的C),不會傻傻的乾着急,他會在瀏覽器的地址隨機輸入一個地址,當然這個地址可能又是原來的網頁,但這裏給了他一個逃離的機會,讓他離開這萬丈深淵。模擬聰明而又悠閒的上網者,對算法進行改進,每一步,上網者可能都不想看當前網頁了,不看當前網頁也就不會點擊上面的連接,而上悄悄地在地址欄輸入另外一個地址,而在地址欄輸入而跳轉到各個網頁的概率是1/n。假設上網者每一步查看當前網頁的概率爲a,那麼他從瀏覽器地址欄跳轉的概率爲(1-a),於是原來的迭代公式轉化爲:

202158112317322

現在我們來計算帶陷阱的網頁圖的概率分佈:

202205000122441

重複迭代下去,得到:

261719185728644

六、用Map-reduce計算Page Rank

  上面的演算過程,採用矩陣相乘,不斷迭代,直到迭代前後概率分佈向量的值變化不大,一般迭代到30次以上就收斂了。真的的web結構的轉移矩陣非常大,目前的網頁數量已經超過100億,轉移矩陣是100億*100億的矩陣,直接按矩陣乘法的計算方法不可行,需要藉助Map-Reduce的計算方式來解決。實際上,google發明Map-Reduce最初就是爲了分佈式計算大規模網頁的pagerank,Map-Reduce的pagerank有很多實現方式,我這裏計算一種簡單的。

考慮轉移矩陣是一個很多的稀疏矩陣,我們可以用稀疏矩陣的形式表示,我們把web圖中的每一個網頁及其鏈出的網頁作爲一行,這樣第四節中的web圖結構用如下方式表示:

A有三條出鏈,分佈指向A、B、C,實際上,我們爬取的網頁結構數據就是這樣的。

1、Map階段

Map操作的每一行,對所有出鏈發射當前網頁概率值的1/k,k是當前網頁的出鏈數,比如對第一行輸出<B,1/3*1/4>,<C,1/3*1/4>,<D,1/3*1/4>;

2、Reduce階段

Reduce操作收集網頁id相同的值,累加並按權重計算,pj=a*(p1+p2+…Pm)+(1-a)*1/n,其中m是指向網頁j的網頁j數,n所有網頁數。

思路就是這麼簡單,但是實踐的時候,怎樣在Map階段知道當前行網頁的概率值,需要一個單獨的文件專門保存上一輪的概率分佈值,先進行一次排序,讓出鏈行與概率值按網頁id出現在同一Mapper裏面,整個流程如下:

211557326376640

 

這樣進行一次迭代相當於需要兩次MapReduce,但第一次的MapReduce只是簡單的排序,不需要任何操作,用python調用Hadoop的Streaming.

SortMappert.py代碼如下:

SortReducer.py也是一樣

PageRankMapper.py代碼:

PageRankReducer.py代碼:

在linux下模仿Map-Reduce的過程:

這個代碼不用改動就可以直接在hadoop上跑起來。調用hadoop命令:

關於使用python操作hadoop可以查看參考文獻。python代碼寫得濃濃的C味,望海涵!

第四步中帶環的陷阱圖,迭代40次,權值a取0.8,計算結果如下:

可以看到pagerank值已經基本趨於穩定,並與第四步的分數表示一致。

PageRank的簡介就介紹到這裏了,如果想深入可以參考原論文或者下面的參考文獻

參考文獻

1.《Mining of Massive Datasets》

2.《An introduction to information retrival》

3.使用python操作Hadoop


原文http://blog.jobbole.com/71431/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章