文本摘要方法

  • 早在20世纪50年代,自动文本摘要已经吸引了人们的关注。在20世纪50年代后期,Hans Peter Luhn发表了一篇名为《The automatic creation of literature abstract》的研究论文,它利用词频和词组频率等特征从文本中提取重要句子,用于总结内容。
  • 由Harold P Edmundson在20世纪60年代后期完成,他使用线索词的出现(文本中出现的文章题目中的词语)和句子的位置等方法来提取重要句子用于文本摘要。此后,许多重要和令人兴奋的研究已经发表,以解决自动文本摘要的挑战。

文本摘要可以大致分为两类——抽取型摘要和抽象型摘要:

  • 抽取型摘要:这种方法依赖于从文本中提取几个部分,例如短语、句子,把它们堆叠起来创建摘要。因此,这种抽取型的方法最重要的是识别出适合总结文本的句子。
  • 抽象型摘要:这种方法应用先进的NLP技术生成一篇全新的总结。可能总结中的文本甚至没有在原文中出现。

相关知识–PageRank算法

PageRank算法启发了TextRank,PageRank主要用于对在线搜索结果中的网页进行排序,通过计算网页链接的数量和质量来粗略估计网页的重要性。
PageRank对于每个网页页面都给出一个正实数,表示网页的重要程度,PageRank值越高,表示网页越重要,在互联网搜索的排序中越可能被排在前面。

抽取型文本摘要算法TextRank

  • TextRank算法是一种基于图的用于关键词抽取和文档摘要的排序算法,由谷歌的网页重要性排序算法PageRank算法改进而来,它利用一篇文档内部的词语间的共现信息(语义)便可以抽取关键词,它能够从一个给定的文本中抽取出该文本的关键词、关键词组,并使用抽取式的自动文摘方法抽取出该文本的关键句。通过把文本分割成若干组成单元(句子),构建节点连接图,用句子之间的相似度作为边的权重,通过循环迭代计算句子的TextRank值,最后抽取排名高的句子组合成文本摘要。

  • 用TextRank提取来提取关键词,用PageRank的思想来解释它:
    如果一个单词出现在很多单词后面的话,那么说明这个单词比较重要
    一个TextRank值很高的单词后面跟着的一个单词,那么这个单词的TextRank值会相应地因此而提高

  1. 第一步是把所有文章整合成文本数据
  2. 接下来把文本分割成单个句子
  3. 然后,我们将为每个句子找到向量表示(词向量)。
  4. 计算句子向量间的相似性并存放在矩阵中
  5. 然后将相似矩阵转换为以句子为节点、相似性得分为边的图结构,用于句子TextRank计算。
  6. 最后,一定数量的排名最高的句子构成最后的摘要。

源码

主调函数是TextRank.textrank函数,主要是在jieba/analyse/textrank.py中实现。

#!/usr/bin/env python
# -*- coding: utf-8 -*-from __future__ import absolute_import, unicode_literals
import sys
from operator import itemgetter
from collections import defaultdict
import jieba.posseg
from .tfidf import KeywordExtractor
from .._compat import *class UndirectWeightedGraph:d = 0.85def __init__(self):#初始化函数self.graph = defaultdict(list)#这是进行分词后的一个词典def addEdge(self, start, end, weight):#添加边的函数# use a tuple (start, end, weight) instead of a Edge object#无向有权图添加边的操作是在addEdge函数中完成的,因为是无向图,所以我们需要依次将start作为起 始点,end作为终止点,然后再将start作为终止点,end作为起始点,这两条边的权重是相同的。self.graph[start].append((start, end, weight))self.graph[end].append((end, start, weight))def rank(self):#对结点权值和节点出度之和分别定义了一个字典ws = defaultdict(float)#权值list表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)#e[2]是什么?# 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 wsclass TextRank(KeywordExtractor):def __init__(self):#初始化时,默认加载分词函数tokenizer = jieba.dt以及词性标注工具jieba.posseg.dt,停用词stop_words = self.STOP_WORDS.copy(),#词性过滤集合pos_filt = frozenset(('ns', 'n', 'vn', 'v')),窗口span = 5,(("ns", "n", "vn", "v"))表示词性为地名、名词、动名词、动词。self.tokenizer = self.postokenizer = jieba.posseg.dtself.stop_words = self.STOP_WORDS.copy()self.pos_filt = frozenset(('ns', 'n', 'vn', 'v'))self.span = 5def pairfilter(self, wp):return (wp.flag in self.pos_filt and len(wp.word.strip()) >= 2and wp.word.lower() not in self.stop_words)def textrank(self, sentence, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v'), withFlag=False):"""Extract keywords from sentence using TextRank algorithm.Parameter:- topK: return how many top keywords. `None` for all possible words.- withWeight: if True, return a list of (word, weight);if False, return a list of words.- allowPOS: the allowed POS list eg. ['ns', 'n', 'vn', 'v'].if the POS of w is not in this list, it will be filtered.- withFlag: if True, return a list of pair(word, weight) like posseg.cutif False, return a list of words"""# frozenset()函数的含义是:返回一个冻结的集合,冻结后集合不能再添加或删除任何元素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 tagsextract_tags = textrank```

