作者头像

使用Python和GloVe词嵌入模型提取新闻和文章的文本摘要

文章摘要是一个简短的段落,其中包含要点,并以文章本身使用的词语来表达。通常,我们仅提取那些我们认为最重要的要素/句子,这些要素/句子通常传达主要思想或必要的支撑点。

摘要不是文章的分析,摘要和分析是不同的东西。摘要在很多情况下很有用,例如,获得一篇篇幅较大的文章的要点,用通俗单词介绍一个复杂的想法,从篇幅较大的文章中获得启发等。

在学术上,提取摘要是一项具有挑战性的任务。值得庆幸的是,机器学习出现了。机器学习的自然语言处理(NLP)模块提供了许多可用于文本摘要的算法。文本摘要有两种主要方法:

创建抽象式摘要:
该技术使用高级的NLP方法来生成摘要,该摘要所使用的单词句子是全新的。这意昧着,摘要是用文章中未使用的词创建的。
创建提取式摘要:
在这种技术中,最重要的单词句子被提取出来一起组建一个摘要。显而易见,摘要中使用的单词句子来自文章本身。

在本文中,我们将使用提取技术从大型新闻文章中提取4-5个重要的重要句子构建新闻简报。 我们将使用一些流行和有效的策略来处理大量文本并从中提取4-5个有意义的句子。

我们将使用全局向量(也称为GloVe算法),它是单词的向量表示。用外行的话来说,我们将使用GloVe算法生成句子向量,并选择每页排名中最重要的句子。事不宜迟,让我们深入研究代码。我在此练习中使用了python。

处理新闻RSS摘要

我选择研究TimeOfIndia的RSS频道,该公司是印度最受欢迎的新闻服务之一。在本练习中,我选择了新闻的“world”部分。但是代码比较灵活,可以处理各种新闻服务的多个RSS频道。

让我们阅读RSS频道,并将新闻的链接传递到BeautifulSoup进行HTML解析。请注意,这里我仅采用了一个RSS频道,并逐步进行解析。稍后,我将这些步骤结合在一起以完美处理多个频道。

# import basic required libraries
import pandas as pd
import numpy as np
import os # for web and HTML
import requests
from bs4 import BeautifulSoup# create a dict of various 

RSS feed link and their categories. Will iterate them one by one.
# Have mentioned only one feed for demo purposes
timesofindia = {'world':'http://timesofindia.indiatimes.com/rssfeeds/296589292.cms'}
for category, rsslink in timesofindia.items():
    print('Processing for category: {0}. \nRSS link: {1}'.format(category,rsslink))
    # get the webpage URL and read the html
    rssdata = requests.get(rsslink)
    #print(rssdata.content)
    soup = BeautifulSoup(rssdata.content)
    print(soup.prettify())

在BeautifulSoup解析之后,我们应该彻底检查了网页的HTML内容(通过使用如上所述的pretifiy函数),然后找到标签/样式或标签序列以进行导航,进而获取所需的新闻标题,链接和pubDate。在我们的例子中,这些元素在“item" 标签内。因此,让我们提取“item",然后遍历每个“item” 标签并提取每个单独的元索。

# get all news items. It has title, description, link, guid, pubdate for each news items. 
# Lets call this items and we will iterate thru it
allitems = soup.find_all('item')# print one news item/healine to check
for item in range(len(allitems)):
    print('Processing news-item #:',item)
    title = allitems[item].title.text
    link = allitems[item].guid.text
    pubdate = allitems[item].pubdate.text
    print('TITLE:',title)
    print('LINK:',link)
    print('PUBDATE:',pubdate)

输出:

Total news items found: 20
TITLE: Boris Johnson's pregnant fiancee says she is 'on the mend' from coronavirus
LINK: https://timesofindia.indiatimes.com/world/....
PUBDATE: Sun, 05 Apr 2020 17:15:04 IST
TITLE: US to airlift 22,000 Americans stranded overseas; many in India
LINK: https://timesofindia.indiatimes.com/world/.......
PUBDATE: Sun, 05 Apr 2020 14:08:04 IST
TITLE: Ecuador VP apologizes after virus corpses left on streets
LINK: https://timesofindia.indiatimes.com/world/....
PUBDATE: Sun, 05 Apr 2020 14:01:42 IST

得到的元素(例如标题,链接,发布日期)看起来符合我们的预期。让我们进入下一部分,我们将创建一个简单的函数来从链接中获取新闻文章文本。

提取新闻文章

在本节中,我们将通过分析网页的HTML链接来提取新闻文章文本。从RSS feed收到的链接中,我们将取出网页并使用BeautifulSoup 对其进行解析。

网页HTML应该进行被彻底分析,以能够识别所需新闻文本的标签。我创建了一个简单的函数来从链接中获取新闻文本。我将使用BeautifulSoup来提取特定html标签中可用的新闻文本。

