变身抓重点小能手:机器学习中的文本摘要入门指南 | 资源

2019 年 4 月 22 日 量子位
鱼羊 编译整理
量子位 出品 | 公众号 QbitAI

如果你是科研狗,一定有过被摘要支配的恐惧。

如果你想在浩如烟海的互联网信息里寻找重点,一定想要快速排除多余的内容。

基于机器学习的自动文本摘要工具,将一键解放你的双手,化身抓重点小能手,为你捕捉关键,排除冗余。

近日,有位叫Alfrick Opidi的小哥在入门级深度学习云平台FloydHub 上写了一篇关于自动文本摘要的入门教程,量子位对其进行了编译,希望能帮助大家理解。

自动文本摘要属于自然语言处理(NLP)的范畴,通常用机器学习算法来实现,目前实现的方法主要有两种:

抽取式

就像一支荧光笔,抽取式文本摘要就是给原始文本中的重点单词标上高亮,再将其加以组合形成摘要。

概要式

概要式文本摘要更接近于人类的思维——通过深度学习对原始文本进行释义并提炼主旨,而后形成摘要。相比于抽取式,概要式文本摘要更像在说人话。

很显然概要式的表现会比抽取式更好,然而这种算法需要复杂的深度学习技术和语言模型支撑,还面临这诸如自然语言生成这样的NLP问题。

因此抽取式方法仍然广泛流行。

鉴于本文是一篇入门指南,接下来提到的内容都是基于抽取式方法来实现的。

文本摘要基础步骤

文本摘要是如何实现的呢?

举个例子,用文本摘要机器学习算法来对下面这段文字进行处理:

夜里志明和春娇乘坐出租车去城里聚会。聚会上春娇晕倒并被送进了医院。她被诊断出患有脑损伤,医生告诉志明要一直陪着她直到她好起来。因此,志明待在医院整整陪了她三天。

第一步:把段落转成句子

首先要做的是分割段落。

  1. 夜里志明和春娇乘坐出租车去城里聚会

  2. 聚会上春娇晕倒并被送进了医院

  3. 她被诊断出患有脑损伤,医生告诉志明要一直陪着她直到她好起来

  4. 因此,志明待在医院整整陪了她三天

第二步:文本处理

接下来,删掉没什么意义的连接词、数字、标点。

就像这样:

  1. 夜里志明春娇乘坐出租车去城里聚会

  2. 聚会春娇晕倒送医院

  3. 诊断脑损伤医生告诉志明陪着好起来

  4. 志明待在医院天

第三步:标注

然后,对句子进行标记,获得句子中的所有单词:

[‘志明’,‘春娇’,‘乘坐’,‘出租车’,‘去’,‘夜里’,‘聚会’,‘城里‘,‘聚会’,‘春娇’,‘晕倒’,‘医院’,‘诊断’,‘脑’,‘损伤’,‘医生’,‘告诉’,‘志明’,‘陪’,‘好起来’,‘志明’,‘待’,‘医院’,‘天’]

第四步:评估单词的加权出现频率

现在就可以计算单词们的加权出现频率了。

计算公式是:单词加权出现频率 = 单词出现次数 / 段落中最常用单词出现次数

第五步:用加权频率替换单词

把句子中的每个单词都替换成加权频率,就可以计算这个句子的权重。比如在志明和春娇这个例子当中,第一句在整个段落中的权重是最大的,那么它就将构成摘要的主体部分。

以上是机器学习实现文本摘要的基本步骤,下面我们来看看如何在真实世界中构建摘要生成器。

亲手构建摘要生成器

使用Python的NLTK工具包,我们可以亲自动手创造一个文本摘要生成器,实现对Web文章的摘要生成。

来看看代码蓝图:

 1# Creating a dictionary for the word frequency table
2frequency_table = _create_dictionary_table(article)
3
4# Tokenizing the sentences
5sentences = sent_tokenize(article)
6
7# Algorithm for scoring a sentence by its words
8sentence_scores = _calculate_sentence_scores(sentences, frequency_table)
9
10# Getting the threshold
11threshold = _calculate_average_score(sentence_scores)
12
13# Producing the summary
14article_summary = _get_article_summary(sentences, sentence_scores, 1.5 * threshold)
15
16print(article_summary)

第一步:准备数据

这里使用了Beautiful Soup库。

 1import bs4 as BeautifulSoup
