pagerank简单实现

PageRank算法的实现

目标一 迭代法实现

题目

迭代法实现大规模PageRank,网页数量不低于10000

思路

首先创建一个txt文件,里面储存各个点之间的关系,然后通过python语言读取,将其转化为矩阵,并通过公式将其转化为相应矩阵,然后进行迭代,直至误差小于 0.00000001结束。

原理

20180705175428704

20180705175524455

源代码

import numpy as np

if __name__ == '__main__':

    file = open('input2.txt', 'r')
    edges_in = []
    edges_out = []
    while True:
        lines = file.readline().strip('\n')
        if not lines:
            break
        else:
            this_line = lines.split(' ')
            edges_out.append(this_line[0])
            edges_in.append(this_line[1])
    # 根据边获取节点的集合
    nodes = []
    for edge in edges_out:
        if edge not in nodes:
            nodes.append(edge)
    for edge in edges_in:
        if edge not in nodes:
            nodes.append(edge)
    length = len(nodes)  # 数据的个数
    i = 0
    node_to_num = {}
    for node in nodes:
        node_to_num[node] = i
        i += 1
    for i in range(len(edges_in)):
        edges_in[i] = node_to_num[edges_in[i]]
        edges_out[i] = node_to_num[edges_out[i]]
    # 生成初步的S矩阵
    S = np.zeros([length, length])
    for i in range(len(edges_in)):
        S[edges_in[i], edges_out[i]] = 1
    # 计算比例:即一个网页对其他网页的PageRank值的贡献,即进行列的归一化处理
    for j in range(length):
        sum_of_col = sum(S[:, j])
        for i in range(length):
            if sum_of_col != 0:
                S[i, j] /= sum_of_col
            else:
                S[i, j]  = 1/length #  判断是零的情况
    # 计算矩阵A
    a = 0.85
    A = a * S + (1 - a) / length * np.ones([length, length])
    # 准备进行迭代
    PageRank1 = np.ones(length) / length
    PageRank2 = np.zeros(length)

    judge = 1  # 误差判断
    while judge > 0.00000001:  # 开始迭代
        PageRank2 = np.dot(A, PageRank1)  # 迭代公式
        judge = PageRank2 - PageRank1
        judge = max(map(abs, judge))
        PageRank1 = PageRank2

    print('最终结果:', PageRank1)

运行截图

注:因为10000个数据不太好展示,所以附带运行了一下10以内的数据进行简单展示。

10以内的简单展示

QQ图片20220419223952

QQ图片20220419224442

QQ图片20220419224742

QQ图片20220419225309

目标二 代数法实现

题目

代数法求小规模PageRank的稳态解,网页数量为5

思路

利用上一个迭代法部分代码求得S与A,然后进行求逆等相应操作。

原理

20180705180130457

源代码

import numpy as np

if __name__ == '__main__':

    file = open('input.txt', 'r')
    edges_in = []
    edges_out = []
    while True:
        lines = file.readline().strip('\n')
        if not lines:
            break
        else:
            this_line = lines.split(' ')
            edges_out.append(this_line[0])
            edges_in.append(this_line[1])
    # 根据边获取节点的集合
    nodes = []
    for edge in edges_out:
        if edge not in nodes:
            nodes.append(edge)
    for edge in edges_in:
        if edge not in nodes:
            nodes.append(edge)
    length = len(nodes)  # 数据的个数
    i = 0
    node_to_num = {}
    for node in nodes:
        node_to_num[node] = i
        i += 1
    for i in range(len(edges_in)):
        edges_in[i] = node_to_num[edges_in[i]]
        edges_out[i] = node_to_num[edges_out[i]]
    # 生成初步的S矩阵
    S = np.zeros([length, length])
    for i in range(len(edges_in)):
        S[edges_in[i], edges_out[i]] = 1
    # 计算比例:即一个网页对其他网页的PageRank值的贡献,即进行列的归一化处理
    for j in range(length):
        sum_of_col = sum(S[:, j])
        for i in range(length):
            if sum_of_col != 0:
                S[i, j] /= sum_of_col
            else:
                S[i, j] = 1 / length
    # 计算矩阵A
    a = 0.85
    A = a * S + (1 - a) / length * np.ones([length, length])
    E = np.identity(length)
    B = np.ones(length)
    PageRank = (1 - a) / length * np.linalg.inv(E - a * S)
    PageRank = np.dot(PageRank, np.transpose(B))
    print('最终结果:', PageRank)

运行截图

QQ图片20220419223952

QQ图片20220419233454

附加

题目

构造不存在稳态的情况,设计方法变为有稳态的情况

思路

pagerank的计算公式按迭代方式计算,保证矩阵A是正确的。

A=d*P+(1-d)ee^T/n

0<d<1

源代码

注:本人上述代码均使用了该方法避免不收敛

运行截图

QQ图片

QQ图20419234843

补充:

1.代数求解方法需要解方程组

image-20220429163643661

矩阵:S
0 0 0 0 1 0 0 1 0 1 0 0 1 0 1 0 \begin{matrix} 0&0&0&0\\ 1&0&0&1\\ 0&1&0&0\\ 1&0&1&0\\ \end{matrix} 0101001000010100
矩阵:(E-aS)-1
1 0 0 0 − 0.425 1 0 − 0.85 0 − 0.85 1 0 − 0.425 0 − 0.85 1 \begin{matrix} 1&0&0&0\\ -0.425&1&0&-0.85 \\ 0&-0.85&1&0\\ -0.425&0&-0.85&1\\ \end{matrix} 10.42500.425010.8500010.8500.8501
方程:
{ 1 p 1 + 0 p 2 + 0 p 3 + 0 p 4 = 0.375 − 0.425 p 1 + 1 p 2 + 0 p 3 + − 0.85 p 4 = 0.375 0 p 1 + − 0.85 p 2 + 1 p 3 + 0 p 4 = 0.375 − 0.425 p 1 + 0 p 2 + − 0.85 p 3 + 1 p 4 = 0.375 \begin{cases} 1p_1+0p_2+0p_3+0p_4=0.375\\ -0.425p_1+1p_2+0p_3+-0.85p_4=0.375\\ 0p_1+-0.85p_2+1p_3+0p_4=0.375\\ -0.425p_1+0p_2+-0.85p_3+1p_4=0.375\\ \end{cases} 1p1+0p2+0p3+0p4=0.3750.425p1+1p2+0p3+0.85p4=0.3750p1+0.85p2+1p3+0p4=0.3750.425p1+0p2+0.85p3+1p4=0.375
解之得:
0.0375 0.32640914 0.31494776 0.3211431 \begin{matrix} 0.0375&0.32640914&0.31494776&0.3211431\\ \end{matrix} 0.03750.326409140.314947760.3211431

2.变成稳态的方法

利用衰减系数进行判断,用户会有概率随机跳转到一个网页,这样可以保证存在稳态

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值