jieba分词库——基于 TextRank 算法的关键词抽取


基于 TextRank 算法的关键词抽取

TextRank 由 Mihalcea 与 Tarau 于 EMNLP 在2014年提出来,其思想非常简单。关键词抽取的任务就是从一段给定的文本中自动抽取出若干有意义的调语或词组。 TextRank 算法是利用局部调汇之间关系《共现窗口)对后续关键词进行排序,直接从文本本身抽取

  • 定义:通过词之间的相邻关系构建网络,然后用 PageRank 迭代计算毎个节点的 rank 值,排序 rank 值即可得到关键词
  • 方法:利用图模型来提取文章中的关键词步骤

基于 TextRank 的关键词提取过程步骤如下:

  1. 把给定的文本按照完整句子进行分割,对于每个句子。进行分词和词性标注处理,并过滤掉停用词,只保留指定词性得单词
  2. 构建候选关键词图 G -(. E ),其中 V 为节点集,上一步生成的候选关键词组成,然后采用共现关系( co - occurrence )构造任两点之间的边,两个节点之间存在边仅当它们对应的词汇在长度为 K 的国口中共曾量更新现, K 表示窗口大小,即最多共现 K 个单词。根据上面公式,迭代传播各节点的权重,直至收敛。
  3. 对节点权重进行倒序排序,从而得到最里要的 T 个单词,作为候选关镛词。第二部得到最里要的 T 个单词,在原始文本中进行标记,着形成相邻词組,则组合成多词关键词。例如。文本中有句子" Matlab code for plotting ambiguity function ",如果“ Matlab "和" code "均属于候选关键词,则组合成“ Matlab与召回排序计算code "加入关键词序列。

词性和专名类别标签集合如下表,其中我们将最常用的4个专名类别标记为大写的形式:(https://github.com/baidu/lac)

 用法示例:

def textrank(partition):
    import os

    import jieba
    import jieba.analyse
    import jieba.posseg as pseg
    import codecs

    

    class TextRank(jieba.analyse.TextRank):
        def __init__(self, window=20, word_min_len=2):
            super(TextRank, self).__init__()
            self.span = window  # 窗口大小
            self.word_min_len = word_min_len  # 单词的最小长度
            # 要保留的词性,根据jieba github ,具体参见https://github.com/baidu/lac
            self.pos_filt = frozenset(
                ('n', 'x', 'eng', 'f', 's', 't', 'nr', 'ns', 'nt', "nw", "nz", "PER", "LOC", "ORG"))

        def pairfilter(self, wp):
            """过滤条件,返回True或者False"""

            if wp.flag == "eng":
                if len(wp.word) <= 2:
                    return False

            if wp.flag in self.pos_filt and len(wp.word.strip()) >= self.word_min_len \
                    and wp.word.lower() not in stopwords_list:
                return True
    # TextRank过滤窗口大小为5,单词最小为2
    textrank_model = TextRank(window=5, word_min_len=2)
    allowPOS = ('n', "x", 'eng', 'nr', 'ns', 'nt', "nw", "nz", "c")

    for row in partition:
        tags = textrank_model.textrank(row.sentence, topK=20, withWeight=True, allowPOS=allowPOS, withFlag=False)
        for tag in tags:
            yield row.article_id, row.channel_id, tag[0], tag[1]