1. 程式人生 > >PageRank演算法我的java程式碼的實現

PageRank演算法我的java程式碼的實現

PageRank對網頁排名的演算法,曾是Google發家致富的法寶。以前雖然有實驗過,但理解還是不透徹,這幾天又看了一下,這裡總結一下PageRank演算法的基本原理。

一、什麼是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圖結構用如下方式表示:

1 2 3 4 1 A    B    C    D 2 B    A    D 3 C    C 4 D    B    C

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程式碼如下:

1 2 3 4 5 1 #!/bin/python 2 '''Mapper for sort''' 3 import sys 4 for line in sys.stdin: 5      print line.strip()

SortReducer.py也是一樣

1 2 3 4 5 1 #!/bin/python 2 '''Reducer for sort''' 3 import sys 4 for line in sys.stdin: 5       print line.strip()

PageRankMapper.py程式碼:

1 2 3 4 5

相關推薦

多種負載均衡演算法及其Java程式碼實現【網路上較好的轉載】

首先給大家介紹下什麼是負載均衡(來自百科) 負載均衡 建立在現有網路結構之上,它提供了一種廉價有效透明的方法擴充套件 網路裝置和 伺服器的頻寬、增加 吞吐量、加強網路資料處理能力、提高網路的靈活性和可用性。 負載均衡,英文名稱為Load Balance,其意思就

一致性Hash演算法Java程式碼實現

一致性Hash演算法 關於一致性Hash演算法,在我之前的博文中已經有多次提到了,MemCache超詳細解讀一文中"一致性Hash演算法"部分,對於為什麼要使用一致性Hash演算法、一致性Hash演算法的演算法原理做了詳細的解讀。 演算法的具體原理這裡再次貼上: 先構造

常見14種經典排序演算法Java程式碼實現

尊重原創,轉載請標明出處   http://blog.csdn.net/abcdef314159 ,想了解更多演算法題可以關注微信公眾號“資料結構和演算法”,每天一題為你精彩解答。 一,氣泡排序 排序演算法其實有很多,氣泡排序基本上算是最簡單的一種

二分查詢演算法java程式碼實現

一、演算法思想 首先,假設表中元素是按升序排列,將表中間位置記錄的關鍵字與查詢關鍵字比較,如果兩者相等,則查詢成功;否則利用中間位置記錄將表分成前、後兩個子表,如果中間位置記錄的關鍵字大於查詢關鍵字,則進一步查詢前一子表,否則進一步查詢後一子表。重複以上過程,直到找到滿足條

基於矩陣分解的推薦演算法java程式碼實現

目前推薦系統中用的最多的就是矩陣分解方法,在Netflix Prize推薦系統大賽中取得突出效果。以使用者-專案評分矩陣為例,矩陣分解就是預測出評分矩陣中的缺失值,然後根據預測值以某種方式向用戶推薦。常見的矩陣分解方法有基本矩陣分解(basic MF),正則化矩

對一致性Hash演算法Java程式碼實現的深入研究