2import urllib.request  
3
4# Fetching the content from the URL
5fetched_data = urllib.request.urlopen('https://en.wikipedia.org/wiki/20th_century')
6
7article_read = fetched_data.read()
8
9# Parsing the URL content and storing in a variable
10article_parsed = BeautifulSoup.BeautifulSoup(article_read,'html.parser')
11
12# Returning <p> tags
13paragraphs = article_parsed.find_all('p')
14
15article_content = ''
16
17# Looping through the paragraphs and adding them to the variable
18for p in paragraphs:  
19    article_content += p.text

使用urllib.request实现网页数据的抓取,再调用BeautifulSoup来解析网页数据。

第二步:数据处理

为确保抓取到的文本数据尽可能没有噪音,需要做一些基本的文本清理。这里使用了NLTKstopwordsPorterStemmer

PorterStemmer可以将单词还原为词根形式,就是说能把 cleaning, cleaned, cleaner 都还原成 clean。

此外还要创建一个字典,来存储文本中每一个单词的出现频率。
循环整个文本来消除 “a”、“the” 这样的停止词,并记录单词们的出现频率。

 1from nltk.corpus import stopwords
2from nltk.stem import PorterStemmer
3def _create_dictionary_table(text_string) -> dict:
4
5    # Removing stop words
6    stop_words = set(stopwords.words("english"))
7
8    words = word_tokenize(text_string)
9
10    # Reducing words to their root form
11    stem = PorterStemmer()
12
13    # Creating dictionary for the word frequency table
14    frequency_table = dict()
15    for wd in words:
16        wd = stem.stem(wd)
17        if wd in stop_words:
18            continue
19        if wd in frequency_table:
20            frequency_table[wd] += 1
21        else:
22            frequency_table[wd] = 1
23
24    return frequency_table

第三步:将文章标注成句子

1from nltk.tokenize import word_tokenize, sent_tokenize
2
3sentences = sent_tokenize(article)

第四步:计算句子的权重

句子的权重取决于它包含的单词的出现频率。

 1def _calculate_sentence_scores(sentences, frequency_table) -> dict:   
