引言

最近在面试北京技术负责人一位候选者(学校杠杠的)时,他对现在公司的新闻领域做摘要时说准确率能达99%,并且也通过了他们内部验证以及用户的对外展示(这家公司你就可劲想吧)。心里是有点不太相信可以达到这么高,理由:

  1. 新闻常见字数成千上万,对于这种情况人的理解也有所差异,但只要摘要中出现核心关键词/句子基本也认可。
  2. 对于所用到的无监督的方式(用到了textrank),目前业界的上限在那,同时受限于特征工程。
  3. 对于使用生成式模型,比如使用PGN,这类方式就要有标注数据。以及有个问题就是生成文本不可控,这也是目前业界在研究的方向。
  4. 用到了textrank,那么句子都是从原文中获得的,那么连续性无法保证,更应该说从原文提取关键句子,代表原文。

之前没做过这方面,就比较好奇怎么实现的。所以此篇为开篇之作,研究TextRank4ZH是怎么做关键句提取的。

TextRank4ZH关键句实现

啊,这个项目够久远的了~

1. 实现

入口,核心在sort_sentences,构造了一个无向加权图,来计算textrank。那加权是怎么计算的呢?看sim_func函数,它是通过计算两个句子共现词来实现。

2. 总结

整理流程不复杂,具体可归纳为下面几步:

  1. 对原文分句,并对每个句子分词,过滤停用词,获取指定词性候选词
  2. 计算两两句子之间的相似度来构成textrank无向图。

作者这里计算句子相似度的方式可以更改成比如使用word2vec来表示句子的向量,或许他是这种方式来实现的。

3. textrank

那关键点就变成了怎么使用textrank了,textrank的核心就是:当前节点的重要程度是由引用它的节点的数量以及对应重要程度所决定

下面我通过几个例子来说明textrank怎么使用networkx来实现计算的,方便以后使用。

1. 使用方式

使用方式有两种:

  1. 通过add_edge来构造有向图
  2. 通过matrix来构造有向图

但是这里是没有权重的,所以引入第二个例子。

2. 引入权重

这里在add_edge的时候指定weight,可看到nx.to_numpy_matrix的矩阵变化了。

3. 无向图

textrank4ZH使用的都是无向图,这个并不影响textrank的计算结果。

4. 总结

根据上面几个例子,下次在计算textrank的时候,

  1. 构造无向图(有个小坑:nx.from_numpy_matrix不指定create_using,会导致生成的G2和原来的G的matrix不一样,导致最终的textrank也不一样.例子,但是具体怎么使用都是可以滴)
  2. 指定weight(weight可以通过其他方式来获得)