Upload
mfumi
View
12.363
Download
2
Embed Size (px)
DESCRIPTION
About Mining of Massive Datasets Chapter 5.1
Citation preview
MMDs Chapter 5 Link Analysis 5.1 PageRank
5.1 PageRank• 2000年代、googleのような検索エンジンで我々の生活は大きく変化した
• googleは最も早い検索エンジンではなかったが最初にスパマーに打ち勝った検索エンジン
• googleのイノベーションは PageRank によってもたらされた
5.1.1 Early Search Engines and Term Spam
• google以前の検索エンジンの多くは、webをクローリングしてページごとに単語の転置インデックスを作成
• クエリ検索はこの転置インデックスから求める
• スパマーはページに単語をたくさん書けば良かった
スパムに打ち勝つためにgoogleが導入した方法
1. PageRankの考案 (詳細は次スライド)。PageRankはランダムサーファーをシミュレートすることで計算する
2. ページの内容はそのページに出現する単語だけでなく、そのページへのリンクに使われた語からも判断スパマーは評価を上げたいサイトへリンクをある偽サイトを作ることは可能だが、結局それらのページには外部からリンクが張られないため、ランダムサーファーをシミュレートすることで計算するPageRankは偽サイトに対しては低くなる
なぜランダムサーファーのシミュレートがページ評価につながるか?
• ユーザは基本的に良いページにリンクを張る
• ランダムサーファーの挙動はどのページにユーザが訪れやすいかを示すものになる。
5.1.2 Definition of PageRank
• PageRank は ランダムサーファーが最終的にどのページにたどり着くかの確率分布
• 例, webは有向グラフで表すMは推移行列, Mij は j から i へ移動する確率、各列の総和は1
PageRankの計算• ランダムサーファーの初期位置は全てのページに等しい確率で分布するとする。ベクトルで表現するとv_0 = ^t(1/n,1/n,…,1/n) (^tはtranspose)
• 1回移動したあとの確率分布v_1は定義より Mv_0, 2回移動した後は Mv_1 = M^2 v_0, n 回なら M^n v_0
• 以下の2つの条件が成り立つとき、 v = Mv となるようなvが存在することが知られている
1. グラフは強連結、つまり任意の2点に有向路が存在
2. 外へのリンクが一つもないノード(dead end)が存在しない
PageRankの計算(cond)• 定義より、 v_n = M v_n-1 = M^2 v_n-2 = … = M^n v_0
• つまり、 v = Mv となるようなベクトルは M^n のn無限大の極限を計算すれば良い
• 別の見方をするとvはMの固有値1に対する固有ベクトルで、その要素の総和が1のもの
• 実は推移行列Mの最大固有値は1
• 一般に行列の最大固有値とその固有ベクトルはベキ乗法で求められる
PageRankの計算(cond)• まとめ:PageRankを計算するには適当な初期ベクトル(ただし要素の和は1)にMを繰り返しかけることを収束するまで繰り返せば良い もちろん固有ベクトルを直接求めてもOK(ただしベキ乗法の方が楽)
• 実際には50~75回ぐらいやれば十分
• 先ほどの例だと
5.1.3 Structure of the Web
• Webが強連結であれば先ほどの定義で良いが、実際は違う
PageRank計算のために考えなけらばならないこと
• Pagerank計算のためには以下の二つに対処しなければならない
1. dead end, 頂点は外へのリンクを持たない
2. spider trap, 頂点は外へのリンクを持つものの、あるグループより外へのリンクがない
• 2つとも “taxation” で解決できる
5.1.4 Avoiding Dead Ends• dead end があるとPageRankは0になってしまう
dead endの対応方法
1. dead endなノードを取り除く。そうすると別のdead end が生じることがあるので再帰的に処理する。グラフは最終的には強連結になる。
2. “taxation” メソッドを使う(後のスライド)
dead endを取り除いてPageRankを計算する
• 以下のようにすればdead endなので取り除いたノードに大してもPageRankを計算することができる
• dead endなノードを除いたグラフでPageRankを計算
• グラフにdead end なノードvを追加する。このときvのページランクは、 Σ(PR(u)/L(u))で定義する。ここでuはvへのリンクを持つノード、PR(u)がuのページランク、L(u)がuの総リンク数
• こうして計算したPageRankは総和が1を超えるので確率分布ではなくなるが、ページの重要度を計るのに十分有用な判断基準になる。
dead endを取り除いてPageRankを計算する: 例
• ノードCのPageRankを考える CはAとDからリンクされている AのPageRankは2/9で、Aの総リンク数は3 DのPageRankは3/9で、Dの総リンク数は2, よって CのPageRank = 2/9 * 1/3 + 3/9 * 1/2 = 13/54
• EのPageRankはCからしかリンクが張られていないのでCと同じ13/54
5.1.4 Spider Traps and Taxation
• Spider Trapとは? CがSpider TrapなのでそのPageRankは1
dead endやspider trapに対抗するためのPageRankの修正• 以下のようにPageRankを修正するここで βは ある定数(実際は0.8~0.9) eは全ての要素が1のベクトル
• この式は(1-β)の確率でランダムサーファーは任意のwebページにジャンプすることを示している
• このように式を変形してもベクトルの要素の総和が1であるという条件に変化はないことに注意
• ノードがdead endのときは そのノードに対応する列の推移確率を全て1/N とする (常にジャンプすることを意味する)
taxationを考慮したPageRank計算の例
• β=0.8、(1-β)/4 = 1/20
※vの総和は1であるから以下の式でもよい
5.1.6 Using PageRank in a Search Engine
• 実際の検索エンジンでPageRankはどう使われるか?
• googleは250を超える要素でランク付けをおこなっている。PageRankはそのうちの一つ
• 一般に、まず検索エンジンはクエリの単語を含むページをとってくる
• そうしてとってきた候補ページの順序を決定するための重要な判断基準の一つがPageRank
補足: PageRankの定義• このスライドでは、PageRankは推移行列をある初期ベクトル(総和1)に無限回かけた物として定義した
• dead end なノードを取り除いてPageRankを計算する方法で使用した定義でもPageRankを定義できる(オリジナルはこれで定義されている)。つまり、あるノードAのPageRank PR(A)は PR(A) = (1-β)/N + βΣ(PR(u)/L(u))ここでuはAへリンクを持つノード、L(u)はuの総リンク数。またPRの総和は1という条件がある。
補足: PageRankの定義(cond)
• 例一方で、先ほどのPageRankの定義では、(β=1とした)
補足2:RによるPageRankの実装#反復法 #M : 推移確率行列 #d: damping factor #eps epsilon pageRank <- function(M,d,eps){ N <- nrow(M) v <- (numeric(N) + 1) / N # 初期分布 v2 <- (numeric(N)+10000) M2 = d * M + (1-d)/N * matrix(1,N,N) cnt <- 1 ! while(norm(as.matrix(v-v2,"F")) > eps){ v2 <- v v <- M2 %*% v cnt <- cnt + 1 } ! cat("iteration count: ",cnt,"\n"); v } !
# 固有ベクトルからPageRankを計算 pageRank2 <- function(M,d){ N <- nrow(M) M2 = d * M + (1-d)/N * matrix(1,N,N) eig <- eigen(M2) v <- eig$vectors[,1] if(v[1] < 0){ v <- v * (-1) } v <- v / sum(v) v }
# 逆行列による計算 # v = dMv + (1-d)/N1 より v = (I-dM)^-1((1-d)/N1)) pageRank3 <- function(M,d){ N <- nrow(M) M2 = diag(N) - d*M inv_M2 = solve(M2) v <- inv_M2%*%((1-d)/N*matrix(1,N,1)) v }
補足2:RによるPageRankの実装(cond)
# テストコード (1000x1000 の適当な確率推移行列のPageRankを計算) N <- 1000 M <- matrix(0,N,N); for(i in 1:N){ x <- as.integer(runif(1)*(N/10)) if(x != 0){ for(j in 1:x){ k <- as.integer(runif(1)*(N-1))+1 while(M[k,i] != 0){ k <- as.integer(runif(1)*(N-1))+1 } M[k,i] = 1/x } }else{ for(j in 1:N){ M[j,i] = 1/N } } } print("Iteration Method") system.time(pageRank(M,0.8,1e-7)) print("EigenVector") system.time(pageRank2(M,0.8)) print("Inverse Matrix") system.time(pageRank3(M,0.8))
# 結果 #[1] "Iteration Method" #iteration count: 10 # ユーザ システム 経過 # 0.147 0.010 0.161 #[1] "EigenVector" # ユーザ システム 経過 # 33.059 0.111 34.255 #[1] "Inverse Matrix" # ユーザ システム 経過 # 5.905 0.019 6.084