文章目录
用处:提取关键词、文本摘要
优点:运算简单,计算速度快。
无监督学习。
思想来源于 PageRank
从入链和出链来看待网页。
沦为 Mihaicea 《TextRank》
公式:
TextRank
类似于PageRank的思想,
将文本中的语法单元
视作图中的节点,如果两个语法单元存在一定语法关系(例如共现
),则这两个语法单元在图中就会有一条边相互连接。
通过一定的迭代次数,最终不同的节点会有不同的权重,权重高的语法单元可以作为关键词。
参考论文:Rada Mihalcea的《TextRank:Bring Order into texts》
节点的权重不仅依赖于它的入度结点
,还依赖于这些入度结点的权重,入度结点越多,入度结点的权重越大,说明这个结点的权重越高;
图中任两点 Vi , Vj 之间边的权重为 wji , 对于一个给定的点 Vi, In(Vi) 为 指 向 该 点 的 点 集 合 , Out(Vi) 为点 Vi 指向的点集合。
TextRank迭代计算公式为:
其中, d 为阻尼系数, 取值范围为 0 到 1,代表从图中某一特定点指向其他任意点的概率, 一般取值为 0.85。
使用TextRank 算法计算图中各点的得分时, 需要给图中的点指定任意的初值, 并递归计算直到收敛。
即图中任意一点的误差率小于给定的极限值时就可以达到收敛, 一般该极限值取 0.0001。
算法通用流程:
应用到关键短语抽取:
- 预处理,首先进行分词和词性标注,将单个word作为结点添加到图中;
- 设置语法过滤器,将通过语法过滤器的词汇添加到图中;出现在一个窗口中的词汇之间相互形成一条边;
- 基于上述公式,迭代直至收敛;一般迭代20-30次,迭代阈值设置为0.0001;
- 根据顶点的分数降序排列,并输出指定个数的词汇作为可能的关键词;
- 后处理,如果两个词汇在文本中前后连接,那么就将这两个词汇连接在一起,作为关键短语;
其中,TextRank是为TextRank算法抽取关键词所定义的类。
类在初始化时,默认加载了分词函数和词性标注函数 tokenizer = postokenizer = jieba.posseg.dt
、停用词表stop_words = self.STOP_WORDS.copy()
、词性过滤集合 pos_filt = frozenset(('ns', 'n', 'vn', 'v'))
,窗口 span = 5,((“ns”, “n”, “vn”, “v”))表示词性为地名、名词、动名词、动词。
首先定义一个无向有权图
,然后对句子进行分词;
依次遍历分词结果,如果某个词i满足过滤条件(词性在词性过滤集合中,并且词的长度大于等于2,并且词不是停用词),然后将这个词之后窗口长度为5范围内的词j(这些词也需要满足过滤条件),将它们两两(词i和词j)作为key,出现的次数作为value,添加到共现词典中;
然后,依次遍历共现词典,将词典中的每个元素,key = (词i,词j),value = 词i和词j出现的次数,其中词i,词j作为一条边起始点和终止点,共现的次数作为边的权重,添加到之前定义的无向有权图中。
然后对这个无向有权图进行迭代运算textrank算法,最终经过若干次迭代后,算法收敛,每个词都对应一个指标值;
如果设置了权重标志位,则根据指标值值对无向有权图中的词进行降序排序,最后输出topK个词作为关键词;
def textrank(self, sentence, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v'), withFlag=False):
self.pos_filt = frozenset(allowPOS)
# 定义无向有权图
g = UndirectWeightedGraph()
# 定义共现词典
cm = defaultdict(int)
# 分词
words = tuple(self.tokenizer.cut