# Function to fetch each news link to get news essay 
def fetch_news_text(link):
# read the html webpage and parse it
    soup = BeautifulSoup(requests.get(link).content, 'html.parser')   
    # fetch the news article text box
    # these are with element <div class="_3WlLe clearfix">
    text_box = soup.find_all('div', attrs={'class':'_3WlLe clearfix'})
    # extract text and combine
    news_text = str(". ".join(t.text.strip() for t in text_box))
    return news_text# using the above function, process text
news_articles = [{'Feed':'timesofindia',
                  'Category':category, 
                  'Headline':allitems[item].title.text, 
                  'Link':allitems[item].guid.text, 
                  'Pubdate':allitems[item].pubdate.text,
                  'NewsText': fetch_news_text(allitems[item].guid.text)} 
                     for item in range(len(allitems))]news_articles = pd.DataFrame(news_articles)
news_articles.head(3)

获取到的新闻文章的细节

为了进行文本清理,我使用了文本的预处理,这些步骤是删除HTML标记,特殊字符,数字,标点符号,停用词,处理重音字符,扩展收缩,词干和词形等。

在这里,我将这些预处理步骤放到一个函数中,该函数将返回干净且标准化的语料库。

# test normalize cleanup on one article
# clean_sentences = normalize_corpus([news_articles['NewsText'][0]])
clean_sentences = normalize_corpus(news_articles['NewsText'])

产生句子向量

我们将使用GloVe词嵌入来生成句子的向量表示。对于本练习,我使用的是经过预先训练的Wikipedia 2014 + Gigaword 5 GloVe向量(https://nlp.stanford.edu/projects/glove/)

# define dict to hold a word and its vector
word_embeddings = {}# read the word embeddings file ~820MB
f = open('.\\GloVe\\glove.6B\\glove.6B.100d.txt', encoding='utf-8')
for line in f:
    values = line.split()
    word = values[0]
    coefs = np.asarray(values[1:], dtype='float32')
    word_embeddings[word] = coefs
f.close()# check the length
len(word_embeddings) # 400000

在这个集合中,我们有40万个单词嵌入进去。这些单词嵌入的大小为822 MB。大小可能会因嵌入tokens而异。嵌入越多,精度越高。让我们使用这些单词嵌入为归一化的句子创建向量。对于一个句子,我们将首先获取每个单词的向量,然后将取所有句子/词向量分数的平均值,最终得出这个句子的合并向量分数。

# create vector for each sentences
# list to hold vector 
sentence_vectors = []# create vector for each clean normalized sentence
for i in clean_sentences:
    if len(i) != 0:
        v = sum([word_embeddings.get(w, np.zeros((100,))) for w in i.split()])/(len(i.split())+0.001)
    else:
        v = np.zeros((100,))
    sentence_vectors.append(v)print('Total vectors created:',len(sentence_vectors))

取前N个句子

向量只是平面上的有方向的线段。使用余弦相似度方法,将发现句子之间的相似度。向量间的余弦角越小则越相似。在文章中,我们可以每隔一个句子计算一个余弦角。在这里,也可以使用其他方法,例如欧几里得距离,它们之间距离越小,向量越相似。

接下来,让我们将这个余弦相似度矩阵转换成一个图形,其中节点代表句子,边界将代表句子之间的相似度得分。在此图上,将应用PageRank算法得出每个句子的排名。

import networkx as nx

# build graph and get pagerank
nx_graph = nx.from_numpy_array(sim_mat)
scores = nx.pagerank(nx_graph)

# print final values of sentences
scores

输出:

{0: 0.0651816121717921,
 1: 0.0642861521750098,
 2: 0.06399116048715114,
 3: 0.06432009432128397,
 4: 0.06385988469675835,
 5: 0.06400525631019922,
 6: 0.06520921510891638,
 7: 0.06320537732857809,
 8: 0.06298228524215846,
 9: 0.06399491863786076,
 10: 0.0640726538022174,
 11: 0.06349704017361839,
 12: 0.06357060319536506,
 13: 0.057627597033478764,
 14: 0.058463972076477785,
 15: 0.05173217723913434}  

由于我们在第一篇文章中得到了16个句子,因此我们得到了16个分数,每个句子一个。我们根据上面计算的排名选择前N个句子。

最后步骤和结论

如上所述,最终文本需要经过一些处理才能呈现。这些处理可以是将每个句子的首字母大写,从每篇文章的开头删除位置名称,删除多余的空格/制表符/标点符号,更正换行符等。.

最后,我们可以将所有这些步骤放在一起以创建摘要引擎/脚本。可将该脚本安排为每天早晨在选定的RSS频道上运行,并将新闻摘要发送到你的收件箱。这样,您无需遍历所有文章来了解最新信息。或者,你可以创建一个漂亮的HTML页面/小部件以显示主要出版物的新闻摘要。请注意,在上面,我使用了单个RSS频道,但是在创建管道时,可以指定更多的RSS频道。另外,我使用了一些打印语句来显示中间值,可以将这些中间值删除以获得无缝的体验。

希望您喜欢这篇文章。如果您想对其中的任何方法分享任何建议,请随时在评论中说。读者的反馈/评论始终是作家的灵感。

参考:

文本预处理

deephub翻译组:张森豪

评论
用户头像