前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >精品教学案例 | 基于TextRank的新闻摘要(Python实现)

精品教学案例 | 基于TextRank的新闻摘要(Python实现)

原创
作者头像
数据酷客
修改2020-05-09 17:24:20
2.4K0
修改2020-05-09 17:24:20
举报
文章被收录于专栏:数据科学人工智能

查看本案例完整的数据、代码和报告请登录数据酷客(http://cookdata.cn)案例板块。

本案例适合作为大数据专业自然语言处理课程的配套教学案例。通过本案例,能够达到以下教学效果:

  • 培养学生对非结构化的文本数据的处理能力。案例主要介绍如何给海量网球新闻文档数据集,生成概括其中心思想的摘要。
  • 帮助学生熟悉自动文摘的原理和方法。例如:抽取式文档摘要(Extractive Summarization)和生成式文档摘要(Abstractive Summarization)。
  • 提高学生动手实践能力。案例中使用Python实现TextRank算法,并结合PageRank算法和GloVe词向量来生成网球新闻文档摘要。

前言

自然语言处理对我们的生活有着巨大的影响,文档摘要是自然语言处理的诸多应用之一。不断发展的数字化媒体以及越来越快的信息发布速度,我们没有那么多时间去阅读所有的文章、书籍,以此发现对我们有用的信息。文档摘要应运而生。

你有使用过inshorts这款新颖的App吗,它将一篇文章转化为60个词的摘要,这也是我们今天这篇文章所要讲的主题--自动文档摘要

自动文档摘要是自然语言处理领域最有挑战和趣味的研究问题,它从书籍、文章、博客、论文等文本资源生成精准的、有意义的摘要。由于现实世界中存在着海量的文本数据,我们迫切需要自动文摘这门技术。

通过这篇文章,我们将会探索文档摘要这个领域,学习TextRank算法来完成文档摘要,并用Python进行实现,让我们开始吧。

1. 文档摘要途径

自动文档摘要从1950年代开始获得关注。在1950年代后期,Hans Peter Luhn发表了一篇标题为 The automatic creation of literature abstracts(自动创建文章摘要)的论文,使用词语频率、词组频率等特征将重要的句子抽取出来作为文档摘要。

另外一篇重要的研究是1960年代后期 Harold P Edmundson完成的,使用了句子中是否出现了标题中的单词以及句子的位置等特征来抽取重要的句子。从那以后,自动文档摘要领域出现了很多重要的、令人激动的研究。

文档摘要可以划分为两个种类 -- 抽取式文档摘要生成式文档摘要

  1. 抽取式文档摘要(Extractive Summarization):这类方法从文档中抽取短语、句子等片段,将这些片段组合在一起形成文档摘要。因此从文档中抽取出正确的句子是这类方法的关键。
  2. 生成式文档摘要(Abstractive Summarization):这种方法使用高阶的自然语言处理技术去生成一篇全新的摘要,摘要的内容甚至没有出现在原始文档中。

在这篇案例中,我们关注的是第一种--抽取式文档摘要

2. 理解TextRank算法

在开始介绍TextRank之前,我们先来讲一下于之非常相似的PageRank算法。事实上,TextRank就是受到了PageRank算法思想的启发。PageRank主要是用来给搜索引擎结果排序的。让我们从下面这个例子了解PageRank的基本思想吧。

2.1 PageRank

假设我们有四个网页 -- w1, w2, w3, w4. 这四个网页包含了指向其他网页的链接。其中有一些网页可能没有指向其他网页的链接,这样的网页被称为悬挂页面(dangling pages)。

  • w1包含了指向w2和w4的链接
  • w2包含了指向w3和w1的链接
  • w4只包含了指向w1的链接
  • w3没有包含链接

为了将这些页面排序,我们需要通过PageRank计算每个页面的得分。这个分数表明用户访问这个页面的概率。

为了得到用户从一个页面跳转到另一个页面的概率,我们先构造一个 n*n 的方矩阵 M,n是网页的数量。

矩阵中每个元素代表了用户从一个网页跳转到另一个网页的概率。举例来说,下面这个高亮的部分包含了用户从w1跳转到w2的概率。

矩阵中元素的初始化过程如下:

  1. 页面i到页面j的概率 M[i][j] 初始化为 1/页面i包含的的不重复链接数量
  2. 如果页面i没有指向页面j链接,则将M[i][j] 初始化为0
  3. 如果用户停留在悬挂页面,则假设他从悬挂页面跳转到其他页面的概率都相同。M[i][j] 初始化为 1/所有网页数量

在我们的例子中,矩阵 M 被初始化为:

最后,矩阵中的元素将会根据算法在不断的迭代中得到更新,从而得到页面排序

2.2 TextRank算法

在大致了解PageRank后,现在我们来学习TextRank算法。TextRank与PageRank有很多相似之处:

  • 用句子取代网页
  • 句子之间的相似性等同于网页跳转概率
  • 句子间相似得分同样被存储在矩阵 M 中,类似于PageRank。

TextRank是一项抽取式的无监督文档摘要技术。让我们来看一下TextRank用于文档摘要的流程吧:

  1. 将所有文章的文本合并到一起。
  2. 将文本进行切分,得到句子集合
  3. 通过词向量得到句子的向量化表示
  4. 计算句子向量间的相似度并存储于矩阵M中
  5. 将矩阵M转化为图。在这张图中,句子作为节点,句子间相似度作为边。以此计算句子的排序。
  6. 最后,排在前面的句子构成文档的摘要

3. 问题来源

作为一个网球迷,我经常尝试着浏览尽可能多的在线网球资讯,从而了解这个领域最近发生了什么。然而事实证明,这实在太难了。资讯那么多,而时间总是有限的。

因此,我决定写一个能够扫描大量文章然后给出一篇精准摘要的系统。我该怎么做呢?这就是我在这篇案例想要教给大家的。我们将运用TextRank算法,从抓取的文章集合中构造一篇简洁准确的摘要。

需要注意的是,这项任务是从多篇相同领域文章中得到一篇摘要。本文并未涉及多领域文本摘要--从给出的多篇不同领域文当中得到多篇摘要,不过学习完这个案例,你可以去尝试一下多领域文本摘要。

4. 实现TextRank算法

不多说了,在jupyter notebook中开始动手吧,实现我们上面所学的知识。

4.1 导入需要的库

导入我们需要用到的库

代码语言:javascript
复制
import numpy as np
import pandas as pd
import nltk
nltk.download('punkt') # 执行一次就可以了
import re

4.2 读取数据

现在让我们读取我们的数据集,已经上传到平台,目录是./input/tennis_articles_v4.csv

代码语言:javascript
复制
df = pd.read_csv("./input/tennis_articles_v4.csv")

4.3 检查数据

我们大致看一下数据集中的文本。

代码语言:javascript
复制
df.head()

有三个列 -- 文章id、文章的文本内容、来源。我们感兴趣的是文章的文本内容。可以将一些文本打印出来,看看它们是怎样的。

代码语言:javascript
复制
df['article_text'][0]

现在我们有两个选择:为每篇文档单独创建一篇摘要,或者为所有文章创建一篇摘要。在这里,我们选择后一个,创建一篇总的摘要。

4.4 切分文本成句子

需要将这些文本内容分割成单独的句子,这里用到了nltk库的sent_tokenize()函数。

代码语言:javascript
复制
from nltk.tokenize import sent_tokenize
sentences = []
for s in df['article_text']:
  sentences.append(sent_tokenize(s))

sentences = [y for x in sentences for y in x] # flatten list

让我们打印一些sentences列表中的句子看看。

代码语言:javascript
复制
sentences[:5]

4.5 下载GloVe词向量

Glove词向量是词语的向量化表示。这些词向量可以用来构建句子的向量化表示。我们也可以用词袋模型或者TF-IDF方法来为句子构建特征向量,但是这些方法忽略了句子中单词的顺序,而且这样的特征向量通常维数过高。

我们将会使用斯坦福大学提供的在维基百科语料上训练好的GloVe词向量,这个词向量的大小有822MB,由于文件较大,建议读者自行在本地下载,下载链接为:Glove

下面我们来提取词向量。

代码语言:javascript
复制
word_embeddings = {}
f = open('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()
代码语言:javascript
复制
# 词向量的大小
len(word_embeddings)

这400000个词向量被我们存储在字典中,字典中键值对的key是单词,value是其对应词向量。

4.6 文本预处理

尽可能地除去文本数据的噪音是一个好习惯,下面我们来做一些基本的文本清洗工作。

代码语言:javascript
复制
# 除去标点、数字和特殊字符
clean_sentences = pd.Series(sentences).str.replace("[^a-zA-Z]", " ")

# 左右字母转换成小写
clean_sentences = [s.lower() for s in clean_sentences]

将停用词除去,例如:is, am, this, in等。先要确保已经下载了nltk的停用词,然后导入停用词。

代码语言:javascript
复制
nltk.download('stopwords')
from nltk.corpus import stopwords
stop_words = stopwords.words('english')

我们先定义一个清除句子中停用词的方法,然后应用到所有句子上。

代码语言:javascript
复制
def remove_stopwords(sen):
    sen_new = " ".join([i for i in sen if i not in stop_words])
    return sen_new

clean_sentences = [remove_stopwords(r.split()) for r in clean_sentences]

通过我们上面创建的词向量字典,clean_sentences将被用来构建句子的向量表示。

4.7 句子的向量表示

我们先取出句子中单词对应的词向量,每个词向量的维度是100维,将它们相加再取平均,得到的向量就用来表示这个句子。

代码语言:javascript
复制
sentence_vectors = []
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)

注意:关于文本预处理的更多知识,可以看看这门课程的视频:Natural Language Processing (NLP) using Python

4.8 相似矩阵

下一步就是计算句子间的相似性,我们将用余弦相似性来衡量句子的相似性。我们先构建一个空矩阵,然后填入句子间的余弦相似度。

初始矩阵的大小是n*n, n代表句子数量。

代码语言:javascript
复制
# 构建相似矩阵
sim_mat = np.zeros([len(sentences), len(sentences)])

#使用余弦相似来计算两个句子间的相似度
from sklearn.metrics.pairwise import cosine_similarity

# 使用句子间的相似度初始化矩阵
for i in range(len(sentences)):
    for j in range(len(sentences)):
        if i != j:
            sim_mat[i][j] = cosine_similarity(sentence_vectors[i].reshape(1,100), sentence_vectors[j].reshape(1,100))[0,0]

4.9 使用PageRank算法

在进一步处理前,我们现将相似矩阵sim_mat转化为图。图中的节点用来表示句子,边用来表示句子间的相似度。在这个图上,我们使用PageRank来给句子的排序,得到句子的排序得分,得分越高的句子越重要。

代码语言:javascript
复制
import networkx as nx

nx_graph = nx.from_numpy_array(sim_mat)
scores = nx.pagerank(nx_graph)

4.10 摘要抽取

终于到最后一步了,抽取排序后前N个句子作为这些文档的摘要。

代码语言:javascript
复制
# 按照句子PageRank分数排序
ranked_sentences = sorted(((scores[i],s) for i,s in enumerate(sentences)), reverse=True)

# 选取前10个句子作为摘要
for i in range(10):
    print(ranked_sentences[i][1])

完成啦!我们为这些文档生成了多么棒的、简洁、准确、有用的摘要。

5. 接下来

自动文摘是热门的研究领域,在这篇案例中,我们只讨论了冰山一角。再深入一步,我们将会探索生成式文档摘要技巧,深度学习将起到重要作用。此外我们还会探讨下面这些文档摘要任务。

面向特定问题

  • 多领域文档摘要(Multiple domain text summarization)
  • 单文档摘要(Single document summarization)
  • 跨语言文档摘要(Cross-language text summarization),原始文档的语言与摘要的语言不一样。

具体算法

  • 使用RNNs和LSTM神经网络
  • 使用强化学习
  • 使用生成对抗网络

小结

我希望这篇文章能够帮助你了解自动文摘的概念。这项技术有大量的使用场景并且已经被用在了很多非常成功的应用当中。无论是为了提高你的业务表现,还是为了自己的知识,文档摘要是所有NLP积极分子所应该熟悉的。

源自:PRATEEK JOSHI(作者)—— An Introduction to Text Summarization using the TextRank Algorithm (with Python implementation)

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 查看本案例完整的数据、代码和报告请登录数据酷客(http://cookdata.cn)案例板块。
  • 1. 文档摘要途径
  • 2. 理解TextRank算法
    • 2.1 PageRank
      • 2.2 TextRank算法
      • 3. 问题来源
      • 4. 实现TextRank算法
        • 4.1 导入需要的库
          • 4.2 读取数据
            • 4.3 检查数据
              • 4.4 切分文本成句子
                • 4.5 下载GloVe词向量
                  • 4.6 文本预处理
                    • 4.7 句子的向量表示
                      • 4.8 相似矩阵
                        • 4.9 使用PageRank算法
                          • 4.10 摘要抽取
                          • 5. 接下来
                            • 小结
                            相关产品与服务
                            NLP 服务
                            NLP 服务(Natural Language Process,NLP)深度整合了腾讯内部的 NLP 技术,提供多项智能文本处理和文本生成能力,包括词法分析、相似词召回、词相似度、句子相似度、文本润色、句子纠错、文本补全、句子生成等。满足各行业的文本智能需求。
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档