公號:碼農充電站pro
主頁:https://codeshellme.github.iohtml
在互聯網早期,隨着網絡上的網頁逐漸增多,如何從海量網頁中檢索出咱們想要的頁面,變得很是的重要。python
當時著名的雅虎和其它互聯網公司都試圖解決這個問題,但都沒能有一個很好的解決方案。git
直到1998 年先後,兩位斯坦福大學的博士生,拉里·佩奇和謝爾蓋·布林一塊兒發明了著名的 PageRank 算法,才完美的解決了網頁排名的問題。也正是由於這個算法,誕生了偉大的 Google 公司。github
(上圖中:左爲布林,右爲佩奇。)算法
PageRank 算法的核心原理是:在互聯網中,若是一個網頁被不少其它網頁所連接,說明該網頁很是的重要,那麼它的排名就高。shell
拉里·佩奇將整個互聯網當作一張大的圖,每一個網站就像一個節點,而每一個網頁的連接就像一個弧。那麼,互聯網就能夠用一個圖或者矩陣來描述。數組
拉里·佩奇也因該算法在30 歲時當選爲美國工程院院士。網絡
假設目前有4 個網頁,分別是 A,B,C,D,它們的連接關係以下:數據結構
咱們規定有兩種鏈:工具
好比圖中的C 網頁,有兩個入鏈,一個出鏈。
PageRank 的思想就是,一個網頁的影響力就等於它的全部入鏈的影響力之和。
用數學公式表示爲:
其中(分值表明頁面影響力):
PR(u)
是網頁u
的分值。Bu
是網頁u
的入鏈集合。v
是網頁u
的任意一個入鏈。PR(v)
是網面v
的分值。L(v)
是網頁v
的出鏈數量。v
帶給網頁u
的分值就是 PR(v) / L(v)
。PR(u)
就等於全部的入鏈分值之和。在上面的公式中,咱們假設從一個頁面v 到達它的全部的出鏈頁面的機率是相等的。
好比上圖來講,頁面A 有三個出鏈分別連接到了 B、C、D 上。那麼當用戶訪問 A 的時候,就有跳轉到 B、C 或者 D 的可能性,跳轉機率均爲 1/3。
下面來看下如何計算網頁的分值。
咱們能夠用一個表格,來表示上圖中的網頁的連接關係,及每一個頁面到其它頁面的機率:
A | B | C | D | |
---|---|---|---|---|
A | 0 A->A |
1/2 B->A |
1 C->A |
0 D->A |
B | 1/3 A->B |
0 B->B |
0 C->B |
1/2 D->B |
C | 1/3 A->C |
0 B->C |
0 C->C |
1/2 D->C |
D | 1/3 A->D |
1/2 B->D |
0 C->D |
0 D->D |
根據這個表格中的數字,能夠將其轉換成一個矩陣M:
假設 A、B、C、D 四個頁面的初始影響力都是相同的,都爲 1/4,即:
通過第一次分值轉移以後,能夠獲得 W1,以下:
同理能夠獲得W2,W3 一直到 Wn:
那麼何時計算終止呢?
佩奇和布林已經證實,無論網頁的初識值選擇多少(咱們這假設都是1/4),最終都能保證網頁的分值可以收斂到一個真實肯定值。
也就是直到 Wn 再也不變化爲止。
這就是網頁分值的計算過程,仍是比較好理解的。
咱們上文中介紹到的是PageRank 的基本原理,是簡化版本。在實際應用中會出現等級泄露(RankLeak)和等級沉沒(Rank Sink)的問題。
若是一個網頁沒有出鏈,就會吸取其它網頁的分值不釋放,最終會致使其它網頁的分值爲0,這種現象叫作等級泄露。以下圖中的網頁C:
相反,若是一個網頁沒有入鏈,最終會致使該網頁的分值爲0,這種現象叫作等級沉沒。以下圖中的網頁C:
爲了解決上面的問題,拉里·佩奇提出了隨機瀏覽模型,即用戶並不都是依靠網頁連接來訪問網頁,也有可能用其它方式訪問網址,好比輸入網址。
所以,提出了阻尼因子的概念,這個因子表明用戶按照跳轉連接來上網的機率,而 1-d 則表明用戶經過其它方式訪問網頁的機率。
因此,將上文中的公式改進爲:
其中:
如何用代碼來計算網頁的PR 分值呢?(爲了方便查看,我把上圖放在這裏)
咱們能夠看到,該圖實際上就是數據結構中的有向圖,所以咱們能夠經過構建有向圖來構建 PageRank 算法。
NetworkX 是一個Python 工具包,其中集成了經常使用的圖結構和網絡分析算法。
咱們能夠用 NetworkX 來構建上圖中的網絡結構。
首先引入模塊:
import networkx as nx
用 DiGraph 類建立有向圖:
G = nx.DiGraph()
將4 個網頁的連接關係,用數組表示:
edges = [ ("A", "B"), ("A", "C"), ("A", "D"), ("B", "A"), ("B", "D"), ("C", "A"), ("D", "B"), ("D", "C") ]
數組中的元素做爲有向圖的邊,並添加到圖中:
for edge in edges: G.add_edge(edge[0], edge[1])
使用pagerank
方法計算PR 分值:
# alpha 爲阻尼因子 PRs = nx.pagerank(G, alpha=1) print PRs
輸出每一個網頁的PR 值:
{'A': 0.33333396911621094, 'B': 0.22222201029459634, 'C': 0.22222201029459634, 'D': 0.22222201029459634}
最終,咱們計算出了每一個網頁的PR 值。
NetworkX 包中還提供了畫出網絡圖的方法:
import matplotlib.pyplot as plt # 畫網絡圖 nx.draw_networkx(G) plt.show()
以下:
咱們還能夠設置圖的形狀,節點的大小,邊的長度等屬性,具體能夠點擊這裏查看。
更多關於 NetworkX 的內容能夠參考其官方文檔。
PageRank 算法給了咱們一個很重要的啓發,權重在不少時候是一個很是重要的指標。
本篇文章主要介紹了:
(本節完。)
推薦閱讀:
歡迎關注做者公衆號,獲取更多技術乾貨。