ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

PangRank算法原理及其Python实现

2019-04-28 20:53:21  阅读:935  来源: 互联网

标签:PR 网页 Python 算法 Vn PangRank amp nodes 节点


文章目录


算法来源

早期搜索引擎采用分类目录的方法,通过人工进行网页分类,并整理出高质量的网页。

后来,随着网页的增多,人工分类已经不现实,此时期搜索引擎采用文本检索的方法,即计算用户检索的关键词与网页内容的相关度,返回所有结果,但关键词并不能反映网页的质量,搜索效果不好。

斯坦福大学的两位研究生佩奇 (Larry Page)和布林 (Sergey Brin) 借鉴了学术论文排序的方法,即论文被引用次数,提出了评价网页质量的方法:

  • 若一个网页被其他网页链接,说明该网页重要性较高;
  • 被高质量网页链接的网页,其重要性相应提高;

算法原理

如下图所示A、B、C和D网页之间的链接图:

该有向图的概率转移矩阵,又称Markov矩阵,如下:
T=(01/2101/3001/21/3001/21/31/200) T = \left( \begin{matrix} 0 & 1/2 & 1 & 0\\ 1/3 & 0 & 0 & 1/2\\ 1/3 & 0 & 0 & 1/2\\ 1/3 & 1/2 & 0 & 0 \end{matrix} \right) T=⎝⎜⎜⎛​01/31/31/3​1/2001/2​1000​01/21/20​⎠⎟⎟⎞​
其中T[i][j]T[i][j]T[i][j]表示第jjj个网页跳转至第iii个网页的概率,转移矩阵的列向量元素和为1。如A网页可跳转至B、C和D网页,跳转概率均为1/3。

初始各网页具有相同PR值,即
V0=(1/41/41/41/4)T V_0=(1/4\quad 1/4 \quad 1/4 \quad 1/4)^T V0​=(1/41/41/41/4)T
持续nnn次转移后,得到网页的最终PR值,即
Vn=TVn1=TnV0 V_n = T\cdot V_{n-1} = T^n \cdot V_0 Vn​=T⋅Vn−1​=Tn⋅V0​

n+n\rightarrow +\inftyn→+∞,若概率转移矩阵TTT满足以下条件,则VnV_nVn​最终收敛:

  • 概率转移矩阵是随机矩阵,即T[i][j]0T[i][j] \geq 0T[i][j]≥0,且iT[i][j]=1\sum_{i}T[i][j]=1∑i​T[i][j]=1;

  • 概率转移矩阵是不可约的,即TTT对应强连通图,图中任何节点都可以到达其他节点,即TTT中不存在全0列(终止节点),且转移矩阵对角线元素不为1(陷阱节点)。终止节点没有到达任何节点的链接,最终得到的PR向量为0向量;陷阱节点只有跳转至自身的链接,最终得到的PR向量中仅陷阱节点的PR值为1,其他节点的PR值为0;

  • 概率转移矩阵是非周期的,即TTT为素矩阵,自身的某次幂为正矩阵;

因此,上述例子得到的最终PR向量为
limn+Vn=limn+TnV0=(3/92/92/92/9)T \lim_{n\rightarrow+\infty}V_n=\lim_{n\rightarrow+\infty}T^n\cdot V_0=(3/9 \quad 2/9 \quad 2/9 \quad 2/9)^T n→+∞lim​Vn​=n→+∞lim​Tn⋅V0​=(3/92/92/92/9)T
结果表明,经过n次跳转后,用户停留在A网页的概率为3/9,高于其他网页。

终止节点和陷阱节点

终止节点

终止节点是指,没有任何出链的节点,如下图中的C节点:

终止节点在概率转移矩阵中,对应列元素全为0,如下:
T=(01/2001/3001/21/3001/21/31/200) T = \left( \begin{matrix} 0 & 1/2 & \color{red}\bm0 & 0\\ 1/3 & 0 & \color{red}\bm0 & 1/2\\ 1/3 & 0 & \color{red}\bm0 & 1/2\\ 1/3 & 1/2 & \color{red}\bm0 & 0 \end{matrix} \right) T=⎝⎜⎜⎛​01/31/31/3​1/2001/2​0000​01/21/20​⎠⎟⎟⎞​
其中,状态转移矩阵中第3列元素全为0,表明第3个节点没有跳转至任何节点的链接,该节点为终止节点。

容易验证,执行第n次转移后,PR向量的元素和不断减小,即
iVn[i]=iVn1[i]Vn1[3] \sum_{i} V_n[i]=\sum_{i} V_{n-1}[i]-V_{n-1}[3] i∑​Vn​[i]=i∑​Vn−1​[i]−Vn−1​[3]
最终得到的PR向量为
limn+Vn=(0000) \lim\limits_{n\rightarrow+\infty}V_n=(0 \quad 0 \quad 0 \quad 0) n→+∞lim​Vn​=(0000)

陷阱节点

陷阱节点是指,只有跳转至自身链接的节点,如下图中的C节点:

