分享

TextRank算法

 小世界的野孩子 2022-10-17 发布于北京

TextRank算法

TD-IDF是基于词频的算法,而TextRank是基于图 形的算法。

TextRank是受到PageRank算法的启发。

 

PageRank算法

PageRank主要用于对在线搜索结果中的网页进行排序

PageRank对于每个网页页面都给出一个正实数,表示网页的重要程度,PageRank值越高,表示网页越重要,在互联网搜索的排序中越可能被排在前面。同样,被链接的网页的PageRank值也会相应的因此而提高。

假设整个互联网是一个有向图,节点是网页,每条边是转移概率。网页浏览者在每个页面上依照连接出去的超链接,以等概率跳转到下一个网页,并且在网页上持续不断地进行这样的随机跳转,这个过程形成了一阶马尔科夫链,比如下图:
在这里插入图片描述
  每个笑脸是一个网页,既有其他网页跳转到该网页,该网页也会跳转到其他网页。在不断地跳转之后,这个马尔科夫链会形成一个平稳分布,而PageRank就是这个平稳分布,每个网页的PageRank值就是平稳概率。

  PageRank的核心公式是PageRank值的计算公式。公式如下:

  其中,PR(Vi)表示结点Vi的rank值,In(Vi)表示结点Vi的前驱结点集合,Out(Vj)表示结点Vj的后继结点集合。
  这个公式来自于《统计学习方法》,等号右边的平滑项(通过某种处理,避免一些突变的畸形值,尽可能接近实际情况)不是(1-d),而是(1-d)/n。
  阻尼系数d(damping factor)的意义是,在任意时刻,用户到达某页面后并继续向后浏览的概率。1-d就是用户停止点击,随机跳到新URL的概率。
  加平滑项是因为有些网页没有跳出去的链接,那么转移到其他网页的概率将会是0,这样就无法保证存在马尔科夫链的平稳分布。
  于是,我们假设网页以等概率(1/n)跳转到任何网页,再按照阻尼系数d,对这个等概率(1/n)与存在链接的网页的转移概率进行线性组合,那么马尔科夫链一定存在平稳分布,一定可以得到网页的PageRank值。

  所以PageRank的定义意味着网页浏览者按照以下方式在网上随机游走:以概率d按照存在的超链接随机跳转,以等概率从超链接跳转到下一个页面;或以概率(1-d)进行完全随机跳转,这时以等概率(1/n)跳转到任意网页。

  PageRank的计算是一个迭代过程,先假设一个初始的PageRank分布,通过迭代,不断计算所有网页的PageRank值,直到收敛为止,也就是:
在这里插入图片描述

 

 

从PageRank到TextRank算法

  和基于词频( TF-IDF )相比,TextRank进一步考虑了文档内词条之间的语义关系也就是说考虑到额这个词条的上下文,如果这个词的上下文都是一些很重要的词,那么这个词大概率也是很重要的词。 

基本原理:

  • 将文档按照整句进行分割
  • 分词并清理,只保留指定词性的词条
  • 以整句为单位计算词条的共现矩阵(主要用于发现主题,解决词向量相近关系的表示 ),只要在一个句子里出现,就要考虑共现性了,
  • 按指定窗口长度K,构建词条网络
  • 基于网络连接特征计算词条重要性
  • 排序并输出结果

 

 

 

TextRank算法介绍

TextRank

TextRank 算法是一种用于文本的基于图的排序算法。其基本思想来源于谷歌的 PageRank算法, 通过把文本分割成若干组成单元(单词、句子)并建立图模型, 利用投票机制对文本中的重要成分进行排序, 仅利用单篇文档本身的信息即可实现关键词提取、文摘。和 LDA、HMM 等模型不同, TextRank不需要事先对多篇文档进行学习训练, 因其简洁有效而得到广泛应用。

  TextRank 一般模型可以表示为一个有向有权图 G =(V, E), 由点集合 V和边集合 E 组成, E 是V ×V的子集。图中任两点 Vi , Vj 之间边的权重为 wji , 对于一个给定的点 Vi, In(Vi) 为 指 向 该 点 的 点 集 合 , Out(Vi) 为点 V指向的点集合。点 Vi 的得分定义如下:

 

  其中, d 为阻尼系数, 取值范围为 0 到 1, 代表从图中某一特定点指向其他任意点的概率, 一般取值为 0.85。使用TextRank 算法计算图中各点的得分时, 需要给图中的点指定任意的初值, 并递归计算直到收敛, 即图中任意一点的误差率小于给定的极限值时就可以达到收敛, 一般该极限值取 0.0001。

