无需搭建和训练模型,87行代码搞定文章摘要生成

晓查 编译整理

量子位 出品 | 公众号 QbitAI

在不想去读长篇大论的时候,让电脑帮助我们提炼文章的摘要,这简直是懒癌患者福音,还能大大节约时间。

现在有人手把手教你如何用Python做到这一点,甚至都不要训练模型,简单易懂。

无需搭建和训练模型,87行代码搞定文章摘要生成

一名全栈工程师Praveen Dubey在Medium上分享了他的代码。下面让我们一起来看看他的思路吧。

提取摘要分几步

Praveen Dubey首先面临的是方法选择的问题。通常生成文章摘要有两种方法:抽象法、提取法。

抽象法基于语义理解选择措辞,概括文章内容以生成新的较短文本。提取法则是通过选择保留最重要的单词子集,来总结文章。

作者选择了提取法。相比于抽象法,这种方法不需要对文章进行深入的理解。

另外,提取法获得的结果往往比抽象法更好,因为它是采用原文中的单词,不像抽象法还存在自然语言生成的问题。

无需搭建和训练模型,87行代码搞定文章摘要生成

在文章中,作者使用无监督学习的方法,基于相似度矩阵,来生成排名来找到句子的相似性并对它们进行排名。这样做的还有一个好处是,不需要使用项目前训练和构建模型。

概率起来就是:输入文章→拆分成句子→删除停止词→建立相似度矩阵→基于矩阵生成排名→选择前N个句子进行汇总。

安装教程

接下来,将按照以上步骤创建属于你自己的摘要生成器。

导入必要的软件库

从自然语言工具包NLTK中导入停止词(stopwords),安装numpy等依赖库。

from nltk.corpus import stopwords
from nltk.cluster.util import cosine_distance
import numpy as np
import networkx as nx

生成简洁的句子

def read_article(file_name):
 file = open(file_name, "r")
 filedata = file.readlines()
 article = filedata[0].split(". ")
 sentences = []
 for sentence in article:
 print(sentence)
 sentences.append(sentence.replace("[^a-zA-Z]", " ").split(" "))
 sentences.pop() 
 return sentences

相似度矩阵

使用余弦相似性来找到句子之间的相似性的地方。所谓余弦相似性是两个向量的夹角余弦,以此作为向量之间相似性的度量。

def build_similarity_matrix(sentences, stop_words):
 # Create an empty similarity matrix
 similarity_matrix = np.zeros((len(sentences), len(sentences)))
 for idx1 in range(len(sentences)):
 for idx2 in range(len(sentences)):
 if idx1 == idx2: #ignore if both are same sentences
 continue 
 similarity_matrix[idx1][idx2] = sentence_similarity(sentences[idx1], sentences[idx2], stop_words)
return similarity_matrix

生成汇总方法

方法将保持调用所有其他辅助函数来保持摘要pipeline的运行。

def generate_summary(file_name, top_n=5):
 stop_words = stopwords.words('english')
 summarize_text = []
 # Step 1 - Read text and tokenize
 sentences = read_article(file_name)
 # Step 2 - Generate Similary Martix across sentences
 sentence_similarity_martix = build_similarity_matrix(sentences, stop_words)
 # Step 3 - Rank sentences in similarity martix
 sentence_similarity_graph = nx.from_numpy_array(sentence_similarity_martix)
 scores = nx.pagerank(sentence_similarity_graph)
 # Step 4 - Sort the rank and pick top sentences
 ranked_sentence = sorted(((scores[i],s) for i,s in enumerate(sentences)), reverse=True) 
 print("Indexes of top ranked_sentence order are ", ranked_sentence)
for i in range(top_n):
 summarize_text.append(" ".join(ranked_sentence[i][1]))
 # Step 5 - Offcourse, output the summarize texr
 print("Summarize Text: 
", ". ".join(summarize_text))

把以上代码按顺序汇总起来,就得到完整的代码。

一次性减少2/3内容

本文作者对一段314词的微软新闻进行试验,获得了不到100词的摘要,效果明显。

无需搭建和训练模型,87行代码搞定文章摘要生成

如果你觉得缩减得还不够,可以进一步处理,减少它的字符数。

作者在程序中使用了TextRank对句子进行排名,这是一种基于图的通用NLP排名算法。TextRank不依赖于任何训练数据,可以处理任意文本。

此外,还有很多先进的技术可用于提取文本摘要。作者还提供了两篇该领域的文章,如果你对这一话题感兴趣,可以进一步深入学习。

传送门

项目地址:

https://github.com/edubey/text-summarizer

文本摘要技术简要概述:

https://arxiv.org/abs/1707.02268v3

自然语言生成的现状调查:核心任务、应用和评估:

https://arxiv.org/abs/1703.09902v1

版权所有,未经授权不得以任何形式转载及使用,违者必究。