先说一下自动文摘的方法。自动文摘(Automatic Summarization)的方法主要有两种:Extraction和Abstraction。其中Extraction是抽取式自动文摘方法,通过提取文档中已存在的关键词,句子形成摘要;Abstraction是生成式自动文摘方法,通过建立抽象的语意表示,使用自然语言生成技术,形成摘要。由于生成式自动摘要方法需要复杂的自然语言理解和生成技术支持,应用领域受限。一般采用抽取式的自动文摘方法。

目前主要方法有:

  • 基于统计:统计词频,位置等信息,计算句子权值,再选取权值高的句子作为文摘,特点:简单易用,但对词句的使用大多仅停留在表面信息。
  • 基于图模型:构建拓扑结构图,对词句进行排序。例如,TextRank/LexRank
  • 基于潜在语义:使用主题模型,挖掘词句隐藏信息。例如,采用LDA,HMM
  • 基于整数规划:将文摘问题转为整数线性规划,求全局最优解。

TextRank:

算法TextRank受到网页之间关系PageRank算法启发,利用局部词汇之间关系(共现窗口)构建网络,计算词的重要性,选取权重大的做为关键词。常用流程: 原始语料 → 分词 → 停用词过滤 → 关键词抽取

先说下PageRank

PageRank

PageRank最开始用来计算网页的重要性。整个www可以看作一张有向图图,节点是网页。如果网页A存在到网页B的链接,那么有一条从网页A指向网页B的有向边。构造完图后,使用下面的公式:

S(Vi)是网页i的重要性(PR值)。d是阻尼系数,一般设置为0.85。In(Vi)是存在指向网页i的链接的网页集合。Out(Vj)是网页j中的链接存在的链接指向的网页的集合。|Out(Vj)|是集合中元素的个数。
PageRank需要使用上面的公式多次迭代才能得到结果。初始时,可以设置每个网页的重要性为1。上面公式等号左边计算的结果是迭代后网页i的PR值,等号右边用到的PR值全是迭代前的。
举个例子:

上图表示了三张网页之间的链接关系,直觉上网页A最重要。可以得到下面的表:

   结束\起始 A B C
A 0 1 1
B 0 0 0
C 0 0 0

横栏代表其实的节点,纵栏代表结束的节点。若两个节点间有链接关系,对应的值为1。 
根据公式,需要将每一竖栏归一化(每个元素/元素之和),归一化的结果是: 

   结束\起始 A B C
A 0 1 1
B 0 0 0
C 0 0 0

上面的结果构成矩阵M。我们用matlab迭代100次看看最后每个网页的重要性:最终A的PR值为0.4050,B和C的PR值为0.1500。 如果把上面的有向边看作无向的(其实就是双向的),结果也是一样。 

TextRank

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

  • 如果一个单词出现在很多单词后面的话,那么说明这个单词比较重要
  • 一个TextRank值很高的单词后面跟着的一个单词,那么这个单词的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”加入关键词序列。

关于窗口的补充:

网页之间的链接关系可以用图表示,那么怎么把一个句子(可以看作词的序列)构建成图呢?TextRank将某一个词与其前面的N个词、以及后面的N个词均具有图相邻关系(类似于N-gram语法模型)。具体实现:设置一个长度为N的滑动窗口,所有在这个窗口之内的词都视作词结点的相邻结点;则TextRank构建的词图为无向图。下图给出了由一个文档构建的词图(去掉了停用词并按词性做了筛选):

网上别人的评估:

接下来将评估TextRank在关键词提取任务上的准确率、召回率与F1-Measure,并与TFIDF做对比;准确率计算公式如下:

测试集是由刘知远老师提供的网易新闻标注数据集,共有13702篇文档。Jieba完整地实现了关键词提取TFIDF与TextRank算法,基于Jieba-0.39的评估实验代码如下:

