数据挖掘十大算法(九):PageRank算法原理与实现

一、简介

PageRank,又称网页排名、谷歌左侧排名,是一种由搜索引擎根据网页之间相互的超链接计算的技术,而作为网页排名的要素之一,以Google公司创办人拉里·佩奇(Larry Page)之姓来命名。Google用它来体现网页的相关性和重要性,在搜索引擎优化操作中是经常被用来评估网页优化的成效因素之一。

假设一个由4个网页组成的群体:A,B,C和D。如果所有页面都只链接至A,那么A的PR(PageRank)值将是B,C及D的Pagerank总和。
在这里插入图片描述
重新假设B链接到A和C,C只链接到A,并且D链接到全部其他的3个页面。一个页面总共只有一票。所以B给A和C每个页面半票。以同样的逻辑,D投出的票只有三分之一算到了A的PageRank上。

在这里插入图片描述
数据挖掘十大算法(九):PageRank算法原理与实现_第1张图片
阻尼系数是根据上网者使用浏览器书签的平均频率估算而得,通常d=0.85。

二、计算实例

数据挖掘十大算法(九):PageRank算法原理与实现_第2张图片
为了便于计算,我们假设每个页面的PR初始值为1,d为0.5。
数据挖掘十大算法(九):PageRank算法原理与实现_第3张图片
下面是迭代计算12轮之后,各个页面的PR值:
数据挖掘十大算法(九):PageRank算法原理与实现_第4张图片
那么什么时候,迭代结束哪?
比如上次迭代结果与本次迭代结果小于某个误差,我们结束程序运行;
比如还可以设置最大循环次数。

三、Python实现

'''
读取数据:
A B
A C
B C
C A

注意:在code中我们是每一次epoch更新一轮,
与前面的手动计算不同。
'''


import numpy as np

if __name__ == '__main__':

    # 读入有向图,存储边
    file = open('input.txt', 'r')
    edges = [line.strip('\n').split(' ') for line in file]
    print(edges)

    # 根据边获取节点的集合
    nodes = []
    for edge in edges:
        if edge[0] not in nodes:
            nodes.append(edge[0])
        if edge[1] not in nodes:
            nodes.append(edge[1])
    print(nodes)

    N = len(nodes)

    # 将节点符号(字母),映射成阿拉伯数字,便于后面生成A矩阵/S矩阵
    i = 0
    node_to_num = {}  # 存储节点和数字的对应关系

    for node in nodes:
        node_to_num[node] = i
        i += 1
    for edge in edges:
        edge[0] = node_to_num[edge[0]]
        edge[1] = node_to_num[edge[1]]
    print(edges, '\n')

    # 生成初步的S矩阵
    S = np.zeros([N, N])
    for edge in edges:
        S[edge[1], edge[0]] = 1
    print('初步S矩阵为:(链接关系)')
    print(S)

    # 计算比例:即一个网页对其他网页的PageRank值的贡献
    # 要理解这里必须是 列归一化!我们要做的是矩阵乘法。
    for j in range(N):
        sum_of_col = sum(S[:, j])
        for i in range(N):
            if sum_of_col != 0: S[i, j] /= sum_of_col
            else: S[i, j] /= sum_of_col
    print(S, '\n')


    # 设定初始的PageRank值均为1
    P_now = np.ones(N)
    P_last = np.ones(N)

    alpha = 0.5
    e = 100000  # 误差初始化
    k = 0  # 记录迭代次数
    print('loop...')

    while e > 0.00000001:
        P_now = (1 - alpha) + alpha * np.dot(S, P_now)

        e = P_now - P_last  # 计算误差
        e = max(map(abs, e))
        P_last = P_now
        k += 1

        print('iteration %s:' % str(k), P_now)

    print('final result:', P_now)

输出结果:
数据挖掘十大算法(九):PageRank算法原理与实现_第5张图片

你可能感兴趣的:(Machine,Learning)