TextRank算法TD-IDF是基于词频的算法,而TextRank是基于图 形的算法。 TextRank是受到PageRank算法的启发。
PageRank算法PageRank主要用于对在线搜索结果中的网页进行排序。 PageRank对于每个网页页面都给出一个正实数,表示网页的重要程度,PageRank值越高,表示网页越重要,在互联网搜索的排序中越可能被排在前面。同样,被链接的网页的PageRank值也会相应的因此而提高。 假设整个互联网是一个有向图,节点是网页,每条边是转移概率。网页浏览者在每个页面上依照连接出去的超链接,以等概率跳转到下一个网页,并且在网页上持续不断地进行这样的随机跳转,这个过程形成了一阶马尔科夫链,比如下图: PageRank的核心公式是PageRank值的计算公式。公式如下: 其中,PR(Vi)表示结点Vi的rank值,In(Vi)表示结点Vi的前驱结点集合,Out(Vj)表示结点Vj的后继结点集合。 所以PageRank的定义意味着网页浏览者按照以下方式在网上随机游走:以概率d按照存在的超链接随机跳转,以等概率从超链接跳转到下一个页面;或以概率(1-d)进行完全随机跳转,这时以等概率(1/n)跳转到任意网页。
PageRank的计算是一个迭代过程,先假设一个初始的PageRank分布,通过迭代,不断计算所有网页的PageRank值,直到收敛为止,也就是:
从PageRank到TextRank算法和基于词频( TF-IDF )相比,TextRank进一步考虑了文档内词条之间的语义关系。 也就是说考虑到额这个词条的上下文,如果这个词的上下文都是一些很重要的词,那么这个词大概率也是很重要的词。 基本原理:
TextRank算法介绍TextRank TextRank 算法是一种用于文本的基于图的排序算法。其基本思想来源于谷歌的 PageRank算法, 通过把文本分割成若干组成单元(单词、句子)并建立图模型, 利用投票机制对文本中的重要成分进行排序, 仅利用单篇文档本身的信息即可实现关键词提取、文摘。和 LDA、HMM 等模型不同, TextRank不需要事先对多篇文档进行学习训练, 因其简洁有效而得到广泛应用。 TextRank 一般模型可以表示为一个有向有权图 G =(V, E), 由点集合 V和边集合 E 组成, E 是V ×V的子集。图中任两点 Vi , Vj 之间边的权重为 wji , 对于一个给定的点 Vi, In(Vi) 为 指 向 该 点 的 点 集 合 , Out(Vi) 为点 Vi 指向的点集合。点 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)]
|
|