陷阱节点在概率转移矩阵中,对应的对角线元素为1,如下:
T=(01/2001/3001/21/3011/21/31/200) T = \left( \begin{matrix} 0 & 1/2 & 0 & 0\\ 1/3 & 0 & 0 & 1/2\\ 1/3 & 0 & \color{red}\bm1 & 1/2\\ 1/3 & 1/2 & 0 & 0 \end{matrix} \right) T=⎝⎜⎜⎛​01/31/31/3​1/2001/2​0010​01/21/20​⎠⎟⎟⎞​
其中,状态转移矩阵对角线的第三个元素为1,表明第3个节点只有跳转至自身的链接,该节点为陷阱节点。

容易验证,执行第n次后,陷阱节点对应的PR值不断增大,即
Vn[3]=Vn1[3]+j3T[3][j]Vn1[j] V_n[3]=V_{n-1}[3]+\sum_{j\neq 3} T[3][j]\cdot V_{n-1}[j] Vn​[3]=Vn−1​[3]+j̸​=3∑​T[3][j]⋅Vn−1​[j]
最终得到PR向量为
limn+Vn=(0010) \lim\limits_{n\rightarrow+\infty}V_n=(0 \quad 0 \quad 1 \quad 0) n→+∞lim​Vn​=(0010)

解决思路

当用户遇到终止节点网页或陷阱节点网页,用户可通过在浏览器重新输入新的地址,以逃离这个网页。因此,对转移公式进行如下修正:
Vn=αTVn1+(1α)V0 V_n = \alpha T\cdot V_{n-1} + (1-\alpha)V_0 Vn​=αT⋅Vn−1​+(1−α)V0​
可见,用户以1α1-\alpha1−α的概率通过地址栏跳转至其它网页,α\alphaα值的大小与算法的收敛速度成反比,一般选取为0.85。

算法不足

第一,未区分站内导航链接。与站内导航链接相比,外链更能体现PR值的传递关系;

第二,未过滤广告链接和功能链接。如没有实际价值的广告链接,以及“分享到微博”等功能链接;

第三,对新网页不友好。新网页的入链较少,即使其内容质量很高,要获得高PR值仍需要很长时间;

算法实现

# encoding: utf-8

import numpy as np
from numpy.linalg import norm


def graph2trans_mat(graph):
    """
    根据图生成概率转移矩阵

    :param graph: list, [['A', 'B'], ...]表示节点A可向节点B转移
    :return: numpy.array, 概率转移矩阵, 元素[i, j]表示节点j可向节点i的转移概率
    """
    # 统计节点数
    nodes_set = set()
    for edge in graph:
        if edge[0] not in nodes_set:
            nodes_set.add(edge[0])
        if edge[1] not in nodes_set:
            nodes_set.add(edge[1])

    # 定义节点字典, key为节点名称, value为节点编号
    nodes_num = len(nodes_set)
    nodes_dict = dict(zip(sorted(nodes_set), range(nodes_num)))

    # 生成概率转移矩阵trans_mat, [i, j]为1表示节点j可向节点i转移
    trans_mat = np.zeros((nodes_num, nodes_num), dtype=np.float64)
    for j, i in graph:
        trans_mat[nodes_dict[i], nodes_dict[j]] = 1.

    # 列向量单位化
    trans_mat /= trans_mat.sum(axis=0)
    return trans_mat


def page_rank(trans_mat, alpha=0.85, max_iter=100, epsilon=1e-5):
    """
    迭代计算节点的PR值

    :param trans_mat: 概率转移矩阵,A[i][j]表示第j个节点转移到第i个节点的概率
    :param alpha: 跳转至初始状态的因子
    :param max_iter: 最大迭代次数
    :param epsilon: 向量PRn与向量PRn_1之差的1范数小于该值时, 终止迭代
    :return: list, 各节点的PR值
    """
    # 节点数目
    nodes_num = trans_mat.shape[0]
    # 初始PR向量
    PR0 = np.full((nodes_num, 1), 1. / nodes_num, dtype=np.float64)
    PRn_1 = np.copy(PR0)

    for i in range(max_iter):
        PRn = alpha * np.dot(trans_mat, PRn_1) + (1 - alpha) * PR0
        # PR向量改变较小时,终止迭代
        if norm(PRn - PRn_1, ord=1) < epsilon:
            break
        else:
            PRn_1 = PRn

    return PRn_1


if __name__ == '__main__':
    graph = [
        ['A', 'B'],
        ['A', 'C'],
        ['A', 'D'],
        ['B', 'A'],
        ['B', 'D'],
        ['C', 'A'],
        ['D', 'B'],
        ['D', 'C']
    ]
    print(page_rank(trans_mat=graph2trans_mat(graph))[:, 0])
    # [0.32455881 0.22514706 0.22514706 0.22514706]

标签:PR,网页,Python,算法,Vn,PangRank,amp,nodes,节点
来源: https://blog.csdn.net/sinat_34072381/article/details/89645488

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有