2
3    # Algorithm for scoring a sentence by its words
4    sentence_weight = dict()
5
6    for sentence in sentences:
7        sentence_wordcount = (len(word_tokenize(sentence)))
8        sentence_wordcount_without_stop_words = 0
9        for word_weight in frequency_table:
10            if word_weight in sentence.lower():
11                sentence_wordcount_without_stop_words += 1
12                if sentence[:7in sentence_weight:
13                    sentence_weight[sentence[:7]] += frequency_table[word_weight]
14                else:
15                    sentence_weight[sentence[:7]] = frequency_table[word_weight]
16
17        sentence_weight[sentence[:7]] = sentence_weight[sentence[:7]] /        sentence_wordcount_without_stop_words
18
19    return sentence_weight

需要注意的是,长句有可能得到不必要的高分,为了避免这一点,要将句子的总分数除以该句的单词数

第五步:计算句子的阈值

为了进一步优化结果,要计算句子的平均分数。使用此阈值,可以避免分数较低的句子的干扰。

 1def _calculate_average_score(sentence_weight) -> int:
2
3    # Calculating the average score for the sentences
4    sum_values = 0
5    for entry in sentence_weight:
6        sum_values += sentence_weight[entry]
7
8    # Getting sentence average value from source text
9    average_score = (sum_values / len(sentence_weight))
10
11    return average_score

如果感兴趣,FloydHub提供了进行深度学习模型训练的环境,你可以在FloydHub Notebook上运行整个代码。

还可以更上档次

以上只是机器学习中文本摘要算法的入门小知识,想要达到更上档次的效果,甚至可以把抽取式方法和概要式方法结合起来。

图片来自Taming Recurrent Neural Networks for Better Summarization

传送门

如果还想更深入地了解机器学习中的文本摘要,不妨看看以下资源。

WikiHow,一个大规模、高质量的文本摘要数据集:
https://www.wikihow.com/Main-Page

WikiHow食用指南:
https://arxiv.org/pdf/1810.09305.pdf

用指针生成网络(Pointer-Generator Networks)实现文本摘要:
https://arxiv.org/pdf/1704.04368.pdf
http://www.abigailsee.com/2017/04/16/taming-rnns-for-better-summarization.html

如何在文本摘要中使用基于预训练的编码器-解码器框架:
https://arxiv.org/pdf/1902.09243.pdf

原文链接:
https://blog.floydhub.com/gentle-introduction-to-text-summarization-in-machine-learning/

订阅AI内参,获取AI行业资讯

加入社群

量子位AI社群开始招募啦,量子位社群分:AI讨论群、AI+行业群、AI技术群;


欢迎对AI感兴趣的同学,在量子位公众号(QbitAI)对话界面回复关键字“微信群”,获取入群方式。(技术群与AI+行业群需经过审核,审核较严,敬请谅解)

诚挚招聘

量子位正在招募编辑/记者,工作地点在北京中关村。期待有才气、有热情的同学加入我们!相关细节,请在量子位公众号(QbitAI)对话界面,回复“招聘”两个字。

量子位 QbitAI · 头条号签约作者

վ'ᴗ' ի 追踪AI技术和产品新动态

喜欢就点「好看」吧 !

登录查看更多
1

相关内容

一份简明有趣的Python学习教程,42页pdf
专知会员服务
76+阅读 · 2020年6月22日
专知会员服务
155+阅读 · 2020年4月21日
【干货书】机器学习Python实战教程,366页pdf
专知会员服务
338+阅读 · 2020年3月17日
谷歌机器学习速成课程中文版pdf
专知会员服务
145+阅读 · 2019年12月4日
【机器学习课程】Google机器学习速成课程
专知会员服务
164+阅读 · 2019年12月2日
【开源书】PyTorch深度学习起步,零基础入门(附pdf下载)
专知会员服务
110+阅读 · 2019年10月26日
学习自然语言处理路线图
专知会员服务
137+阅读 · 2019年9月24日
赛尔原创 | 文本摘要简述
哈工大SCIR
22+阅读 · 2019年3月25日
中文自然语言处理入门实战
人工智能头条
16+阅读 · 2019年1月11日
资源 | Python 中文书籍大集合
AI研习社
13+阅读 · 2018年12月20日
机器学习各种熵:从入门到全面掌握
AI研习社
10+阅读 · 2018年3月22日
一文学会最常见的10种NLP处理技术(附资源&代码)
如何入门Python与机器学习 | 赠书
CSDN大数据
9+阅读 · 2017年11月12日
机器学习必备手册
机器学习研究会
19+阅读 · 2017年10月24日
Python 自然语言处理(NLP)工具库汇总
数据挖掘入门与实战
7+阅读 · 2017年9月25日
NLP自然语言处理(二)——基础文本分析
乐享数据DataScientists
12+阅读 · 2017年2月7日
Tutorial on NLP-Inspired Network Embedding
Arxiv
7+阅读 · 2019年10月16日
Arxiv
3+阅读 · 2019年9月5日
Arxiv
3+阅读 · 2018年5月28日
VIP会员
相关VIP内容
一份简明有趣的Python学习教程,42页pdf
专知会员服务
76+阅读 · 2020年6月22日
专知会员服务
155+阅读 · 2020年4月21日
【干货书】机器学习Python实战教程,366页pdf
专知会员服务
338+阅读 · 2020年3月17日
谷歌机器学习速成课程中文版pdf
专知会员服务
145+阅读 · 2019年12月4日
【机器学习课程】Google机器学习速成课程
专知会员服务
164+阅读 · 2019年12月2日
【开源书】PyTorch深度学习起步,零基础入门(附pdf下载)
专知会员服务
110+阅读 · 2019年10月26日
学习自然语言处理路线图
专知会员服务
137+阅读 · 2019年9月24日
相关资讯
赛尔原创 | 文本摘要简述
哈工大SCIR
22+阅读 · 2019年3月25日
中文自然语言处理入门实战
人工智能头条
16+阅读 · 2019年1月11日
资源 | Python 中文书籍大集合
AI研习社
13+阅读 · 2018年12月20日
机器学习各种熵:从入门到全面掌握
AI研习社
10+阅读 · 2018年3月22日
一文学会最常见的10种NLP处理技术(附资源&代码)
如何入门Python与机器学习 | 赠书
CSDN大数据
9+阅读 · 2017年11月12日
机器学习必备手册
机器学习研究会
19+阅读 · 2017年10月24日
Python 自然语言处理(NLP)工具库汇总
数据挖掘入门与实战
7+阅读 · 2017年9月25日
NLP自然语言处理(二)——基础文本分析
乐享数据DataScientists
12+阅读 · 2017年2月7日
Top
微信扫码咨询专知VIP会员