原文来源:http://f.dataguru.cn/thread-170008-1-1.html。(此文是我写的,只是想搬个地方)
1,基本思想
如果网页T存在一个指向网页A的连接,则表明T的所有者认为A比较重要,从而把T的一部分重要性得分赋予A。这个重要性得分值为:PR(T)/L(T)
其中PR(T)为T的PageRank值,L(T)为T的出链数
则A的PageRank值为一系列类似于T的页面重要性得分值的累加。
即一个页面的得票数由所有链向它的页面的重要性来决定,到一个页面的超链接相当于对该页投一票。一个页面的PageRank是由所有链向它的页面(链入页面)的重要性经过递归算法得到的。一个有较多链入的页面会有较高的等级,相反如果一个页面没有任何链入页面,那么它没有等级。
2,简单计算
假设一个由只有4个页面组成的集合:A,B,C和D。如果所有页面都链向A,那么A的PR(PageRank)值将是B,C及D的和。
继续假设B也有链接到C,并且D也有链接到包括A的3个页面。一个页面不能投票2次。所以B给每个页面半票。以同样的逻辑,D投出的票只有三分之一算到了A的PageRank上。
换句话说,根据链出总数平分一个页面的PR值。
给每个页面一个初始权值1。第一轮计算完毕,A、B、C、D页面都有新的权值。第二轮,又用每个页面新的权值,又可以进行计算。。。经数学证明了,经过有限次计算后,每个页面的权值会趋于稳定。
由此,google论文中给的page rank公式:
由此可以看出G也是 n*n的方阵。
再看看特征值和特征向量的定义:
也就是说求向量q,就是求方阵G,特征值为 1的特征向量。
引用原文,原文思想很详细,我只列出简单部分
ps:java 有方阵计算的第三方jar包,可以直接求出特征向量。这里为了体验一下,q1=q*G,q2=q1*G。。。。。q(n)=q(n-1)*G的收敛性。故多次相乘,看看效果。
http://math.nist.gov/javanumerics/jama/
3,简单示例
现假设有A,B,C,D,E五个网页,其中
1)A网页有链接指向B,C,D,E
2)B网页有链接指向A,D
3)C网页有链接指向A,D
4)D网页有链接指向C
5)E网页有链接指向A,C
6)java代码
package hadoop;
import Jama.Matrix;
public class CalculatePR {
static double alpha =0.85;
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
double[][] arrayS ={
{0d,1.0d/2,1.0d/2,0,1.0d/2},
{1.0d/4,0,0,0,0},
{1.0d/4,0,0,1,1.0d/4},
{1.0d/4,1.0d/2,1.0d/2,0,0},
{1.0d/4,0,0,0,0}
};
double[][] arrayPR={{1},{1},{1},{1},{1}};
double[][] arrayMinimum = {{0.01d},{0.01d},{0.01d},{0.01d},{0.01d}};
int n = arrayS.length;
Matrix s = new Matrix(arrayS);//源矩阵
Matrix pageRank = new Matrix(arrayPR);//page rank初始值
Matrix minimum = new Matrix(arrayMinimum);//极小值
Matrix u=new Matrix(n,n,1.0d);//单元矩阵
Matrix g=s.times(alpha).plus(u.times((1-alpha)/n));
/*
* 开始迭代计算适合的pageRank值。(也就是求矩阵g,特征值为1 的特征向量pageRank。ps:近似值)
*/
Matrix pageRankPre = pageRank;
pageRank = g.times(pageRank);
int iterator =1;
while(true){
if(compareAbs(minimum,pageRankPre.minus(pageRank))){
break;
}else{
pageRankPre = pageRank;
pageRank = g.times(pageRank);
iterator ++;
}
}
System.out.print("倒数第一次迭代结果:");
pageRankPre.print(2, 2);
System.out.print("最后结果:");
pageRank.print(2, 2);
System.out.print("迭代次数:");
}
/*
* 同阶矩阵,比较对应元素的的绝对值。如果对任意的i,j=1,2,...,n。都有|a(ij)|>|b(ij)|则返回true,否则返回false
*/
public static boolean compareAbs(Matrix a,Matrix b){
boolean flag = true;
for(int i=0;i<a.getRowDimension();i++){
for(int j=0;j<a.getColumnDimension();j++){
if(Math.abs(a.get(i, j))<=Math.abs(b.get(i, j))){
flag = false;break;
}
}
}
return flag;
}
}
alpha 值来源:第一篇引文里提到,一般都用0.85。不固定
我把pageRank值稳定的条件设置为:前后两次结果相差小于arrayMinimum里的设置。即,每一个元素差值<0.01。一共迭代了60次。
运行结果为:
倒数第一次迭代结果:
0.41
0.14
0.56
0.44
0.14
最后结果:
0.41
0.14
0.55
0.44
0.14
迭代次数:60