使用简单提取方法实现的文本摘要器
本文我们将使用一个非常简单但是可靠的提取方法来实现一个文本摘要器。
你有看到一些应用专门用来从一个文章或者新闻中提取出60字左右的摘要吗?比如inshorts。这样的效果就是我们这篇文章想实现的内容,我们将是用一个非常简单的提取方法来实现这个功能,不用担心,我会详细介绍什么是提取方法的。
其实有很多文章都介绍了文本摘要的实现,那么我们的文章有什么特点呢?那就是简单和易上手,我们会通过一些简单的代码片段来介绍这方面的内容。
文本摘要可以有两种实现的方法:
- 提取方法:从文章中找出n个最能够表达文章意思的句子,这个方法非常容易实现,并且也很容易理解。这也是为什么我会在这篇文章中使用这个方法。
- 抽象方法:这个方法使用了深度学习中的一些内容,比如编解码结构,长短期记忆LSTM(Long Short Term Memory)网络。而这些其实对新手来说很复杂且不容易理解。这个方法所产生的摘要,可能压根就不在文章中,甚至有可能产生完全没有意义的句子。
现在你理解了为什么我们选择提取方法了吧,让我们来看具体的代码吧:
要求:
我们假设你能够熟悉使用python,并且已经安装了python3。这个例子中使用的是jupyter notebook,当然你可以使用任何你想要的IDE。
需要安装的库:
这个项目你需要安装下面这些包。假如你还没有安装,你可以简单使用一下语句进行安装:pip install packgename,假如你使用的是本地的文件,那么html和xml相关的处理包可能就不需要安装了。
- bs4 – BeautifulSoup 是用来解析Html页面的。
- lxml – 这个包是用来使用python处理html和XML的。
- nltk – 用来处理自然语言相关的任务。
- urllib – 用来请求一个页面。(注:可能需要pip install requests)
开始编码:
首先我们需要引入这些我们需要的库,bs4和urllib是用来处理文章的。re(正则表达式)是用来移除文章中不需要的文本。第四行是用来安装nltk的。在这之后,我们就会下载一些文本处理过程中使用到的数据,比如punkt(用于句子的标志)以及stopwords(主要处理那些没有意义的词,比如is, the, of等等)。
import bs4 import urllib.request as url import re #!pip3 install nltk import nltk nltk.download('punkt') nltk.download('stopwords') from nltk import sent_tokenize from nltk.corpus import stopwords from nltk import word_tokenize stop_word = stopwords.words('english') import string
下面就是让用户来输入文章的url
url_name = input("Enter url of the text you want to summerize:")
下面的代码就是通过urllib来得到这个页面的内容,然后使用BeautifulSoup来解析这个页面,得到对应的段落部分,并且把它保存到变量article中。
web = url.urlopen(url_name) page = bs4.BeautifulSoup(web,'html.parser') elements = page.find_all('p') article = '' for i in elements: article+= (i.text) article
下面我们把article中的特殊字符进行一下处理,这里,我们就简单使用replace函数来替换,同时用正则表达式把数字也替换了。
processed = article.replace(r'^\s+|\s+?$','') processed = processed.replace('\n',' ') processed = processed.replace("\\",'') processed = processed.replace(",",'') processed = processed.replace('"','') processed = re.sub(r'\[[0-9]*\]','',processed) processed
下面我们使用nltk中的sent_tokenize函数来吧提取出文章中每一个句子,并保存在sentences中。
sentences = sent_tokenize(processed)
下面我们把文章中的所有字符都变成小写,然后我们遍历文章中所有的单词,并且确定他不是没有用的词或者标点符合(其实之前已经把标点处理了,这边再处理一遍,以防万一)。假如不是这些单词的话,我们就把相应的单词加入到一个字典中,并且计算相应的单词频率。
下面的截图中你可以看到,这个字典中包含了每个词出现的频率(出现频率越高,就意味着这个词越重要),现在你理解了为什么我们把一些没有意义的of, the, for 这些词去除了吧,因为他们肯定会是出现频率最高的词。
frequency = {} processed1 = processed.lower() for word in word_tokenize(processed1): if word not in stop_word and word not in string.punctuation: if word not in frequency.keys(): frequency[word]=1 else: frequency[word]+=1 frequency
现在我们已经通过单词出现的频率简单的计算了每一个单词的重要性,从上图你可以看出来,language是最重要的词,因为他出现的频率最高,是22.
max_fre = max(frequency.values()) for word in frequency.keys(): frequency[word]=(frequency[word]/max_fre) frequency
下面,我们就能计算每一句话的重要性。我们遍历每一句话,然后把这句话中单词的的分数加起来,就是这句话的分数。
从上面的截图你可以看出,现在,每一句话都已经有了一个分数来表示他们的重要性。
sentence_score = {} for sent in sentences: for word in word_tokenize(sent): if word in frequency.keys(): if len(sent.split(' '))<30: if sent not in sentence_score.keys(): sentence_score[sent] = frequency[word] else: sentence_score[sent]+=frequency[word] sentence_score
最后,我们使用heapq来找到最高分的四个句子,你可以选择任意数目的句子,现在就简单把这些选择的句子聚集中一起安装字符串输出。
最后的这篇“Natural language Processing”的输入如下所示:
import heapq summary = heapq.nlargest(4,sentence_score,key = sentence_score.get) summary = ' '.join(summary) final = "SUMMARY:- \n " +summary textfinal = 'TEXT:- '+processed textfinal = textfinal.encode('ascii','ignore') textfinal = str(textfinal) Final
好了,我们完成了!恭喜你!
虽然说提取总结并不是最好的方法,但是对于总结一个文章的主要观点还是足够的。而且,他很可靠,因为他只是输出文章中相关数目的句子,而不是去自己创造一个新的句子。
下次也许我们就可以讨论讨论抽象方法了提取总结了,下次见!
原文地址:https://dzone.com/articles/simple-text-summarizer-using-extractive-method
Recent Comments