我是@老K玩代码,非著名IT创业者。专注分享实战项目和最新行业资讯,已累计分享超1000实战项目!
资源在文末
文本摘要是现在自然语言处理中非常常见,应用也比较广泛的任务类型,商用化的接口也有很多,比如百度大脑以及飞浆提供的api。但缺点是需要支付费用,而且大多都有起始门槛,算下来价格并不便宜,所以并不推荐个人用户。
与其用别人的,不如动手自给自足。老K写了一个基础的文本摘要代码,打算分享给大家。
本着”授人以鱼不如授人以渔“的观念,本篇文章先教后送,只想要代码的可以直接拉到文章末尾。
本次分享的代码旨在抛砖引玉,后续会陆续分享更多有意思的实战项目,建议关注频道、收藏文章。
文本摘要(Text Summarization)是自然语言处理任务中一种重要且常见的任务,可以将冗长的原始文本转换成包含关键词信息的精简文本。帮助用户在只阅读摘要文本就能获取文章主旨和内容的实用目的。
在现实场景中,用得到文本摘要的地方颇多,如:
文本摘要的适用模型有很多,常见的可以分为两大类:抽取型摘要和概要型摘要:
在长文本中提取重点的词句,组成文本。
其优点是简单、高效、易于理解;
缺点则是容易产生语法或逻辑错误
以下是常见的几个抽取型摘要的作业思路:
1. 基于词频:
将文档拆分为句子,利用诸如tfidf的词频统计模型,根据词频权重计算出整句权重,提取高权重的句子组成摘要。
本文的代码也将基于该逻辑来实现。
2. 基于textrank
textrank是基于google的pagerank算法衍生出来的解决方案,依照pagerank算法给每个句子一个”对网络重要程度”的得分,提取得分高的句子组成摘要。
3. 基于词嵌入聚类
词嵌入聚类(embedding clustering)是将拆分后的句子表示为句子向量,再用诸如K-means的聚类方法将句子分成多个簇,再从每个簇里摘取中心句组成摘要。
基于深度学习技术,实现对原始文本的理解和精简,生成代表原始文本重要信息的新短语以及句子。
其优点是有效克服语法错误的问题
缺点则是模型训练成本较高,且需要大量标记数据
以下是常见的几个概要型摘要的作业思路:
1. 基于seq2seq模型
训练一个seq2seq模型(如transformer),以监督学习的方式生成文本摘要。
1. 引入依赖库
from collections import defaultdict
from nltk.tokenize import sent_tokenize, word_tokenize
from string import punctuation
import jieba
from heapq import nlargest2. 文本预处理
text = raw.replace("。", ". ").replace(",", ", ").replace("”", "\"").replace("“", "\"")
text = text.replace("!", "! ").replace("?", "? ").replace(":", ": ").replace(";", "; ")
text = ' '.join(jieba.lcut(text))sents= sent_tokenize(text)
token = [word_tokenize(sent) for sent in sents]3. 词频统计
freq = defaultdict(int)
for word in jieba.lcut(text):
if word not in list(punctuation) and word != " ":
freq[word] += 1m = max(freq.values())
for word in freq:
freq[word] /= m4. 提取中心句
ranking = defaultdict(int)
for i, sent in enumerate(token):
for word in sent:
if word in freq:
ranking[i] += freq[word]idx = nlargest(sent_len, ranking, key=ranking.get)
idx = sorted(idx)5. 整理输出
summary = [sents[i].replace(' ', '') for i in idx]
summary = "
".join(summary)
print(summary)以上代码仅为抛砖引玉,供入门使用。模型思路本身简单,但实际应用效果仍然比较优秀。 后续会考虑出几期textrank、bertsum以及transformer的案例代码分享,有需要的可以收藏关注。
from collections import defaultdict
from nltk.tokenize import sent_tokenize, word_tokenize
from string import punctuation
import jieba
from heapq import nlargest
text = "Your Text Here."
text = text.replace("。", ". ").replace(",", ", ").replace("”", "\"").replace("“", "\"")
text = text.replace("!", "! ").replace("?", "? ").replace(":", ": ").replace(";", "; ")
text = ' '.join(jieba.lcut(text))
sents= sent_tokenize(text)
token = [word_tokenize(sent) for sent in sents]
freq = defaultdict(int)
for word in jieba.lcut(text):
if word not in list(punctuation) and word != " ":
freq[word] += 1
m = max(freq.values())
for word in freq:
freq[word] /= m
ranking = defaultdict(int)
for i, sent in enumerate(token):
for word in sent:
if word in freq:
ranking[i] += freq[word]
idx = nlargest(13, ranking, key=ranking.get)
idx = sorted(idx)
summary = [sents[i].replace(' ', '') for i in idx]
summary = "
".join(summary)
print(summary)我是@老K玩代码,非著名IT创业者。专注分享实战项目和最新行业资讯,已累计分享超1000实战项目!
全网同名,欢迎通过各种渠道和我交流。
| 留言与评论(共有 0 条评论) “” |