pageRank和TextRank

ageRank和TextRank

PageRank

PageRank原理

pangRank是用于对网页进行排名的算法。通俗的讲就是对每个网页进行打分,根据得分高低进行排序。怎么打分?

打分思路如下:

1.假如有个网页C

2.当连接(其他网页可以跳转到C)到C的网页越多(A和B的数量越多),C的比重(pagerank值)应该越高。

3.当链接到C的网页的本身比重越高时(A和B本身体的分数越高),C的比重应该越高。

在这里插入图片描述

PageRank论文:

《The PageRank Citation Ranking: Bringing Order to the Web》

具体实现:

假设互联网是一个有向图,ABC三个节点代表网页,每条边代表转移比重。

在这里插入图片描述

每个网页都会以等概率跳转到它链接到的网页,跳转是随机的,这就形成了一个随机游走模型,即一阶马尔可夫链 。初始化时每个节点的权重都是1,随着不断的跳转,不断的迭代。这个马尔科夫链会逐渐的形成一种平稳分布。

在这里插入图片描述

权重(PageRank值)的计算公示如下:

在这里插入图片描述

公式来源于何晗:自然语言处理入门 S ( v i ) S(v_i) S(vi)是某个节点的权重,初始都是1,d是介于(0,1)之间的常熟因子,模拟用户通过点击链接跳转到这个页面的概览,1-d就是用户通过输入网址到这个页面的概览。 I n ( v i ) In(v_i) In(vi)表示能链接到 V i V_i Vi的节点的集合, O u t ( V j ) Out(V_j) Out(Vj)表示从 V j V_j Vj出发的链接的集合。所以从 V − j V-j Vj发出的链接越多,每个链接的权重就越小。以figure2为例,权重为9的节点,总过发出了3条链接,则每条链接的权重为9/3=3。

PageRank程序设计

以figure3为例,假设有ABC三个节点,初始时刻三个节点的权重都是1,

在这里插入图片描述

设计程序计算ABC最终的权重:

#coding=utf8

class Node():
    
    #初始化一个节点
    def __init__(self, value=1, childrens=set(), name=''):
        '''初始时刻所有节点的权重都是1'''
        self.value = value
        self.childrens = childrens
        self.name = name
        
    def __repr__(self):
        return self.name

        
class PageRank():
    
    #初始化有向图
    def __init__(self, allNode=[]):
        self.allNode = allNode
    
    #一次迭代计算(也可以改写成一遍计算一遍迭代的方式,如下)
    def cal(self, d):
        values = []
        for i in self.allNode:
            values.append((1-d) + d*(sum([j.value/len(j.childrens) if i in j.childrens else 0 for j in self.allNode])))
        for i,j in zip(self.allNode,values):
            i.value = j
            
    #def cal(self, d):
        #for i in self.allNode:
            #i.value = (1-d) + d*(sum([j.value/len(j.childrens) if i in j.childrens else 0 for j in self.allNode])) 
 
    
    def computer(self, Num, threshold):
        '''Num是迭代次数,threshold是阈值当总体权重变化量小于这个值时停止迭代'''
        
        #生成需要打印的东西
        text1 = '{0:<15}'
        text2 = '{0:<15}'
        for indx,Node in enumerate(self.allNode):
            text1 += '{{{}:<15}}'.format(indx+1)
            text2 += '{{{}:<15.8f}}'.format(indx+1)   
        print(text1.format('iteration',*['PR({0})'.format(i) for i in self.allNode]))
        
        #开始迭代
        count = 0
        while count<=Num:
            print(text2.format(count,*[i.value for i in self.allNode]))
            values = [i.value for i in self.allNode]
            self.cal(0.5)
            new_values = [i.value for i in self.allNode]
            count += 1
            if sum([abs(i-j) for i, j in zip(values, new_values)])<=threshold:
                break
    
    
if __name__ == '__main__':
    A = Node(value=1,name='A')
    B = Node(value=1,name='B')
    C = Node(value=1,name='C')
    A.childrens = {B,C}
    B.childrens = {C}
    C.childrens = {A}
    pagerank = PageRank(allNode=[A,B,C])
    pagerank.computer(100,0.00000001)
    
        

最终计算结果:

在这里插入图片描述