import jieba.analyse
import json
import codecsdef precision_recall_fscore_support(y_true, y_pred):"""evaluate macro precision, recall and f1-score."""doc_num = len(y_true)p_macro = 0.0r_macro = 0.0for i in range(doc_num):tp = 0true_len = len(y_true[i])pred_len = len(y_pred[i])for w in y_pred[i]:if w in y_true[i]:tp += 1if pred_len == 0:p = 1.0 if true_len == 0 else 0.0else:p = tp / pred_lenr = 1.0 if true_len == 0 else tp / true_lenp_macro += pr_macro += rp_macro /= doc_numr_macro /= doc_numreturn p_macro, r_macro, 2 * p_macro * r_macro / (p_macro + r_macro)file_path = 'data/163_chinese_news_dataset_2011.dat'
with codecs.open(file_path, 'r', 'utf-8') as fr:y_true = []y_pred = []for line in fr.readlines():d = json.loads(line)content = d['content']true_key_words = [w for w in set(d['tags'])]y_true.append(true_key_words)# for w in true_key_words:#     jieba.add_word(w)key_word_pos = ['x', 'ns', 'n', 'vn', 'v', 'l', 'j', 'nr', 'nrt', 'nt', 'nz', 'nrfg', 'm', 'i', 'an', 'f', 't','b', 'a', 'd', 'q', 's', 'z']extract_key_words = jieba.analyse.extract_tags(content, topK=2, allowPOS=key_word_pos)# trank = jieba.analyse.TextRank()# trank.span = 5# extract_key_words = trank.textrank(content, topK=2, allowPOS=key_word_pos)y_pred.append(extract_key_words)prf = precision_recall_fscore_support(y_true, y_pred)print('precision: {}'.format(prf[0]))print('recall: {}'.format(prf[1]))print('F1: {}'.format(prf[2]))

其中,每个文档提取的关键词数为2,并按词性做过滤;span表示TextRank算法中的滑动窗口的大小。评估结果如下:

方法 Precision Recall F1-Measure
TFIDF 0.2697 0.2256 0.2457
TextRank span=5 0.2608 0.2150 0.2357
TextRank span=7 0.2614 0.2155 0.2363

如果将标注关键词添加到自定义词典,则评估结果如下:

方法 Precision Recall F1-Measure
TFIDF 0.3145 0.2713 0.2913
TextRank span=5 0.2887 0.2442 0.2646
TextRank span=7 0.2903 0.2455 0.2660

直观感受下关键词提取结果(添加了自定义词典):

// TFIDF, TextRank, labelled
删了,好像命中审核逻辑,不通过了

从上述两组实验结果,可以发现:

  • TextRank与TFIDF均严重依赖于分词结果——如果某词在分词时被切分成了两个词,那么在做关键词提取时无法将两个词黏合在一起(TextRank有部分黏合效果,但需要这两个词均为关键词)。因此是否添加标注关键词进自定义词典,将会造成准确率、召回率大相径庭。
  • TextRank的效果并不优于TFIDF。
  • TextRank虽然考虑到了词之间的关系,但是仍然倾向于将频繁词作为关键词。

此外,由于TextRank涉及到构建词图及迭代计算,所以提取速度较慢。

