PageRank算法及幂法实现

PageRank算法

定义

PageRank算法是一种对网页进行重要度排名的算法,其有两个指标:
①网页被外链的次数
②外链该网页的其它网页的质量

关于算法的具体引出与定义,在《统计学习方法》这一本书中介绍的比较详细,我对PageRank算法的理解是这样的:
假设该有向图表示网页之间的链接关系,顶点A、B、C、D、E表示网页,边表示网页之间的外链关系。假设网页浏览者真正该在浏览A网页,A网页包含三个外链,分别外链到B、C、D网页,那么他继续浏览B、C、D网页的概率均为1/3。同样的,如果用户正在浏览C网页,C网页包含两个外链,分别外链到B、D网页,那么他继续浏览B、D网页的概率均为1/2。我们可以这样认为,对于一个网页,如果它被许多网页外链,这可以说明他的重要性程度比较高,同时用户在浏览时跳转到该网页的概率也就越大。这样的概率可以通过不断的模拟随机游走模型跳转来进行,在实际实现中是一个迭代的过程。但是对于本身没有任何外链的网页(例如B网页),则不能继续按照外链关系迭代下去了,这时的跳转则是在这几个网页中等概率跳转。
有向图

计算

我们以下面这个公式进行迭代计算:
R t + 1 = d M R t + ( 1 − d ) ∗ l / n Rt+1=dMRt+(1-d)*l/n Rt+1=dMRt+(1d)l/n
其中Rt可理解为浏览者在t时刻处于每一个网页的概率,初始的Rt可以为任意值。表示为一个列向量,d表示网页有外链接的概率,称为阻尼因子,因此根据本网页的外链情况判断是根据链接跳转还是上面说的等概率跳转。M为转移矩阵,Mij表示从j网页跳转到i网页的概率,这个概率是均分的,例如A有三个出度,那么从A跳转到这些网页的概率均为1/3。l为一个所有分量为1的列向量,n为参与排名的网页数量。

PageRank的计算方法共有三种:迭代法、幂法及代数法
迭代法直接按照上述公式进行迭代计算直到Rt收敛,代数法我还不能理解,下面来详细介绍幂法。

幂法(power method)是一个常用的页面秩计算方法,通过近似计算矩阵的主特征值和主特征向量获得有向图的一般PageRank。
根据Perron-Frobenius定理 ,一般PageRank的向量R是矩阵A的主特征向量,主特征值是1。因此我们可以使用幂法近似计算平均PageRank。但是在实际应用中,经常会遇到有两个或多个节点被访问过的情况,这时就无法用通常方法计算主特征矢量了,必须采用新算法才能得到正确结果。幂法计算主特征向量需要事先计算转移矩阵A,A由公式
A = d M + ( 1 − d ) ∗ E / n A=dM+(1-d)*E/n A=dM+(1d)E/n
确定。
计算转移矩阵A之后,我们可以选择一个随机的初始向量x0开始迭代同时规范结果向量,迭代公式为
y t + 1 = A x t yt+1=Axt yt+1=Axt
幂法的计算步骤就是按照上述公式不断迭代直到||xt+1-xt|| < η时停止,其中η为算法精度,令R=xt,R为最终PageRank向量值。
下面是Python实现的源码:

from ast import Num
from tkinter import E, PROJECTING
from unicodedata import name
import numpy as np

def vec_norm(vec):              #向量规范化
    n = vec.shape[0]
    #求向量模
    vec_list = vec.tolist()
    sum = 0
    for item in vec_list:
        sum = sum + item[0] ** 2
    sum = sum ** 0.5
    #规范化
    for i in range(0, n):
        vec[i] = (vec_list[i])[0] / sum


def page_rank_(d, x0, M, precision = 0.0005):
    n = M.shape[0]              #矩阵元素个数
    #构造初始转移矩阵
    E = np.mat(np.ones((n, n)), float)
    A = d * M + ((1-d)/n) * E
    #print(A)
    #迭代
    pre_now = 5.000
    y0 = x0
    while pre_now > precision:
        #计算新的x0值
        y0 = np.dot(A, y0)
        vec_norm(y0)       #规范化
        #print(y0)
        pre_list = []
        for i in range(0, n):
            pre = abs((y0[i])[0] - (x0[i])[0])
            pre_list.append(pre)
        x0 = y0
        pre_now = max(pre_list)
    #vec_norm(y0)
    return y0

page_rank_函数中的基本转移矩阵M根据实际情况计算给出,例如对于下面的有向图
在这里插入图片描述
基本转移矩阵M与初始向量x0为
在这里插入图片描述
进行PageRank排名结果为
在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值