文章目录

  • TextRank 提取关键词

用处:提取关键词、文本摘要

优点:运算简单,计算速度快。
无监督学习。

思想来源于 PageRank

从入链和出链来看待网页。

沦为 Mihaicea 《TextRank》


公式:

TextRank
类似于PageRank的思想,
将文本中的语法单元视作图中的节点,如果两个语法单元存在一定语法关系(例如共现),则这两个语法单元在图中就会有一条边相互连接。
通过一定的迭代次数,最终不同的节点会有不同的权重,权重高的语法单元可以作为关键词。

参考论文:Rada Mihalcea的《TextRank:Bring Order into texts》

节点的权重不仅依赖于它的入度结点,还依赖于这些入度结点的权重,入度结点越多,入度结点的权重越大,说明这个结点的权重越高;

图中任两点 Vi , Vj 之间边的权重为 wji , 对于一个给定的点 Vi, In(Vi) 为 指 向 该 点 的 点 集 合 , Out(Vi) 为点 Vi 指向的点集合。
TextRank迭代计算公式为:

其中, d 为阻尼系数, 取值范围为 0 到 1,代表从图中某一特定点指向其他任意点的概率, 一般取值为 0.85。

使用TextRank 算法计算图中各点的得分时, 需要给图中的点指定任意的初值, 并递归计算直到收敛。
即图中任意一点的误差率小于给定的极限值时就可以达到收敛, 一般该极限值取 0.0001。

算法通用流程:
应用到关键短语抽取:

  1. 预处理,首先进行分词和词性标注,将单个word作为结点添加到图中;
  2. 设置语法过滤器,将通过语法过滤器的词汇添加到图中;出现在一个窗口中的词汇之间相互形成一条边;
  3. 基于上述公式,迭代直至收敛;一般迭代20-30次,迭代阈值设置为0.0001;
  4. 根据顶点的分数降序排列,并输出指定个数的词汇作为可能的关键词;
  5. 后处理,如果两个词汇在文本中前后连接,那么就将这两个词汇连接在一起,作为关键短语;

其中,TextRank是为TextRank算法抽取关键词所定义的类。
类在初始化时,默认加载了分词函数和词性标注函数 tokenizer = postokenizer = jieba.posseg.dt、停用词表stop_words = self.STOP_WORDS.copy()、词性过滤集合 pos_filt = frozenset(('ns', 'n', 'vn', 'v')),窗口 span = 5,((“ns”, “n”, “vn”, “v”))表示词性为地名、名词、动名词、动词。

首先定义一个无向有权图,然后对句子进行分词;
依次遍历分词结果,如果某个词i满足过滤条件(词性在词性过滤集合中,并且词的长度大于等于2,并且词不是停用词),然后将这个词之后窗口长度为5范围内的词j(这些词也需要满足过滤条件),将它们两两(词i和词j)作为key,出现的次数作为value,添加到共现词典中;

然后,依次遍历共现词典,将词典中的每个元素,key = (词i,词j),value = 词i和词j出现的次数,其中词i,词j作为一条边起始点和终止点,共现的次数作为边的权重,添加到之前定义的无向有权图中。

然后对这个无向有权图进行迭代运算textrank算法,最终经过若干次迭代后,算法收敛,每个词都对应一个指标值;

如果设置了权重标志位,则根据指标值值对无向有权图中的词进行降序排序,最后输出topK个词作为关键词;

