文本摘要
0.Abstract
本文实现了一个简单的中文文本摘要, 摘要方法使用生成式. 评估方法使用Rouge-N.
项目代码github地址:
PyTorch实现 [New!!! 2021.04.03新增]
https://github.com/neesetifa/summarization_pytorch
Keras实现
https://github.com/neesetifa/summarization_keras
1.任务介绍
文本摘要通常有两种, 它们分别是抽取式摘要(Extractive summarization)和生成式摘要(Abstractive summarization). 压缩式摘要暂不讨论.
抽取式摘要主要从源文档中提取出现成的词/句.
生成式摘要是基于NLG(Natural Language Generation).由模型自己生成句子. 生成式摘要较抽取式摘要具有更高的灵活性, 允许模型有一定概率生成新的词语/短语. 通常基于sequence to sequence结构实现. 此类型是本文实现的摘要生成方式.
数据集
来自NLPCC2017
一共约50K条数据, 分为摘要(summarization)和原文(text)两部分.
使用正则匹配清洗数据集(清洗后有5条为空数据)
部分数据的清洗效果, 上面是原文, 下面是清洗后的数据:
评估方法
本项目使用的评估方法是ROUGE-N和ROUGE-L
ROUGE-N的最大值是1. 即"参考摘要"里的所有字都在"模型自动生成的摘要"里出现过.
测试集
同样来自NLPCC2017, 测试集约为2000条.
2. 词表构建
词表构建比较简单, 没有使用分词工具, 直接分字.
PS: 可以使用分词工具进行分词. 此处使用分字没有特殊含义.
chars = {
}
for summarization,text in df.values:
for w in summarization:
chars[w] = chars.get(w, 0) + 1
for w in text: #
chars[w] = chars.get(w, 0) + 1
词表里额外加入了4个特殊词, 分别是:
<pad> 即padding,补全用
<unk> unknown,未知词/不在词表里的词
<start> 开始符
<end> 结束符
4个特殊词放在词表的 0-3这4个index里, 正式词从编号4开始. 整个词表保存在一个json文件里.
json.dump([chars, id2char, char2id], open('vocab.json', 'w'))
3. Baseline模型
Baseline模型使用了sequence to sequence结构+attention机制.
encoder部分用了双向LSTM结构(即BiLSTM), decoder里面用了单向LSTM.
由于单向结构只考虑了上下文中的"上文"信息, 并没有考虑后面的内容. 双向结构同时拥有从后往前的信息, 即考虑了"下文"的信息.
decoder部分没有加入双向是因为显然解码只能从左往右. 如果decoder部分也能做双向还请留言指教.
双向LSTM的结构可以参考下图, hi是LSTM单元. (把LSTM换成最基本的RNN或者GRU, 从结构上来说都是可以的)
h1是正向结构:
h t ( 1 ) = f ( U 1 h t − 1 ( 1 ) + W 1 x t + b 1 ) h_t^{(1)}=f(U_{1}h_{t-1}^{(1)}+W_{1}x_{t}+b_{1}) ht(1)=f(U1ht−1(1)+W1xt+b1)
h2是逆向结构:
h t ( 2 ) = f ( U 2 h t + 1 ( 2 ) + W 2 x t + b 2 ) h_t^{(2)}=f(U_{2}h_{t+1}^{(2)}+W_{2}x_{t}+b_{2}) ht(2)=f(U2ht+1(2