1、文本摘要提取
文本摘要可以大致分为两类——抽取型摘要和抽象型摘要:
- 抽取型摘要:这种方法依赖于从文本中提取几个部分,例如短语、句子,把它们堆叠起来创建摘要。因此,这种抽取型的方法最重要的是识别出适合总结文本的句子。
- 抽象型摘要:这种方法应用先进的NLP技术生成一篇全新的总结。可能总结中的文本甚至没有在原文中出现。
这里我们使用的Textrank算法就是抽取型摘要。
2、PageRank原理
谷歌的两位创始人的佩奇和布林,借鉴了学术界评判学术论文重要性的通用方法,“那就是看论文的引用次数”。由此想到网页的重要性也可以根据这种方法来评价。
- 如果一个网页被很多其他网页链接到的话说明这个网页比较重要,也就是PageRank值会相对较高
- 如果一个PageRank值很高的网页链接到一个其他的网页,那么被链接到的网页的PageRank值会相应地因此而提高
PageRank算法也是基于图的,每个网页可以看作是一个图中的结点,如果网页A能够跳转到网页B,那么则有一条A->B的有向边。这样,我们就可以构造出一个有向图了。
利用公式:
经过多次迭代就可以获得每个网页对应的权重。下面解释公式每个元素的含义:
3、TextRank原理
这里和PageRank算法一样,不过是将网页换成句子、词汇、字,吸取n-gram算法的精髓,我们只建立某个词和前后n个词之间的联系。简单来说,某个单词,只与它附近的n个单词有关,即与它附近的n个词对应的结点连一条无向边(两个有向边),除此之外还可删除某些词性的词、停用词、自定义的一些词
如下是一篇文章的TextRank结果:
构图成功即可使用上述公式求解
- 提取关键词以单词为结点
- 提取文章摘要自然就是以句子为结点了,但是对于边,即使是相邻的两个句子也可以讲不同的故事
论文中计算两个句子相似度的公式如下:
其他计算相似度的方法应该也是可行的,比如余弦相似度,最长公共子序列之类的,不过论文里一笔带过了。这里使用log我觉得是希望分母变小,相似度增大便于比较,由于使用了带权的边,因此参考PageRank的公式也要进行相应的修改,具体公式如下:
对比于 下面PageRank的公式,这里TextRank添加了权值参数也是可以理解的
最后说明TextRank不需要训练,直接使用数据即可,但是我觉得训练其实在切词等之前的准备工作中就完成了,具体可做如下工作:
- 文章摘要提取
- 关键词提取
评价体系是rouge,rouge是根据召回率改的,就是多少正确结果被找出来了,这里也就是:
- 系统算法生成的摘要与参考摘要相同的N-gram数/参考摘要中的N-gram总数
以下是 rouge 的计算方法:
4、基于TextRank的关键词提取代码实现
代码API讲解:
- jieba.analyse.textrank(sentence, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v')) 直接使用,接口相同,注意默认过滤词性。
- jieba.analyse.TextRank() 新建自定义 TextRank 实例
基本思想:
- 将待抽取关键词的文本进行分词
- 以固定窗口大小(默认为5,通过span属性调整),词之间的共现关系,构建图
- 计算图中节点的PageRank,注意是无向带权图
s = "此外,公司拟对全资子公司吉林欧亚置业有限公司增资4.3亿元,增资后,吉林欧亚置业注册资本由7000万元增加到5亿元。吉林欧亚置业主要经营范围为房地产开发及百货零售等业务。目前在建吉林欧亚城市商业综合体项目。2013年,实现营业收入0万元,实现净利润-139.13万元。"
print('='*40+'\n'+' TextRank'+'\n'+'-'*40)
for x, w in jieba.analyse.textrank(s, topK= 5, withWeight=True):
print('%s %s' % (x, w))
"""
吉林 1.0
欧亚 0.9966893354178172
置业 0.6434360313092776
实现 0.5898606692859626
收入 0.43677859947991454
"""
5、词性标注
jieba.posseg.POSTokenizer(tokenizer=None)
新建自定义分词器,tokenizer
参数可指定内部使用的jieba.Tokenizer
分词器。jieba.posseg.dt
为默认词性标注分词器。- 标注句子分词后每个词的词性,采用和 ictclas 兼容的标记法。ictclas----中文词法分析是中文信息处理的基础与关键。中国科学院计算技术研究所在多年研究工作积累的基础上,研制出了汉语词法分析系统ictclas,具体词性有哪些可参考我的博客
import jieba.posseg
print('='*40+'\n'+'4. 词性标注'+'\n'+'-'*40)
words = jieba.posseg.cut("我是真的爱北京天安门")
for word, flag in words:
print('%s %s' % (word, flag))
"""
我 r
是 v
真的 d
爱 v
北京 ns
天安门 ns
# 这里不完全兼容ictclas,因为是在ictclas中标注为vshi
"""
6、并行分词
- 原理:将目标文本按行分隔后,把各行文本分配到多个 Python 进程并行分词,然后归并结果,从而获得分词速度的可观提升
- 基于 python 自带的 multiprocessing 模块,目前暂不支持 Windows
- 用法:
jieba.enable_parallel(4)
# 开启并行分词模式,参数为并行进程数-
jieba.disable_parallel()
# 关闭并行分词模式 - 实验结果:在 4 核 3.4GHz Linux 机器上,对金庸全集进行精确分词,获得了 1MB/s 的速度,是单进程版的 3.3 倍
- 注意:并行分词仅支持默认分词器
jieba.dt
和jieba.posseg.dt
。
7、剩余功能包括返回分词在原句中的起始位置、命令行分词、搜索引擎三个功能不介绍了,如有需求自行查看https://github.com/fxsjy/jieba