1. 基于TextRank的关键词提取

  关键词抽取的任务就是从一段给定的文本中自动抽取出若干有意义的词语或词组。TextRank算法是利用局部词汇之间关系(共现窗口)对后续关键词进行排序,直接从文本本身抽取。其主要步骤如下:

  (1)把给定的文本T按照完整句子进行分割,即

  (2)对于每个句子,进行分词和词性标注处理,并过滤掉停用词,只保留指定词性的单词,如名词、动词、形容词,即,其中是保留后的候选关键词。

  (3)构建候选关键词图G = (V,E),其中V为节点集,由(2)生成的候选关键词组成,然后采用共现关系(co-occurrence)构造任两点之间的边,两个节点之间存在边仅当它们对应的词汇在长度为K的窗口中共现,K表示窗口大小,即最多共现K个单词。

  (4)根据上面公式,迭代传播各节点的权重,直至收敛。

  (5)对节点权重进行倒序排序,从而得到最重要的T个单词,作为候选关键词。 

  (6)由(5)得到最重要的T个单词,在原始文本中进行标记,若形成相邻词组,则组合成多词关键词。例如,文本中有句子“Matlab code for plotting ambiguity function”,如果“Matlab”和“code”均属于候选关键词,则组合成“Matlab code”加入关键词序列。

用jieba实现TextRank算法

  

from gensim.corpora import Dictionary

import wordcloud
import pandas as pd
import jieba
import jieba.analyse
import matplotlib.pyplot as plt
from nltk.corpus import brown

from sklearn.feature_extraction.text import CountVectorizer

# 数据准备
# ============================================================================================================
#
raw = pd.read_table('./金庸-射雕英雄传txt精校版.txt',names=['txt'],encoding='GBK')
# print(raw)

# 加入章节标识
# 章节判断用变量预处理
def m_head(tmpstr):
    return tmpstr[:1]  #取第一个字

def m_mid(tmpstr):
    return tmpstr.find("")

# 用apply函数将下面的属性加入到对应列
raw['head'] = raw.txt.apply(m_head)
raw['mid'] = raw.txt.apply(m_mid)
raw['len'] = raw.txt.apply(len)


# 章节判断
chapnum = 0
for i in range(len(raw)):
    if raw['head'][i] == "" and raw['mid'][i] >0 and raw['len'][i]<30:
        chapnum += 1
    if chapnum >= 40 and raw['txt'][i] == "附录一:成吉思汗家族":
        chapnum=0
    raw.loc[i,'chap'] = chapnum

# 删除临时变量
del raw['head']
del raw['mid']
del raw['len']

# 段落聚合  根据章节聚合
rawgrp = raw.groupby('chap')

chapter = rawgrp.agg(sum)

chapter = chapter[chapter.index != 0]
# 设定分词以及清理停用词函数
# 先用pandas将停用词读出,存到变量w中,最后取出w,转为list
stoplist = list(pd.read_csv('停用词.txt',names=['w'],sep='aaa',encoding='utf-8',engine='python').w)
# 清理停用词哈数
def m_cut(intxt):
    return [w for w in jieba.cut(intxt) if w not in stoplist and len(w)>1]
countvec = CountVectorizer()

analyze = countvec.build_analyzer()
# 使用空格分开
t = analyze('郭靖 和 哀牢山 三十六 剑 。')
# 默认删去停用词列表中的词和符号
print(t)
# ['郭靖', '哀牢山', '三十六']


#
# ============================================================================================================
# 数据准备结束


# TextRank算法的jieba实现

# 对射雕英雄传的第一章进行关键词抓取,取前20个
t = jieba.analyse.textrank(
    chapter.txt[1],
    topK=20,#词频前20
    withWeight=True
)
# 默认是过滤词性的 也就是allowPOS=('ns','n','vn','v')  默认值
print(t)
# 这个结果和前面的TF-IDF结果差异较大,因为TextRank算法过滤掉了一些词性,只保留了名词和动词
# [('官兵', 1.0), ('武官', 0.9334143199050102), ('丘处机', 0.7358359699167335), ('娘子', 0.6744231421648419), ('丈夫', 0.5830294283456839), ('金兵', 0.5781198085682175), ('临安', 0.5770670188243039), ('说道', 0.5770566609658306), ('小人', 0.5090129786491732), ('只见', 0.4571074590990817), ('皇帝', 0.44602714989497655), ('出来', 0.44153726005111005), ('妻子', 0.3806600930485957), ('道人', 0.37477396448704836), ('道长', 0.3700338339927484), ('百姓', 0.326847924487172), ('短剑', 0.30052710293852547), ('双手', 0.29602787925127344), ('心想', 0.29137224579945303), ('贫道', 0.28869640746976294)]

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多