TD-IDF是基于词频的算法,而TextRank是基于图 形的算法。python
TextRank是受到PageRank算法的启发。web
PageRank主要用于对在线搜索结果中的网页进行排序。算法
PageRank对于每一个网页页面都给出一个正实数,表示网页的重要程度,PageRank值越高,表示网页越重要,在互联网搜索的排序中越可能被排在前面。一样,被连接的网页的PageRank值也会相应的所以而提升。网络
假设整个互联网是一个有向图,节点是网页,每条边是转移几率。网页浏览者在每一个页面上依照链接出去的超连接,以等几率跳转到下一个网页,而且在网页上持续不断地进行这样的随机跳转,这个过程造成了一阶马尔科夫链,好比下图:
每一个笑脸是一个网页,既有其余网页跳转到该网页,该网页也会跳转到其余网页。在不断地跳转以后,这个马尔科夫链会造成一个平稳分布,而PageRank就是这个平稳分布,每一个网页的PageRank值就是平稳几率。app
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)跳转到任意网页。ui
PageRank的计算是一个迭代过程,先假设一个初始的PageRank分布,经过迭代,不断计算全部网页的PageRank值,直到收敛为止,也就是:
spa
和基于词频( TF-IDF )相比,TextRank进一步考虑了文档内词条之间的语义关系。 也就是说考虑到额这个词条的上下文,若是这个词的上下文都是一些很重要的词,那么这个词大几率也是很重要的词。 code
基本原理:
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”加入关键词序列。
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)]