函数:jieba.analyse.textrank(string, topK=20, withWeight=True, allowPOS=())
string:待处理语句
topK:关键字的个数,重要性从高到低排序,默认20
withWeight:是否返回权重值,默认false
allowPOS:词性过滤,是否仅返回指定类型,默认为空,为空表示不过滤,若提供则仅返回符合词性要求的关键词,allowPOS(‘ns’, ‘n’, ‘vn’, ‘v’) 地名、名词、动名词、动词

# 导入文件并分词
def lcut(Intro_movie):segment=[]segs = jieba.lcut(Intro_movie) # jiaba.lcut()   for seg in segs:if len(seg)>1 and seg!='\r\n':segment.append(seg)return segment#去停用词
def dropstopword(segment):words_df = pd.DataFrame({'segment':segment})stopwords = pd.read_csv("../movie_sentiment/stopwords.txt" ,index_col=False,quoting=3,sep="\t",names=['stopword'],encoding='utf-8') # quoting=3 全不引用    return words_df[~words_df.segment.isin(stopwords.stopword)].segment.values.tolist()# 基于TextRank算法的关键词抽取(仅动词和动名词)
import jieba.analyse as analysedata_item['keywords'] = data_item.intro.apply(lcut)\.apply(dropstopword)\.apply(lambda x : " ".join(x))\.apply(lambda x:" ".join(analyse.textrank(x, topK=8, withWeight=False, allowPOS=('n','ns','vn', 'v'))))
data_item.sort_values('rating_num', ascending=False)[['movie_id','movie_title','keywords']].head(20)

应用

  • 和 LDA、HMM 等模型不同, TextRank不需要事先对多篇文档进行学习训练, 因其简洁有效而得到广泛应用。
  • 在多篇单领域文本数据中抽取句子组成摘要
  • TextRank算法有jieba分词和TextRank4zh这2个开源库的写法,但是两者无论写法和运算规则都有很大出入,结合公式来说jieba做的更符合公式,TextRank4zh更具有准确性,因为TextRank4zh在公式上面做了一定的优化。

基于Jieba的TextRank算法实现:

  1. 对每个句子进行分词词性标注处理;
  2. 过滤掉除指定词性外的其他单词,过滤掉出现在停用词表的单词,过滤掉长度小于2的单词;
  3. 将剩下的单词中循环选择一个单词,将其与其后面4个单词分别组合成4条边
  4. 构建出候选关键词图G=(V,E),把2个单词组成的边,和其权值记录了下来;
  5. 套用TextRank的公式,迭代传播各节点的权值,直至收敛;
  6. 对结果中的Rank值进行倒序排序,筛选出前面的几个单词,就是需要的关键词

参考文献
独家 | 基于TextRank算法的文本摘要(附Python代码)
TextRank算法原理简析、代码实现
TextRank源码的学习与详细解析

