pagerank演算法原理介紹
pagerank演算法是google的網頁排序演算法,在《the top ten algorithms in data mining》一書中第6章有介紹。大致原理是使用者搜尋出的多個網頁需要按照一定的重要程度(即後面講的權重)排序,每個網頁的權重由所有鏈結到它的其他網頁的權重的加權和,加權係數為每個網頁鏈出的網頁數的倒數,也就是說每個網頁的權重會平均分配到其鏈向的所有網頁。
例如a鏈結到b和c,b鏈結到c,c鏈結到a,p(x)表示x的權重,如下圖所示
則每個節點的權重關係為:
p(a) = p(c)
p(b) = p(a)/2
p(c) = p(a)/2 + p(b)
一般地,可以寫成個線性方程組形式:
p = ap
如此通過迭代即可求出最終各個網頁的權重值。
但是,當存在某些特殊情況時,如某個網頁的鏈入或鏈出數為0,則迭代不會收斂。因此在上述演算法中增加了個阻尼係數d,d表示使用者會繼續點選下一網頁的概率,同時使用者在1-d的概率下會隨機訪問到任意網頁,那麼上面的公式會修正為:
p = (1-d)/n * ones(n,1) + d*ap
其中n為所有網頁數,ones(n,1)表示n行1列的全1矩陣。通過上述公式可以迭代計算出最終各網頁權重。
詳細介紹可以參考wiki百科。
演算法實現
首先宣告這個cpagerank類:
1 typedef unsigned char下面就是具體各個函式的實現了。byte;
2class
cpagerank
3;
首先建構函式主要是初始化一些迭代相關變數,分配空間等,這裡把生成節點指向圖的工作也放在這裡,支援直接隨機生成和讀取二進位制檔案兩種方式。
1 cpagerank::cpagerank(int nwebnum, bool析構函式自然就是釋放記憶體了:bloadfromfile)
2
1 cpagerank::~cpagerank()下面就是隨機生成或讀取檔案產生節點指向關係,如果隨機生成的話,會自動儲存當前生成的圖,便於遇到問題時可復現除錯:2
1既然已經產生了各個節點的關係了,那pagerank的核心思想就是根據關係,生成出上面的轉移矩陣p:void cpagerank::initgraph(bool
bloadfromfile)213
}1415//
建立隨機的節點指向圖
16int
i, j;
17srand((unsigned)time(null));
18for(i = 0; i < m_nnum; i++)
1925
//自己不指向自己
26 m_pu8relation[i * m_nnum + i] = 0;27
}2829 pf = fopen("
map.dat
", "wb"
);30
if(pf)
31
35 }
1接下來就需要求解出各個節點的權重,process函式裡先呼叫generatep生成出p矩陣,然後採用迭代法求解,當時為了測試收斂速度,直接返回了迭代次數:void
cpagerank::generatep()217
}1819//
生成轉移矩陣,每個節點的權重平均流出
20 pu8relation =m_pu8relation;
21 pf32p =m_pf32p;
22for(i = 0; i < m_nnum; i++)
2330
else
3134 pu8relation++;
35 pf32p++;36}
37}3839
//考慮阻尼係數,修正轉移矩陣
40 pf32p =m_pf32p;
41for(i = 0; i < m_nnum; i++)
4248
}49 }
1最後的結果已經存在了m_pf32outweight中了,下面函式直接傳出結果:intcpagerank::process()214
15//
生成p矩陣
16generatep();
1718
//迭代
19for(t = 0; t < m_nmaxitertime; t++)
2031
32float f32err = fabs(pf32new[i] -pf32org[i]);
33if(f32err >f32maxerr)
3437}38
39//
迭代誤差足夠小,停止
40if(f32maxerr
4144
45//
交換2次迭代結果
46float *pf32temp =pf32org;
47 pf32org =pf32new;
48 pf32new =pf32temp;49}
5051
//迭代結果存在pf32new中
52 m_pf32outweight =pf32new;
53return
t;54 }
1這樣,整個演算法就算完成了,考慮到篇幅,貼上來的**把opencv顯示相關的**去掉了,完整**見float *cpagerank::getweight()
2
下面是結果圖,即便節點數較多時,演算法收斂也比較快。
分析總結
對於上面這個公式,看到網上有人假定p的總能量是1,則可以改寫為p=bp的形式來進行迭代,這種方法也實現了一下,問題仍然是當存在網頁鏈入或者鏈出數為0時,每次迭代後不能保證能量守恆,那麼下一次就會導致p=bp這個公式不成立,從而出現迭代不收斂;一種有效的做法是每次迭代後就將p進行能量規一化,這樣是可以保證結果的收斂性的。但是這種做法與原始演算法的結果會有一點細微的出入。因此建議按照原始的公式進行迭代求解。
PageRank演算法原理剖析及Spark實現
pagerank對網頁排名的演算法,曾是google發家致富的法寶。pagerank演算法計算每乙個網頁的pagerank值,然後根據這個值的大小對網頁的重要性進行排序 首先,將web做如下抽象 1 將每個網頁抽象成乙個節點 2 如果乙個頁面a有鏈結直接鏈向b,則存在一條有向邊從a到b 多個相同鏈結...
PageRank演算法實現
在網際網路上,如果乙個網頁被很多其他網頁所鏈結,說明它受到普遍的承認和信賴,那麼它的排名就高。這就是pagerank的核心思想。引用來自 數學之美 的簡單例子 網頁y的排名應該來自於所有指向這個網頁的其他網頁的權重之和,在上圖中y的網頁排名就是0.001 0.01 0.02 0.05 0.081。如...
PageRank演算法的python實現
演算法原理不在贅述,請參考 將 儲存為.py格式,預設使用的資料是 檔案所在目錄下data目錄下的 pgr data.txt 檔案分別作為源資料輸入。以上引數可以在源 中修改,也可以使用命令列引數傳入,參考以下啟動方式 python pagerank.py pgr data.txt 命令中後引數為輸...