自动摘要
2020-05-06 本文已影响0人
AntiGravity
背景
大数据时代,信息爆炸?垃圾遍地!
互相复制的新闻
重复推送的广告
大量冗余无效的信息
所以需要筛选信息,通过文本自动摘要
应用场景:P2C网站、企业;论文网站、新闻网站、搜索引擎
使用价值:冗余去除、片面提取、杂质剔除
概览
有监督:人工摘要后契合。无监督:算法生成。
基本原理
- 文本信息都在句子中。
- 标点符号进行分句或分段。
- 找出信息最多的句/段。(关键词、相似度、潜在语义等)
实现思路
抽取式
- 定义:提取关键词、句子形成摘要
- 各句打分:
- 基于统计:如TextTeaser,基于长度、位置、关键词等信息进行评分
- 基于网络图:如TextRank,按照节点权重
- 基于潜在语义:使用主题模型,挖掘隐藏信息进行评分
- 基于各句和文章之间的相似度
- TF-IDF提取关键词后基于关键词首先出现或包含数量多少
- 句子重组:保证可读性
压缩式
- 压缩信息,可能损失
生成式
- 最接近摘要的本质,难度大
效果评价
人工评价(标准摘要来自专家)
- Edmundson:计算和标准摘要的句子的重合率
- ROUGE:计算和标准摘要的重叠基本单元(n元语法、词序列、词对)的召回率
- ROUGE-N:N-gram
- ROUGE-L:最长公共子序列
- ROUGE-W:连续匹配赋予更大权重
- ROUGE-S:考虑了所有按词序排列的词对。比ngram更深入反应句子级词序。
- ROUGE-S4/S9:多文档
Python实现
思路
- 语料处理
- 分句
- 特征工程
- 向量化
- 句子评分
- 重组生成摘要
# 语料
chapter.txt[1]
# 分句(过于简略,未考虑说话的双引号内算一句等)
def cut_sentence(intxt):
delimeters=frozenset('。!?')
buf=[]
for ch in intxt:
buf.append(ch)
if delimeters.__contains__(ch):
yield ''.join(buf)
buf=[]
if buf:
yield ''.join(buf)
sentdf=pd.DataFrame(cut_sentence(chapter.txt[1]))
# 去除过短的句子
sentdf['txtlen']=sentdf[0].apply(len)
sentlist=sentdf[0][sentdf.txtlen>20]
print(len(sentlist))
# 向量化
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
txtlist=[''.join(jieba.lcut(w)) for w in sentlist]
vectorizer=CountVectorizer()
X=vectorizer.fit_transform(txtlist)
tfidf_matrix=TfidfTransformer().fit_transform(X)
# 句子评分
import networkx as nx
similarity=nx.from_scipy_sparse_matrix(tfidf_matrix *tfidf_matrix.T)
scores=nx.pagerank(similarity)
tops=sorted(scores.items(),key=lambda x:x[1], reverse=True)
# 查看评分结果
print(sentlist.iloc[tops[0][0]])
print(sentlist.iloc[tops[1][0]])
sentlist.iloc[tops[2][0]]
# 重组生成摘要
topn=5
topsent=sorted(tops[:topn])
abstract=''
for i in topsent:
abstract=abstract+sentlist.iloc[i[0]]+'......'
abstract[:-6]
改进:
- 分句更精确
- 评分标准尝试pagerank以外的算法
- 不是分句,而通过分段找出关键段落,然后提取潜在语义或关键词、句。