自然语言处理NLP--TextRank算法相关推荐

  1. 【自然语言处理】TextRank算法

    TextRank算法 TextRank算法基于PageRank,用于为文本生成关键字和摘要.其论文是:  Mihalcea R, Tarau P. TextRank: Bringing order i ...

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

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

  3. 自然语言处理(NLP)任务中常用的分词工具及底层算法支持

    刚刚和一个在三快在线(美团)的算法老同学聊天,聊到了他们现有分词工具效果不好的问题,我们最终讨论的结果就是没有效果好或者效果不好之后,只有适合不适合,归根结底还是要看各个分词工具中模型的基础训练数据成 ...

  4. Interview之NLP:人工智能领域求职岗位—自然语言处理NLP算法工程师职位的简介、薪资介绍、知识结构之详细攻略

    Interview之NLP:人工智能领域求职岗位-自然语言处理NLP算法工程师职位的简介.薪资介绍.知识结构之详细攻略 目录 自然语言处理NLP算法工程师的职位简介 1.资讯指数 2.各大公司的具体职 ...

  5. 自然语言处理NLP星空智能对话机器人系列:第21章:基于Bayesian Theory的MRC文本理解基础经典模型算法详解

    自然语言处理NLP星空智能对话机器人系列: 第21章:基于Bayesian Theory的MRC文本理解基础经典模型算法详解 1,Bayesian prior在模型训练时候对Weight控制.训练速度 ...

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

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

  7. 独家 | 基于TextRank算法的文本摘要(附Python代码)

    作者:Prateek Joshi 翻译:王威力 校对:丁楠雅 本文约3300字,建议阅读10分钟. 本文介绍TextRank算法及其在多篇单领域文本数据中抽取句子组成摘要中的应用. TextRank ...

  8. 语义模型及自然语言处理系统基础算法

    语义模型常用算法及详解 1.1 关键词抽取的算法模型 (1)TF-IDF (2)TextRank (3)基于语义的统计语言实现关键词抽取 1.2 短语抽取的算法模型 (1)基于互信息和左右信息熵算法实 ...

  9. 自然语言处理NLP中文分词,词性标注,关键词提取和文本摘要

    NLP相关工具包的介绍 1.1 jieba "结巴"中文分词,理念是做最好的 Python 中文分词组件. 支持三种分词模式: (1)精确模式,试图将句子最精确地切开,适合文本分析 ...

  10. 使用TextRank算法进行文本摘要提取(python代码)

    文本摘要是自然语言处理(NLP)的一种应用,随着人工智能的发展文本提取必将对我们的生活产生巨大的影响.随着网络的发展我们处在一个信息爆炸的时代,通读每天更新的海量文章/文档/书籍会占用我们大量的时间, ...

最新文章

  1. 云机搭jdk1.8和apache-tomcat
  2. 有关可变形部件模型(Deformable Part Model)的一些说明
  3. Jenkins学习七:Jenkins的授权和访问控制
  4. 趣谈设计模式 | 适配器模式(Adapter):如何让现存对象适用于新的环境?
  5. rh9.0虚拟机dmesg启动过程分析(1)
  6. 厦门大学计算机考研怎么样6,【图片】一战厦大计算机上岸,经验帖。慢更【考研吧】_百度贴吧...
  7. i2c-toos 交互数据_什么是CD-i(交互式光盘)?
  8. 坑爹的水题之“元芳你怎么看”
  9. 计算机二级晓云是企业人力,全国计算机二级MsOffice真题试卷wore
  10. 那些高曝光的Annotation(@ComponentScan、@PropertySource与@PropertySources、@Import与ImportResource)
  11. 用CSS3写圆角(超简单)
  12. HTTP协议基本原理简介(一)
  13. Mobicents记录1:如何搭建和运行mobicents3.0环境(基于jboss7.2)
  14. 俄罗斯方块英文JAVA版下载_俄罗斯方块java源代码完美版
  15. 波段高低点指标公式 k线高低点 大盘主图公式源码
  16. Storage System
  17. wifi又被隔壁老王蹭了,这样设置路由器,老王再也蹭不了你的wifi了……路由器设置实用教程基础篇
  18. 前端批量打包下载图片_个人总结 _@jie
  19. 如何评价微软在数据中心使用FPGA代替传统CPU的做法?
  20. React-native 开启DEBUG模式后应用闪退

热门文章

  1. AUTOIT 3.0 基本语法:参考中文文档
  2. 彻底丢失的电子数据怎么恢复
  3. 揭秘:恒生电子到底是干什么的
  4. ubuntu美化桌面
  5. JS__this,arguments,克隆,三目运算符__渡一
  6. mysql获取多层嵌套json_提取多层嵌套Json数据
  7. python如果文件存在就删除_python--文件删除、判断目录存在、字符串替换
  8. 读《万历十五年》和《一个广告人的自白》
  9. 函数stdlib.h应用举例
  10. 你需要知道的那些go语言json技巧