无需搭建和训练模型,87行代码搞定文章摘要生成
晓查 编译整理
量子位 出品 | 公众号 QbitAI
在不想去读长篇大论的时候,让电脑帮助我们提炼文章的摘要,这简直是懒癌患者福音,还能大大节约时间。
现在有人手把手教你如何用Python做到这一点,甚至都不要训练模型,简单易懂。
一名全栈工程师Praveen Dubey在Medium上分享了他的代码。下面让我们一起来看看他的思路吧。
提取摘要分几步
Praveen Dubey首先面临的是方法选择的问题。通常生成文章摘要有两种方法:抽象法、提取法。
抽象法基于语义理解选择措辞,概括文章内容以生成新的较短文本。提取法则是通过选择保留最重要的单词子集,来总结文章。
作者选择了提取法。相比于抽象法,这种方法不需要对文章进行深入的理解。
另外,提取法获得的结果往往比抽象法更好,因为它是采用原文中的单词,不像抽象法还存在自然语言生成的问题。
在文章中,作者使用无监督学习的方法,基于相似度矩阵,来生成排名来找到句子的相似性并对它们进行排名。这样做的还有一个好处是,不需要使用项目前训练和构建模型。
概率起来就是:输入文章→拆分成句子→删除停止词→建立相似度矩阵→基于矩阵生成排名→选择前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词的摘要,效果明显。
如果你觉得缩减得还不够,可以进一步处理,减少它的字符数。
作者在程序中使用了TextRank对句子进行排名,这是一种基于图的通用NLP排名算法。TextRank不依赖于任何训练数据,可以处理任意文本。
此外,还有很多先进的技术可用于提取文本摘要。作者还提供了两篇该领域的文章,如果你对这一话题感兴趣,可以进一步深入学习。
传送门
项目地址:
https://github.com/edubey/text-summarizer
文本摘要技术简要概述:
https://arxiv.org/abs/1707.02268v3
自然语言生成的现状调查:核心任务、应用和评估:
https://arxiv.org/abs/1703.09902v1
- 张朝阳开课手推E=mc²,李永乐现场狂做笔记2022-03-11
- 阿里数学竞赛可以报名了!奖金增加到400万元,题目面向大众公开征集2022-03-14
- 英伟达遭黑客最后通牒:今天必须开源GPU驱动,否则公布1TB机密数据2022-03-05
- “治不了GitHub,还治不了你?”唱片行业追杀youtube-dl2022-03-08