PageRank的向量表示

上述迭代过程可用矩阵相乘的形式表示,初始状态向量为: R 0 = [ 1.0 , 1.0 , 1.0 ] T R_0 = [1.0,1.0,1.0]^T R0=[1.0,1.0,1.0]T ,

转移矩阵(有的称呼为概览转移矩阵、状态转移矩阵)为: M = [ [ 0 , 0 , 1 ] , [ 0.5 , 0 , 0 ] , [ 0.5 , 1 , 0 ] ] M=[[0, 0, 1],[0.5, 0, 0],[0.5, 1, 0]] M=[[0,0,1],[0.5,0,0],[0.5,1,0]]

则一次迭代的结果为:

R 1 = ( 1 − d ) ⋅ ( e e t n ⋅ R 0 ) + d ⋅ M ⋅ R 0 R_1 = (1-d)·(\frac{ee^t}{n}·R_0) + d·M·R_0 R1=(1d)(neetR0)+dMR0 ,其中e为单位列向量,eeT为n*n的1矩阵。n为节点个数,在此为3 。

R 1 = 0.5 ∗ [ 1 , 1 , 1 ] + 0.5 ∗ [ 1 , 0.5 , 1.5 ] = [ 1 , 0.75 , 1.25 ] R_1 = 0.5*[1,1,1] + 0.5*[1,0.5,1.5] = [1,0.75,1.25] R1=0.5[1,1,1]+0.5[1,0.5,1.5]=[1,0.75,1.25]

以此类推:

在这里插入图片描述

转移矩阵M如下:

在这里插入图片描述

pagerank程序设计-矩阵

import numpy as np

class Node():
    
    #初始化一个节点
    def __init__(self, value=1, childrens=set(), name=''):
        '''初始时刻所有节点的权重都是1'''
        self.value = value
        self.childrens = childrens
        self.name = name
        
    def __repr__(self):
        return self.name

        
class PageRank():
    
    #初始化有向图
    def __init__(self, allNode=[]):
        self.allNode = allNode
        self.state = np.array([i.value for i in self.allNode])
        self.Matric()
    
    #生成转移矩阵    
    def Matric(self):
        values = []
        for i in self.allNode:
            values.append([j.value/len(j.childrens) if i in j.childrens else 0 for j in self.allNode])
        self.metric = np.array(values)        
    
    #一次迭代计算
    def cal(self, d):
        self.state = (1-d)/len(self.allNode)*np.ones([len(self.allNode),len(self.allNode)])@self.state + d*self.metric@self.state
        for i,j in zip(self.allNode,list(self.state)):
            i.value = j
    
    def computer(self, Num, threshold):
        '''Num是迭代次数,threshold是阈值当总体权重变化量小于这个值时停止迭代'''
        
        #生成需要打印的东西
        text1 = '{0:<15}'
        text2 = '{0:<15}'
        for indx,Node in enumerate(self.allNode):
            text1 += '{{{}:<15}}'.format(indx+1)
            text2 += '{{{}:<15.8f}}'.format(indx+1)   
        print(text1.format('iteration',*['PR({0})'.format(i) for i in self.allNode]))
        
        #开始迭代
        count = 0
        while count<=Num:
            print(text2.format(count,*[i.value for i in self.allNode]))
            values = [i.value for i in self.allNode]
            self.cal(0.5)
            new_values = [i.value for i in self.allNode]
            count += 1
            if sum([abs(i-j) for i, j in zip(values, new_values)])<=threshold:
                break
    
        
if __name__ == '__main__':
    A = Node(value=1,name='A')
    B = Node(value=1,name='B')
    C = Node(value=1,name='C')
    A.childrens = {B,C}
    B.childrens = {C}
    C.childrens = {A}
    pagerank = PageRank(allNode=[A,B,C])
    pagerank.computer(100,0.00001)

计算结果:

在这里插入图片描述

TextRank

TextRank从google的网页排序算法脱胎而来,是一种基于图结构的应用于文本处理排序的无监督模型,可以应用在关键词和关键句的抽取。

TextRank关键词提取

将单词视为节点,每个单词的外联来自,身前身后固定大小的窗口内的所有单词。如下图所示:

图片来源:何晗:自然语言处理入门

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值