Webページが下図のような \(n = 6 \) ページからなるリンク構造を持つものとする.例えばページ A からはページ B, D, E へリンクが貼られており,ページ A にはページ B, D, F からリンクが貼られている.
PageRank は \( n \times n\) の行列 \(H\) の固有値を用いて導出できる.ページ \(i\) から出るリンクの個数を \(P_i\) とする.ページ \(i\) からページ \(j\) にリンクがある場合には,行列 \(H\) の \(i\) 行 \(j\) 列を \(1 / P_i\) とし,それ以外を \(0\) とする.行列 \(H\) を転置した行列に対して,絶対値が最大となる固有値に対応する固有ベクトルを選ぶ.選択された固有ベクトルの各要素を要素の和で割ることにより PageRank が導出される.
実際に Python で PageRank を求めてみよう.まず,リンク構造から行列 \(H\) を作成する.たとえば,ページAからは3つのページ (B, D, E)にリンクが貼られているので,行列の1行目(インデックス0)は2, 4, 5列目(インデックス1,3,4)の要素が1/3となる.
行列の作成import numpy as np # プログラムの先頭でモジュールを読み込む
H = np.array([
[0, 1/3, 0, 1/3, 1/3, 0],
[1/3, 0, 1/3, 0, 0, 1/3],
[0, 1, 0, 0, 0, 0],
[1/2, 0, 0, 0, 1/2, 0],
[0, 0, 0, 0, 0, 1],
[1/3, 1/3, 0, 0, 1/3, 0]
])
print(H)
[[0. 0.33333333 0. 0.33333333 0.33333333 0. ] [0.33333333 0. 0.33333333 0. 0. 0.33333333] [0. 1. 0. 0. 0. 0. ] [0.5 0. 0. 0. 0.5 0. ] [0. 0. 0. 0. 0. 1. ] [0.33333333 0.33333333 0. 0. 0.33333333 0. ]]
次に行列 \(H\) を転置する.
行列の転置HT = np.transpose(H)
print(HT)
[[0. 0.33333333 0. 0.5 0. 0.33333333] [0.33333333 0. 1. 0. 0. 0.33333333] [0. 0.33333333 0. 0. 0. 0. ] [0.33333333 0. 0. 0. 0. 0. ] [0.33333333 0. 0. 0.5 0. 0.33333333] [0. 0.33333333 0. 0. 1. 0. ]]
転置した行列の固有値と固有ベクトルを求める.
固有値と固有ベクトルの計算w, v = np.linalg.eig(HT)
固有値を表示すると,絶対値が最大になる固有値は1番目(インデックス0)の 1.0 であることがわかる.
固有値の表示print(w)
[ 1.00000000e+00 4.34258546e-01 -2.33852425e-16 -9.76310729e-02 -7.67591879e-01 -5.69035594e-01]
全ての固有ベクトルを表示してみる.
固有ベクトルを表示print(v)
[[ 4.34650760e-01 4.32098738e-18 2.79665526e-16 1.68895809e-01 7.22434883e-16 -6.17490156e-01] [ 5.07092553e-01 -5.60913760e-01 1.75476408e-16 8.99013349e-02 6.48590681e-01 -1.00875321e-01] [ 1.69030851e-01 -4.30552847e-01 -2.67261242e-01 -3.06942357e-01 -2.81656046e-01 5.90913950e-02] [ 1.44883587e-01 4.53703675e-17 -5.34522484e-01 -5.76646362e-01 2.49568414e-16 3.61717358e-01] [ 4.10503495e-01 4.30552847e-01 -2.19345510e-16 -1.00808196e-01 2.81656046e-01 -3.14864192e-01] [ 5.79534346e-01 5.60913760e-01 8.01783726e-01 7.25599770e-01 -6.48590681e-01 6.12420915e-01]]
このうち,絶対値が最大となる固有値 (1.0) に対応する固有ベクトルだけを表示する.
固有ベクトルを選ぶvec = v[:, 0]
print(vec)
[0.43465076 0.50709255 0.16903085 0.14488359 0.4105035 0.57953435]
固有ベクトルの要素の和が1になるように,各要素を要素の和で割ることにより,PageRank が計算される.
PageRankの表示print(vec / vec.sum())
[0.19354839 0.22580645 0.07526882 0.06451613 0.1827957 0.25806452]