1.1 、PageRank(网页级别)的概念
互联网发展早期的搜索引擎,对web页面的排序,是根据搜索的词组(短语)在页面中的出现次数(occurence ),并用页面长度和html标签的重要性提示等进行权重修订。链接名气(link popularity)技术通过其它文档链接到当前页面(inbound links)的链接数量来决定当前页的重要性,这样可以有效地抵制被人为加工的页面欺骗搜索引擎的手法。
PageRank计算页面的重要性,对每个链入(inbound)赋以不同的权值,链接提供页面的越重要则此链接入越高。当前页的重要性,是由其它页面的重要性决定的。
1.2、PageRank算法1
PR(A) = (1-d) + d (PR(T1)/C(T1) + ... + PR(Tn)/C(Tn))
其中:
PR(A):页面A的网页级别,
PR(Ti):页面Ti的网页级别,页面Ti链向页面A,
C(Ti):页面Ti链出的链接数量,
d:阻尼系数,取值在0-1之间.
由此可见,
1)这个算法不以站点排序,页面网页级别由一个个独立的页面决定;
2)页面的网页级别由链向它的页面的网页级别决定,但每个链入页面的贡献的值是不同的。如果Ti页面中链出越多,它对当前页面A的贡献就越小。A的链入页面越多,其网页级别也越高;
3)阻尼系数的使用,减少了其它页面对当前页面A的排序贡献。
在实际应用中可采用幂法来计算 P a g e R a n k 。 P a g e R a n k 公式可以转换为求解矩阵A的极限的问题 , 其中矩阵为 A = d P + ( 1 一 d ) * e。eT / m 。 d为阻尼系数,P 为概率转移矩阵, e 为 n 维的全 1 行, m为全部网页个数。
备注:阻尼系数,谷歌取值为0.85,本例为计算方便,取值为0.5
P 概率转移举证
1.6、迭代计算pagerank
Google采用一种近似的迭代的方法计算网页的网页级别的,也就是先给每个网页一个初始值,然后利用上面的公式,循环进行有限次运算得到近似的网页级别。根据Lawrence Page 和 Sergey Brin公开发表的文章,他们实际需要进行100次迭代才能得到整个互联网的满意的网页级别值,这儿的例子只用了10多次就可以了。在迭代的过程中,每个网页的网页级别的和是收敛于整个网络的页面数的。所以,每个页面的平均网页级别是1,实际上的值在(1-d)和(dN+(1-d))之间。
迭代次数 |
PR(A) |
PR(B) |
PR(C) |
0 |
1 |
1 |
1 |
1 |
1 |
0.75 |
1.125 |
2 |
1.0625 |
0.765625 |
1.1484375 |
3 |
1.07421875 |
0.76855469 |
1.15283203 |
4 |
1.07641602 |
0.76910400 |
1.15365601 |
5 |
1.07682800 |
0.76920700 |
1.15381050 |
6 |
1.07690525 |
0.76922631 |
1.15383947 |
7 |
1.07691973 |
0.76922993 |
1.15384490 |
8 |
1.07692245 |
0.76923061 |
1.15384592 |
9 |
1.07692296 |
0.76923074 |
1.15384611 |
10 |
1.07692305 |
0.76923076 |
1.15384615 |
11 |
1.07692307 |
0.76923077 |
1.15384615 |
12 |
1.07692308 |
0.76923077 |
1.15384615 |
迭代计算机的步骤可以表述为:
step1 x=[1,1,1]T // 其中x的维度和网页个数一致
step2 B=P*x
step3
if ||x-B||
return B
else
x=B
step2
计算过程python代码参考:
# -*- coding:gb2312 -*-
'''
Created on 2011-10-22
@author: chenjinandy
'''
# 矩阵 0 1 1
# 0 0 1
# 1 0 0
#代表 A B C 为 A->B A->C B->C C->A
# 计算其pagerank 值
A=[[0,1,1],[0,0,1],[1,0,0]]
def getSum(v):
sum=0
vtemp=[]
for vi in v:
sum+=vi
for vi in v:
vi=(float(vi*1.0)/sum)
vtemp.append(vi)
return vtemp
def getA(A):
Atemp=[]
for v in A:
Atemp.append(getSum(v))
return Atemp
print getA(A) # 输出1
def Nizhuan(A):
Atemp=[]
for j in range(len(A[0])):
v=[]
for i in range(len(A)):
v.append(A[i][j])
Atemp.append(v)
return Atemp
p=Nizhuan(getA(A))
def dA(A,d):
Atemp=[]
for i in range(len(A)):
vtemp=[]
v=A[i]
for j in range(len(v)):
vit=v[j]*d
vtemp.append(vit)
Atemp.append(vtemp)
return Atemp
def add(A,B):
temp=[]
for i in range(len(A)):
v=[]
for j in range(len(A[0])):
vi=A[i][j]+B[i][j]
v.append(vi)
temp.append(v)
return temp
# 求初始的B
#阻尼系数,此处取0.85
d=0.5
e=[[1.0/3,1.0/3,1.0/3],[1.0/3,1.0/3,1.0/3],[1.0/3,1.0/3,1.0/3]]
#B=d*p+(1-d)*e
B=add(dA(p,d),dA(e,(1-d)))
# 接下来进行迭代计算
def cheng(A,B):
temp=[]
for r in range(len(A)):
v=[]
for c in range(len(B[0])):
#print len(B[0])
vt=0.0
for j in range(len(A[0])):
# print A[r][j]
#print B[j][c]
vt+=A[r][j]*B[j][c]
v.append(vt)
temp.append(v)
return temp
x=[[1],[1],[1]]
def getCur(x,B):
i=0
while i<10:
i+=1
r=cheng(B,x)
x=r
print r
print getCur(x,B)