def textrank(self, sentence, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v'), withFlag=False):self.pos_filt = frozenset(allowPOS)# 定义无向有权图g = UndirectWeightedGraph()# 定义共现词典cm = defaultdict(int)# 分词words = tuple(self.tokenizer.cut(sentence))# 依次遍历每个词for i, wp in enumerate(words):# 词i 满足过滤条件if self.pairfilter(wp):# 依次遍历词i 之后窗口范围内的词for j in xrange(i + 1, i + self.span):# 词j 不能超出整个句子if j >= len(words):break# 词j不满足过滤条件,则跳过if not self.pairfilter(words[j]):continue# 将词i和词j作为key,出现的次数作为value,添加到共现词典中if allowPOS and withFlag:cm[(wp, words[j])] += 1else:cm[(wp.word, words[j].word)] += 1# 依次遍历共现词典的每个元素,将词i,词j作为一条边起始点和终止点,共现的次数作为边的权重for terms, w in cm.items():g.addEdge(terms[0], terms[1], w)# 运行textrank算法nodes_rank = g.rank()# 根据指标值进行排序if withWeight:tags = sorted(nodes_rank.items(), key=itemgetter(1), reverse=True)else:tags = sorted(nodes_rank, key=nodes_rank.__getitem__, reverse=True)# 输出topK个词作为关键词if topK:return tags[:topK]else:return tags

其中,无向有权图的的定义及实现是在 UndirectWeightedGraph 类中实现的。

根据 UndirectWeightedGraph 类的初始化函数__init__,可以发现,所谓的无向有权图就是一个词典,词典的key是后续要添加的词,词典的value,则是一个由(起始点,终止点,边的权重)构成的三元组所组成的列表,表示以这个词作为起始点的所有的边。

无向有权图添加边的操作 是在addEdge函数中完成的。
因为是无向图,所以我们需要依次将start作为起始点,end作为终止点,然后再将start作为终止点,end作为起始点,这两条边的权重是相同的。

def addEdge(self, start, end, weight):# use a tuple (start, end, weight) instead of a Edge objectself.graph[start].append((start, end, weight))self.graph[end].append((end, start, weight))

执行textrank算法迭代是在rank函数中完成的。
首先对每个结点赋予相同的权重,以及计算出该结点的所有出度的次数之和;
然后迭代若干次,以确保得到稳定的结果;

在每一次迭代中,依次遍历每个结点;对于结点n,首先根据无向有权图得到结点n的所有入度结点(对于无向有权图,入度结点与出度结点是相同的,都是与结点n相连的结点)
在前面我们已经计算出这个入度结点的所有出度的次数,
它对于 结点n的权值的贡献 = 它本身的权值 * 它与结点n的共现次数 / 这个结点的所有出度的次数

将各个入度结点得到的权值相加,再乘以一定的阻尼系数,即可得到结点n的权值;

迭代完成后,对权值进行归一化,并返回各个结点及其对应的权值。

def rank(self):ws = defaultdict(float)outSum = defaultdict(float)wsdef = 1.0 / (len(self.graph) or 1.0)# 初始化各个结点的权值# 统计各个结点的出度的次数之和for n, out in self.graph.items():ws[n] = wsdefoutSum[n] = sum((e[2] for e in out), 0.0)# this line for build stable iterationsorted_keys = sorted(self.graph.keys())# 遍历若干次for x in xrange(10):  # 10 iters# 遍历各个结点for n in sorted_keys:s = 0# 遍历结点的入度结点for e in self.graph[n]:# 将这些入度结点贡献后的权值相加# 贡献率 = 入度结点与结点n的共现次数 / 入度结点的所有出度的次数s += e[2] / outSum[e[1]] * ws[e[1]]# 更新结点n的权值ws[n] = (1 - self.d) + self.d * s(min_rank, max_rank) = (sys.float_info[0], sys.float_info[3])# 获取权值的最大值和最小值for w in itervalues(ws):if w < min_rank:min_rank = wif w > max_rank:max_rank = w# 对权值进行归一化for n, w in ws.items():# to unify the weights, don't *100.ws[n] = (w - min_rank / 10.0) / (max_rank - min_rank / 10.0)return ws

TextRank 提取关键词

#-*- coding=utf8 -*-
from jieba import analyse # 引入TextRank关键词抽取接口
textrank = analyse.textrank # 原始文本
text = "非常线程是程序执行时的最小单位,它是进程的一个执行流,\ 是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,\ 线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。\ 线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。\ 同样多线程也可以实现并发操作,每个请求分配一个线程来处理。"
print ("\nkeywords by textrank:") # 基于TextRank算法进行关键词抽取 keywords = textrank(text, topK=10, withWeight=True, allowPOS=('ns', 'n')) # 指定参数; 获得了词和权重# 输出抽取出的关键词 f
words=[keyword for keyword,w in keywords if w>0.2]
print (' '.join(words) + "\n")

NLP - TextRank相关推荐

  1. jieba tfidf_【NLP】【三】jieba源码分析之关键字提取(TF-IDF/TextRank)

    [一]综述 利用jieba进行关键字提取时,有两种接口.一个基于TF-IDF算法,一个基于TextRank算法.TF-IDF算法,完全基于词频统计来计算词的权重,然后排序,在返回TopK个词作为关键字 ...

  2. python nlp文本摘要实现_用TextRank算法实现自动文本摘要

    [51CTO.com快译]1. 引言 文本摘要是自然语言处理(NLP)领域中的应用之一,它必将对我们的生活产生巨大影响.随着数字媒体和出 版业的不断发展,谁还有时间浏览整篇文章/文档/书籍来决定它们是 ...

  3. NLP - 关键词提取 - TextRank

    NLP - 关键词提取 - TextRank 一.TextRank介绍 二.PageRank介绍 三.PageRank计算过程 四.关键词提取任务 一.TextRank介绍 TextRank算法则可以 ...

  4. 【NLP】文本关键词提取的两种方法-TFIDF和TextRank

    背景 前两天看到论文<Chinese Poetry Generation with Planning based Neural Network>中使用TextRank进行关键词提取.在阅读 ...

  5. java jieba tfidf_【NLP】【三】jieba源码分析之关键字提取(TF-IDF/TextRank)

    [一]综述 利用jieba进行关键字提取时,有两种接口.一个基于TF-IDF算法,一个基于TextRank算法.TF-IDF算法,完全基于词频统计来计算词的权重,然后排序,在返回TopK个词作为关键字 ...

  6. NLP学习笔记——TextRank算法

    一.算法简介 TextRank算法是一种基于图的排序算法,由谷歌的网页重要性排序算法PageRank算法改进而来,主要应用有关键词提取.文本摘要抽取等.该算法的主要思想是:把文档中的词(句)看成一个网 ...

  7. NLP自然语言处理工具小结

    20220331 https://zhuanlan.zhihu.com/p/79202151 BM25 https://github.com/v1shwa/document-similarity wo ...

  8. NLP带来的“科幻感”超乎你的想象 - ACL2020论文解读

    来源 | 京东智联云开发者 责编 | Carol 近些年,人工智能无疑是信息技术领域最热门的技术之一.人工智能战胜世界围棋冠军.人工智能战胜游戏高手.人工智能医生看病会诊--不断进步的科技正推动着人工 ...

  9. 转载 干货 | 陪伴我学习NLP、知识图谱的那些资源(教程+书籍+网站+工具+论文...可以说很全面了)

    https://blog.csdn.net/guleileo/article/details/81140179 干货 | 陪伴我学习NLP.知识图谱的那些资源(教程+书籍+网站+工具+论文...可以说 ...

最新文章

  1. Oracle 12c DG备库Alert报错ORA-01110
  2. oracle vm 实施图解
  3. WebService_Unity
  4. 0-1 背包问题的 4 种解决方法算法策略
  5. Android设计模式之——解释器模式
  6. python画tan_Python入门之三角函数tan()函数实例详解
  7. 不同图像锐化算子提取的图像信息有哪些不同_传统图像处理
  8. stl取出字符串中的字符_在C ++ STL中使用比较运算符比较两个字符串
  9. 金山网盾3.5实战流氓软件
  10. 通过外挂插件向预训练语言模型中融入知识
  11. Java Android 代码片段收集
  12. 整个社会总嫌自己不够“快”,为啥?
  13. AD15批量修改丝印的方法
  14. C语言加油站程序,C语言解决 加油站问题
  15. whx带我刷JOI training
  16. python常见算法实现_几种常见算法的Python实现
  17. python毕业设计作品基于django框架 景区购票系统毕设成品(4)开题报告
  18. dubbo-go 中如何实现远程配置管理?
  19. 追梦猪seo针对于移动端seo优化和排名技术
  20. Devops实现之sonarQube(四)

热门文章

  1. 北京信息科技大学第十一届程序设计竞赛(重现赛)D kotori和迷宫
  2. Aspose.cell 生成折线图
  3. 阅读笔记WS-DAN
  4. 分布式系统 (大规模分布式系统原理解析和架构实践)
  5. Excel,python全都靠边站,这才是数据分析应该有的样子
  6. oracle 加密方案
  7. 站长爆料:网站被恶意威胁k站索要5000元!
  8. 记ManageEngine Free Tools 工具的一个坑(鼠标点击没反应)
  9. EveryOne Piano
  10. 建国大业 《红》mp3下载