在個人一篇博客PageRank中,在5.1 算法實現中簡單實現部分本來是有一個錯誤的。這個錯誤也體現出我當時對PageRank算法有理解上的誤差。html
這是個什麼樣的錯誤呢?是這樣的:node
簡單實現中計算每一個網頁的PR值時使用的是最原始的方法,即下面的這個公式:python
\[ PR(p_{i}) = \alpha \sum_{p_{j} \in M_{p_{i}}} \frac{PR(p_{j})}{L(p_{j})} + \frac{(1 - \alpha)}{N} \]算法
這個公式要求全部網頁的PR值之和爲1。而我本來的代碼中給每一個網頁賦予的初始PR值的代碼爲:spa
page_rank = dict.fromkeys(nodes, 1.0) # 給每一個節點賦予初始的PR值
也就是說,我給出的初始PR值之和爲5(例子中共有5個網頁)。code
犯這個錯誤的緣由是我理解錯了「與\(P_0\)的選取無關」這句話。正確的理解應該是:「與\(P_0\)的初始機率分佈無關」。htm
然而,我理解錯了也還有另外一個緣由,那就是我原來的程序中無論給出的初始PR值是多少,最終的PR值都是同樣的。現分析以下:blog
按照我本來的程序邏輯,我使用的公式應該是這樣的,其中\(G\)爲全部網頁:get
\[ PR(p_{i}) = \alpha \sum_{p_{j} \in M_{p_{i}}} \frac{PR(p_{j})}{L(p_{j})} + \frac{(1 - \alpha)}{N} \sum_{p_k \in G} PR(p_k) \]博客
而我卻使用了最原始的公式,形成了:
\[ 每輪迭代,每一個頁面的PR值都減小了 \frac{(1 - \alpha)}{N} * (上輪PR值總和 - 1) \\ \Rightarrow 每輪迭代,PR值總和都減小了 (1 - \alpha) * (上輪PR值總和 - 1) \]
現假設初始PR值總和爲 \(A_0\),則有:
\[ 最開始,PR值總和爲:A_0 \\ 第一輪迭代以後,PR值總和爲:A_1 = A_0 - (1 - \alpha) (A_0 - 1) = \alpha A_0 + 1 - \alpha \\ 以此類推,則有 \\ A_{n} = \alpha A_{n-1} + 1 - \alpha \\ \Rightarrow A_{n} - 1 = \alpha (A_{n-1} - 1) \\ \Rightarrow A_{n} - 1 = \alpha^{n} (A_{0} - 1) \\ \Rightarrow A_{n} = \alpha^{n} (A_{0} - 1) + 1\\ \because \alpha < 1 \\ \therefore \lim_{n \rightarrow \infty} A_n = 1 \]
即無論初始PR值爲多少,最終其和都將趨於1(若初始值之和小於1,用類似的方法能夠證實)。也就是說,最終結果是同樣的(由於最終趨於1以後就至關於以「PR值總和爲1」的狀況又開始了計算)。這一點在代碼中也有體現:當PR值設置得很大的時候,須要迭代的次數也相應增大。
總結:應該使用最上面的公式,同時初始PR值總和應該設置爲1。