1 /** 2 * 帶虛擬節點的一致性Hash演算法 3 * @author 五月的倉頡 http://www.cnblogs.com/xrq730/ 4 */ 5 public class ConsistentHashingWithVirtualNode 6 { 7

常用的八種排序演算法Java程式碼實現

1.直接插入排序 經常碰到這樣一類排序問題:把新的資料插入到已經排好的資料列中。 將第一個數和第二個數排序,然後構成一個有序序列 將第三個數插入進去,構成一個新的有序序列。 對第四個數、第五個數……直到最後一個數,重複第二步。

現代應用密碼學中橢圓曲線求點集E以及點乘演算法java程式碼實現

【問題】: (1)生成橢圓曲線有限域上的點集。給定p=211,a=0,b=-4 (2) 給定生成元G(2,2)找出其他點與生成元之間的關係。 【解答】:面多較大的有限域p,依靠手動計算以及不符合實際,因此我在理解橢圓曲線數學原理和點乘演算法的基礎上,用java程式編寫完

銀行家演算法java程式碼實現,Swing寫的介面

java程式碼實現了銀行家演算法,介面寫的個人認為還是較為細緻的,完整的實現了找安全序列等演算法功能,可作為參考學習銀行家演算法。 直接上程式碼:①介面展示方法:public void ShowFrame() { t

mahout推薦演算法——協同過濾推薦演算法java程式碼實現

什麼是協同過濾 協同過濾是利用集體智慧的一個典型方法。要理解什麼是協同過濾 (Collaborative Filtering, 簡稱 CF),首先想一個簡單的問題,如果你現在想看個電影,但你不知道具體看哪部,你會怎麼做?大部分的人會問問周圍的朋友,看看最近有什麼好看的電影推

PageRank演算法java程式碼實現

PageRank對網頁排名的演算法,曾是Google發家致富的法寶。以前雖然有實驗過,但理解還是不透徹,這幾天又看了一下,這裡總結一下PageRank演算法的基本原理。 一、什麼是pagerank PageRank的Page可是認為是網頁,表示網頁排名

最短路徑A*演算法原理及java程式碼實現(看不懂是的失敗)

package astar; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; imp

Java程式碼實現負載均衡五種演算法

版權宣告:本文為博主原創文章,未經博主允許不得轉載。    https://blog.csdn.net/u012904383/article/details/78358354 前言:        

演算法學習——中國大學MOOC-陳越、何欽銘-資料結構-起步能力自測題——java程式碼實現

自測-1 列印沙漏 (20 point(s)) 本題要求你寫個程式把給定的符號列印成沙漏的形狀。例如給定17個“*”,要求按下列格式列印 ***** *** * *** ***** 所謂“沙漏形狀”,是指每行輸出奇數個符號;各行符號中心對齊;相鄰兩行符號數差2;符號數先從大

十大經典排序演算法詳細總結(含JAVA程式碼實現)

文章目錄 十大經典排序演算法詳細總結(含JAVA程式碼實現) 0、排序演算法說明 1、氣泡排序(Bubble Sort) 2、選擇排序(Selection Sort) 3、插入排序(Insertion Sort) 4、希爾

十大排序演算法實現 十大經典排序演算法最強總結(含JAVA程式碼實現

十大經典排序演算法最強總結(含JAVA程式碼實現)   最近幾天在研究排序演算法,看了很多部落格,發現網上有的文章中對排序演算法解釋的並不是很透徹,而且有很多程式碼都是錯誤的,例如有的文章中在“桶排序”演算法中對每個桶進行排序直接使用了Collection.sort

買什麼資料結構與演算法,這裡有:動態圖解十大經典排序演算法(含JAVA程式碼實現

上篇的動圖資料結構反響不錯,這次來個動圖排序演算法大全。資料結構與演算法,齊了。 幾張動態圖捋清Java常用資料結構及其設計原理 本文將採取動態圖+文字描述+正確的java程式碼實現來講解以下十大排序演算法: 氣泡排序 選擇排序 插入排序 希爾排序

【資料結構與演算法】回溯法解決N皇后問題,java程式碼實現

N皇后問題 問題描述 在8×8格的國際象棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法,這稱為八皇后問題。 延伸一下,便為N皇后問題。 核心思想 解決N皇后問題有兩個關鍵點。一是如何進行放置棋子,二是如何驗證棋子是否符合

【資料結構與演算法】貪心演算法解決揹包問題。java程式碼實現

揹包問題(貪心演算法) 貪心演算法思想 簡單的說,就是將大問題轉化為最優子問題,例如本題所要求的,揹包容量有限,要想使物品的總價值最高,那麼,我們必須儘可能的選擇權重高的(即單位價值更高)的物品進行裝載。 在揹包問題中,物品是可拆的,即可以分成任意部分進行裝載,而最終實現的目標是

排序演算法總結(含動圖演示和Java程式碼實現)

本文將圍繞氣泡排序、桶排序、計數排序、堆排序、插入排序、並歸排序、快速排序和選擇排序,按照描述、時間複雜度(最壞情況)、動態圖展示和程式碼實現來講解。本文預設排序為從小到大。 本文相關程式碼已上傳至github,歡迎關注https://github.com/zhuzhenke/commo