系统学习NLP(二十一)--关键词提取算法总结相关推荐

  1. 系统学习NLP(十)--词性标注算法综述

    词性标注:将句子中兼类词的词性根据上下文唯一地确定下来.词性(part-of-speech)是词汇基本的语法属性,通常也称为词类.词性标注就是在给定句子中判定每个词的语法范畴,确定其词性并加以标注的过 ...

  2. 系统学习NLP(十一)--命名实体识别

    转自:https://www.cnblogs.com/bep-feijin/articles/9650898.html 命名实体识别(Named EntitiesRecognition, NER)是自 ...

  3. Unreal Engine 4 —— GAS系统学习 (二十一) 为主角添加技能图标

    欢迎大家加入Unreal Engine C++ & Blueprint群一起交流:1143575617 本节为主角的治疗技能添加上图标到插槽中. 先准备好技能图标,新建一个Material,按 ...

  4. KeyBert、TextRank等九种本文关键词提取算法(KPE)原理及代码实现

    关键词提取 (Keyphrase Extraction,KPE) 任务可以自动提取文档中能够概括核心内容的短语,有利于下游信息检索和 NLP 任务.当前,由于对文档进行标注需要耗费大量资源且缺乏大规模 ...

  5. TextRank关键词提取算法

    参考:百度AI Studio课程_学习成就梦想,AI遇见未来_AI课程 - 百度AI Studio - 人工智能学习与实训社区 (baidu.com) 1.关键词提取算法分类 1.有监督 将关键词提取 ...

  6. java 文本分析 关键词提取_文本关键词提取算法总结

    1.TF-IDF 昨天给大家演示简单的文本聚类,但要给每个聚类再提取一两个关键词用于表示该聚类.我们还是用TFIDF算法来做,因为这是比较简单的提取特征算法,不过这里的TF是指某词在本聚类内所有文章的 ...

  7. 基于TextRank的关键词提取算法

    基于TextRank的关键词提取算法 前沿 TextRank是一种文本排序算法,是基于著名的网页排序算法PageRank改动而来.在介绍TextRank前,我们先简单介绍下什么是PageRank.另外 ...

  8. 关键词提取算法—TF/IDF算法

    关键词提取算法一般可分为有监督学习和无监督学习两类. 有监督的关键词提取方法可以通过分类的方式进行,通过构建一个较为完善的词表,然后判断每个文档与词表中的每个词的匹配程度,以类似打标签的方式,达到关键 ...

  9. 广告行业中那些趣事系列60:详解超好用的无监督关键词提取算法Keybert

    导读:本文是"数据拾光者"专栏的第六十篇文章,这个系列将介绍在广告行业中自然语言处理和推荐系统实践.本篇从理论到实践介绍了超好用的无监督关键词提取算法Keybert,对于希望使用无 ...

  10. python3.4学习笔记(二十一) python实现指定字符串补全空格、前面填充0的方法

    python3.4学习笔记(二十一) python实现指定字符串补全空格.前面填充0的方法 Python zfill()方法返回指定长度的字符串,原字符串右对齐,前面填充0. zfill()方法语法: ...

最新文章

  1. 使用Vue.js初次真正项目开发-2018/07/14
  2. 如何深拷贝一个对象数组?
  3. android按钮点击变化,Android实现按钮点击效果(第一次点击变色,第二次恢复)...
  4. 账户配置 三: Gmail
  5. k8s容器内的东西复制出来_容器 | Docker 如此之好,你为什么还要用k8s
  6. linux raw格式改名img,4款Linux下的RAW格式图片编辑软件
  7. WinRAR 试用版曝漏洞:免费软件并不“免费“
  8. 下单延迟10s撤单性能测试
  9. spring中的ioc解决程序的耦合入门
  10. FLEX 与JAVA的LCDS BLAZEDS配置.
  11. 分享软件测试计划模板
  12. 操作系统之多道程序设计
  13. 艺电模拟城市开源代码读后感
  14. ios睡眠分析 卧床 睡眠_iPhone睡眠模式:教你设置追踪睡眠排程与提升睡眠品质...
  15. 设置计算机开机密码的步骤,电脑设置开机密码的方法
  16. 4g物联网模块dtu网络远程开关控制器485通讯 工业级TTL转4G串口服务器 全网通路由模块 通信通讯模组 二次开发
  17. JVM各内存区域存放内容
  18. 基于知识图谱的知识泛化让AI学会“举一反三”
  19. 适合学生党无线蓝牙耳机,好用又实惠蓝牙耳机推荐
  20. C 语言 —— 循环结构

热门文章

  1. 大学生创新课题项目管理系统
  2. 从零开始学ESP32:(四)ESP32/freeRTOS 实现一个内存池操作
  3. js给元素加html属性,js 如何给标签增加属性
  4. 【每日CSS】宽度自适应 width=100%还是width=auto?
  5. 小程序服务器换肤,微信小程序实现换肤功能
  6. Python|面向对象实例:银行卡类
  7. Java社会实践报告范文精选5篇
  8. 运维备忘录(持续完善)
  9. 让iphone可装android双启动,iPhone 4可安Android实现双系统启动
  10. 2006北京最佳烤鸭店