数据仓库与数据挖掘——PageRank

一、基本介绍

        PageRank算法的基本想法是在有向图上定义一个随机游走模型,即一阶马尔可夫链,描述随机游走者沿着有向图随机访问各个结点的行为。在一定条件下,极限情况访问每个结点的概率收敛到平稳分布,各结点的平稳概率值就是其PageRank值,表示结点的重要度。

        PageRank是递归定义的,PageRank的计算可以通过迭代算法进行。

二、实验内容    

        PageRank算法的核心部分可以从一个有向图开始。最典型的方法是根据有向图构造邻接矩阵来进行处理。邻接矩阵A=(a[i,j])中的元素a[i,j] (∈[0,1])表示从页面j指向页面i的概率。

        基本的PageRank算法在计算等级值时,每个页面都将自己的等级值平均地分配给其引用的页面节点。假设页面的等级值为1,该页面上共有n个超链接,分配给每个超链接页面的等级值就是1/n,那么就可以理解为该页面以1/n的概率跳转到任意一个其所引用的页面上。

        一般地,把邻接矩阵A转换成所谓的转移概率矩阵M来实现PageRank算法:

M=(1-d)*Q+d*A

        其中,Q是一个常量矩阵,最常用的是Q=(q[i,j]),q[i,j]=1/n

​        转移概率矩阵M可以作为一个向量变换矩阵来帮助完成页面等级值向量R的迭代计算:

R[i+1]=M*R[i]

       页面之间的超链接分析通常基于以下假设:

       1)若页面A上存在指向页面B的超链接,就认为页面A对页面B进行了一次参考引用;

       2)一个页面被越多的其他页面指向,越能说明这个页面等级越高;

       3)每个页面都有一个衡量其重要性的参数值(等级值),并且会将这一参数值平均地分配给它指向的全部页面。

三、算法伪代码

四、算法流程图

五、关键源码展示

1、导入数据

2、计算移转概率矩阵

 3、计算页面等级值向量

4、输出页面等级值向量

六、 完整代码与数据集

1、完整代码

N = 4
d = 0.85
delt = 0.1


def loadData():
    with open("PageRank.txt", "r") as f:
        fline = f.readlines()
        matrix = []
        buffer = []
        for item in fline[0:]:
            line = item.strip().split(',')
            # print(line)
            for i in range(len(line)):
                if '/' in line[i]:
                    buffer.append(float(line[i].split('/')[0]) / float(line[i].split('/')[1]))
                else:
                    buffer.append(float(line[i]))
            matrix.append(buffer.copy())
            buffer.clear()
        # print(matrix)
        return matrix


# 矩阵相加
def matrix_add(A, B):
    result = []
    for i in range(len(A)):
        result.append([])
        for j in range(len(A[i])):
            result[i].append(A[i][j] + B[i][j])
    return result


# 矩阵相乘
def matrix_multi(A, B):
    result = [[0 for _ in range(len(B[0]))] for _ in range(len(A))]
    for i in range(len(A)):
        for j in range(len(B[0])):
            for k in range(len(B)):
                result[i][j] += A[i][k] * B[k][0]
    return result


# 根据邻接矩阵求转移概率矩阵
def Transfer_Probability_Matrix(A):
    q = [[(1 - d) * (1 / N)] * N for _ in range(N)]
    for i in range(len(A)):
        for j in range(len(A[0])):
            A[i][j] = d * A[i][j]
    result = matrix_add(q, A)
    return result


# 基于随机冲浪的PageRank算法
def PageRank(M):
    r = [[1] * N for _ in range(N)]
    New_R = r
    R = [0] * N
    epsilon = 1
    cnt = 1
    while epsilon > delt:
        r = New_R
        New_R = matrix_multi(M, r)
        epsilon = 0
        # 求解矩阵一阶范数
        for i in range(N):
            epsilon += abs(New_R[i][0] - r[i][0])
        for i in range(len(New_R)):
            R[i] = New_R[i][0]
        print('R[{}]={}'.format(cnt, R))
        if epsilon > delt:
            print('ε{}={}>ε={},因此继续迭代...'.format(cnt, epsilon, delt))
        else:
            print('ε{}={}≤ε={},因此迭代结束'.format(cnt, epsilon, delt))
        print()
        cnt += 1


def main():
    A = loadData()
    # A = [[0, 1 / 2, 0, 1 / 2],
    #      [1 / 3, 0, 0, 1 / 2],
    #      [1 / 3, 1 / 2, 0, 0],
    #      [1 / 3, 0, 1, 0]]

    M = Transfer_Probability_Matrix(A)
    print('M:')
    for i in range(len(M)):
        print(M[i])
    # print('M={}'.format(M))
    print()
    PageRank(M)


if __name__ == '__main__':
    main()

2、数据集

0,1/2,1,0
1/3,0,0,1/2
1/3,0,0,1/2
1/3,1/2,0,0

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有为肥宅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值