精华内容
参与话题
问答
  • TextRank提取来提取关键词,用PageRank的思想来解释它: 如果一个单词出现在很多单词后面的话,那么说明这个单词比较重要 一个TextRank值很高的单词后面跟着的一个单词,那么这个单词的TextRank值会相应地因此...

     用TextRank提取来提取关键词,用PageRank的思想来解释它:

    • 如果一个单词出现在很多单词后面的话,那么说明这个单词比较重要
    • 一个TextRank值很高的单词后面跟着的一个单词,那么这个单词的TextRank值会相应地因此而提高

    背景相关TF-IDF:

    仅仅从词的统计信息出发,而没有充分考虑词之间的语义信息。现在本文将介绍一种考虑了相邻词的语义关系、基于图排序的关键词提取算法TextRank。 

    思想

    其思想非常简单:通过词之间的相邻关系构建网络,然后用PageRank迭代计算每个节点的rank值,排序rank值即可得到关键词。PageRank本来是用来解决网页排名的问题,网页之间的链接关系即为图的边,迭代计算公式如下

    网页之间的链接关系可以用图表示,那么怎么把一个句子(可以看作词的序列)构建成图呢?

    TextRank将某一个词与其前面的N个词、以及后面的N个词均具有图相邻关系(类似于N-gram语法模型)。 

    具体实现:

    设置一个长度为N的滑动窗口,所有在这个窗口之内的词都视作词结点的相邻结点;则TextRank构建的词图为无向图。下图给出了由一个文档构建的词图(去掉了停用词并按词性做了筛选)

    考虑到不同词对可能有不同的共现(co-occurrence),TextRank将共现作为无向图边的权值。那么,TextRank的迭代计算公式如下: 

     代码实现:

     

    #!/usr/bin/env python
    # -*- coding:utf-8 -*- 
    # Author: Jia ShiLin
    
    from jieba import analyse
    
    # 引入关键词提取接口
    textrank = analyse.textrank  #
    
    # 原始文本
    path = 'TextRank.txt'
    with open(path, ) as f:
        text = str(f.read())
        print('\nkeywords by textrank:')  # 基于TextRank算法进行关键词提取
    
    
        #可以到定义的系统textrank.py原函数中修改默然值,查看值,topK表示最高多少个词了列出,allowPOS表示允许保留的词性词
        ##  def textrank(self, sentence, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v'), withFlag=False):
        keywords = textrank(text,topK=10,withWeight=True,allowPOS=('n','a','ns'))
    
        #输出提取出的关键词 f
        words = [keywords for keywords,w in keywords if w >0.2]
        print(' '.join(words)+'\n')

    refrence:

    https://www.cnblogs.com/en-heng/p/6626210.html

    展开全文
  •  在介绍TextRank前,我想先给大家介绍下PageRank,实质上个人认为可以把TextRank当做PageRank2.0。  谷歌的两位创始人的佩奇和布林,借鉴了学术界评判学术论文重要性的通用方法,“那就是看论文的引用次数”。...

    1.前言

        在介绍TextRank前,我想先给大家介绍下PageRank,实质上个人认为可以把TextRank当做PageRank2.0。

        谷歌的两位创始人的佩奇和布林,借鉴了学术界评判学术论文重要性的通用方法,“那就是看论文的引用次数”。由此想到网页的重要性也可以根据这种方法来评价。于是PageRank的核心思想就诞生了:

    • 如果一个网页被很多其他网页链接到的话说明这个网页比较重要,也就是PageRank值会相对较高
    • 如果一个PageRank值很高的网页链接到一个其他的网页,那么被链接到的网页的PageRank值会相应地因此而提高

     2.PageRank算法原理

          从PageRank的核心思想出发,我们

    • \large S(v_{i})定义\large v_{i}这个页面的PageRank值
    • \large \varepsilon来表示所有其他可以链接到\large v_{i}这个页面的集合
    • 那么便可以用\large (j,i)来定义集合中的其中一个(由页面 \large v_{j}链接到页面\large v_{i}

          我们可以给一个页面的PageRank值做这样的定义:

                                                          \large S(v_{i})=\sum _{(j,i)\in\varepsilon }S(v_{j})

        

    sample1

    以上图为例,PangRank的值就可以表示为:

                                                             \large S(A)=S(C)+S(B)

    这样的计算有个很明显的漏洞,可以看到除了C点,其他三个点都外链了2个节点,那么对于B,D来说,是可以选择不去A的而去另外一个链接。所以外链进入A是有一定概率的。针对这点修整PangRank的表示方法:

                                                            \large S(v_{i})=\sum _{(j,i)\in\varepsilon }\frac{S(v_{j})}{Out_{j}}

    用矩阵的思想处理这个公式,设定:

    • \large S(v)=\bigl(\begin{smallmatrix} S(v_{1})\\ \cdot \cdot \cdot \cdot \cdot\\ \cdot \cdot \cdot \cdot \cdot\\ S(v_{n})\end{smallmatrix}\bigr)为一个N维的PangRank值向量,
    • \large A为所有页面的集合,且A有这样定义:
    • \large A_{ji}=\left\{\begin{matrix} \frac{1}{Out(v_{j})} & if (j,i)\in \varepsilon \\ 0& if (j,i)\notin \varepsilon \end{matrix}\right.

    那么对于大量PageRank,我们便可以转化为这样的形式:

                                                                 \large S(v)=A^{T}S(v)

    这样看似优化了很多,但是还存在一定的问题,我们得事先知道其他相关网站的PageRank值,才能得到指定网站的PageRank值。而其他网站的PageRank值还得从一些具有其链接的网站的PageRank值求得。这就变成了一个先有鸡还是先有蛋的问题。

    PageRank采用power iteration来解决这个问题:

    我们给定\large S(v)一个初始值假定为\large S(v)^{0},然后通过下式子不断的迭代求解:

                                                                 \large S(v)^{k}=A^{T}S(v)^{k-1}

     直到最后收敛于\large \left \| S(v)^{k}-S(v)^{k-1} \right \|<\xi,即差别小于某个阈值。

    于是计算PageRank值的过程就变成了一个 Markov 过程,那么PageRank算法的证明也就转为证明 Markov 过程的收敛性证明,

    若一个 Markov 过程收敛,那么它的状态转移矩阵\large A需要满足:

    • stochastic matrix:则行至少存在一个非零值,即必须存在一个外链接(没有外链接的网页被称为dangling pages);
    • 不可约(irreducible):即矩阵\large A所对应的有向图\large G必须是强连通的,对于任意两个节点\large (j,i)\in \varepsilon,存在一个从\large j\large i的路径;
    • 非周期性(aperiodic):即每个节点存在自回路。

    显然,在一般情况下,这样的情况都是不满足的,为了满足性质stochastic matrix,可以把全为0的行替换为\large \frac{e}{n},其中\large e为单位向量;同时为了满足性质不可约、非周期,需要做平滑处理:     

    个人觉得算法领域很多公式的可解释性不强,大多是为了解决某些限定条件,而人为选择的比较好的优化方式,比如下面公式,把\large A的矩阵乘以的一个阻尼系数d,(这个d通常取0.85实践出来的,好像没什么数学解释),实质上是为了给数据做一个平滑处理,都加上一个(1-d)\frac{E}{n}实质是为了替代为零项

                                                                            \dpi{100} \large \dpi{120} \large S(v)=(1-d)\frac{E}{n}+dA^{T}

    于是

                                                                            \large S(v_{i})=\sum _{(j,i)\in\varepsilon }\frac{S(v_{j})}{Out_{j}}

    就被改写为:

                                                                            \large S(v_{i})=(1-d)+d\sum _{(j,i)\in \varepsilon }\frac{S(v_{j})}{Out_{j}}

    3.TextRank算法原理

         用TextRank提取来提取关键词,用PageRank的思想来解释它:

    • 如果一个单词出现在很多单词后面的话,那么说明这个单词比较重要
    • 一个TextRank值很高的单词后面跟着的一个单词,那么这个单词的TextRank值会相应地因此而提高

    这样TextRank的公式就可以由PageRank公式改写为:

                                                          \large S(v_{i})=(1-d)+d\sum_{(j,i)\in \varepsilon }\frac{w_{ji}}{\sum_{v_{k}\in out(v_{j})}w_{jk}}S(v_{j})

    公式的意思很明显:

         TextRank中一个单词\large i的权重取决于与在\large i前面的各个点\large j组成的\large (j,i)这条边的权重,以及\large j这个点到其他其他边的权重之和。

     

    4.python编程实现

       因为在了解textrank的时候,参考了jieba分词和TextRank4zh这2个开源库的写法。但是两者无论写法和运算规则都有很大出入,结合公式来说本人觉得jieba做的更符合公式,TextRank4zh更具有准确性,因为TextRank4zh在公式上面做了一定的优化。

    Jieba分词TextRank:

    • 对每个句子进行分词和词性标注处理
    • 过滤掉除指定词性外的其他单词,过滤掉出现在停用词表的单词,过滤掉长度小于2的单词
    • 将剩下的单词中循环选择一个单词,将其与其后面4个单词分别组合成4条边。

    例如:         ['有','媒体', '曝光','高圆圆', '和', '赵又廷','现身', '台北', '桃园','机场','的', '照片']
            对于‘媒体‘这个单词,就有('媒体', '曝光')、('媒体', '圆')、('媒体', '和')、('媒体', '赵又廷')4条边,且每条边权值为1,当这条边在之后再次出现时,权值再在基础上加1.

    • 有了这些数据后,我们就可以构建出候选关键词图G=(V,E),图的概念有基础的人可能会很好理解,不理解其实也没关系,按上面例子,你只用知道这一步我们把2个单词组成的边,和其权值记录了下来。
    • 这样我们就可以套用TextRank的公式,迭代传播各节点的权值,直至收敛。
    • 对结果中的Rank值进行倒序排序,筛选出前面的几个单词,就是我们需要的关键词了。
    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(sentence))
        # 依次遍历每个词
        for i, wp in enumerate(words):
            # 词i 满足过滤条件
            if self.pairfilter(wp):
                # 依次遍历词i 之后窗口范围内的词
                for j in xrange(i + 1, i + self.span):
                    # 词j 不能超出整个句子
                    if j >= len(words):
                        break
                    # 词j不满足过滤条件,则跳过
                    if not self.pairfilter(words[j]):
                        continue
                    # 将词i和词j作为key,出现的次数作为value,添加到共现词典中
                    if allowPOS and withFlag:
                        cm[(wp, words[j])] += 1
                    else:
                        cm[(wp.word, words[j].word)] += 1
        # 依次遍历共现词典的每个元素,将词i,词j作为一条边起始点和终止点,共现的次数作为边的权重
        for terms, w in cm.items():
            g.addEdge(terms[0], terms[1], w)
        
        # 运行textrank算法
        nodes_rank = g.rank()
        
        # 根据指标值进行排序
        if withWeight:
            tags = sorted(nodes_rank.items(), key=itemgetter(1), reverse=True)
        else:
            tags = sorted(nodes_rank, key=nodes_rank.__getitem__, reverse=True)
    
        # 输出topK个词作为关键词
        if topK:
            return tags[:topK]
        else:
            return tags

     关于有向图的数据结构:

    def addEdge(self, start, end, weight):
        # use a tuple (start, end, weight) instead of a Edge object
        self.graph[start].append((start, end, weight))
        self.graph[end].append((end, start, weight))

    关于TextRank的手写:

    def rank(self):
        ws = defaultdict(float)
        outSum = defaultdict(float)
    
        wsdef = 1.0 / (len(self.graph) or 1.0)
        # 初始化各个结点的权值
        # 统计各个结点的出度的次数之和
        for n, out in self.graph.items():
            ws[n] = wsdef
            outSum[n] = sum((e[2] for e in out), 0.0)
    
        # this line for build stable iteration
        sorted_keys = sorted(self.graph.keys())
        # 遍历若干次
        for x in xrange(10):  # 10 iters
            # 遍历各个结点
            for n in sorted_keys:
                s = 0
                # 遍历结点的入度结点
                for e in self.graph[n]:
                    # 将这些入度结点贡献后的权值相加
                    # 贡献率 = 入度结点与结点n的共现次数 / 入度结点的所有出度的次数
                    s += e[2] / outSum[e[1]] * ws[e[1]]
                # 更新结点n的权值
                ws[n] = (1 - self.d) + self.d * s
    
        (min_rank, max_rank) = (sys.float_info[0], sys.float_info[3])
    
        # 获取权值的最大值和最小值
        for w in itervalues(ws):
            if w < min_rank:
                min_rank = w
            if w > max_rank:
                max_rank = w
    
        # 对权值进行归一化
        for n, w in ws.items():
            # to unify the weights, don't *100.
            ws[n] = (w - min_rank / 10.0) / (max_rank - min_rank / 10.0)
    
        return ws

    jieba.analyse.textrank完整源码如下:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    from __future__ import absolute_import, unicode_literals
    import sys
    from operator import itemgetter
    from collections import defaultdict
    import jieba.posseg
    from .tfidf import KeywordExtractor
    from .._compat import *
    
    
    class UndirectWeightedGraph:
        d = 0.85
    
        def __init__(self):
            self.graph = defaultdict(list)
    
        def addEdge(self, start, end, weight):
            # use a tuple (start, end, weight) instead of a Edge object
            self.graph[start].append((start, end, weight))
            self.graph[end].append((end, start, weight))
    
        def rank(self):
            ws = defaultdict(float)
            outSum = defaultdict(float)
    
            wsdef = 1.0 / (len(self.graph) or 1.0)
            for n, out in self.graph.items():
                ws[n] = wsdef
                outSum[n] = sum((e[2] for e in out), 0.0)
    
            # this line for build stable iteration
            sorted_keys = sorted(self.graph.keys())
            for x in xrange(10):  # 10 iters
                for n in sorted_keys:
                    s = 0
                    for e in self.graph[n]:
                        s += e[2] / outSum[e[1]] * ws[e[1]]
                    ws[n] = (1 - self.d) + self.d * s
    
            (min_rank, max_rank) = (sys.float_info[0], sys.float_info[3])
    
            for w in itervalues(ws):
                if w < min_rank:
                    min_rank = w
                if w > max_rank:
                    max_rank = w
    
            for n, w in ws.items():
                # to unify the weights, don't *100.
                ws[n] = (w - min_rank / 10.0) / (max_rank - min_rank / 10.0)
    
            return ws
    
    
    class TextRank(KeywordExtractor):
    
        def __init__(self):
            self.tokenizer = self.postokenizer = jieba.posseg.dt
            self.stop_words = self.STOP_WORDS.copy()
            self.pos_filt = frozenset(('ns', 'n', 'vn', 'v'))
            self.span = 5
    
        def pairfilter(self, wp):
            return (wp.flag in self.pos_filt and len(wp.word.strip()) >= 2
                    and wp.word.lower() not in self.stop_words)
    
        def textrank(self, sentence, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v'), withFlag=False):
            """
            Extract keywords from sentence using TextRank algorithm.
            Parameter:
                - topK: return how many top keywords. `None` for all possible words.
                - withWeight: if True, return a list of (word, weight);
                              if False, return a list of words.
                - allowPOS: the allowed POS list eg. ['ns', 'n', 'vn', 'v'].
                            if the POS of w is not in this list, it will be filtered.
                - withFlag: if True, return a list of pair(word, weight) like posseg.cut
                            if False, return a list of words
            """
            self.pos_filt = frozenset(allowPOS)
            g = UndirectWeightedGraph()
            cm = defaultdict(int)
            words = tuple(self.tokenizer.cut(sentence))
            for i, wp in enumerate(words):
                if self.pairfilter(wp):
                    for j in xrange(i + 1, i + self.span):
                        if j >= len(words):
                            break
                        if not self.pairfilter(words[j]):
                            continue
                        if allowPOS and withFlag:
                            cm[(wp, words[j])] += 1
                        else:
                            cm[(wp.word, words[j].word)] += 1
    
            for terms, w in cm.items():
                g.addEdge(terms[0], terms[1], w)
            nodes_rank = g.rank()
            if withWeight:
                tags = sorted(nodes_rank.items(), key=itemgetter(1), reverse=True)
            else:
                tags = sorted(nodes_rank, key=nodes_rank.__getitem__, reverse=True)
    
            if topK:
                return tags[:topK]
            else:
                return tags
    
        extract_tags = textrank
    

     

    打赏一下作者:

     

    展开全文
  • TextRank算法介绍及实现

    千次阅读 2019-07-22 21:57:51
    目录 1、PageRank算法 2、TextRank算法 (1)关键词抽取(keyword extraction) (2)关键短语抽取(keyphrase extration...(1)基于Textrank4zh的TextRank算法实现 (2)基于jieba的TextRank算法实现 (3)...

    目录

    1、PageRank算法

    2、TextRank算法

    (1)关键词抽取(keyword extraction)

    (2)关键短语抽取(keyphrase extration)

    (3)关键句抽取(sentence extraction)

    3、TextRank算法实现

    (1)基于Textrank4zh的TextRank算法实现

    (2)基于jieba的TextRank算法实现

    (3)基于SnowNLP的TextRank算法实现

    4、PageRank算法与TextRank算法的区别


    1、PageRank算法

    PageRank算法通过计算网页链接的数量和质量来粗略估计网页的重要性,算法创立之初即应用在谷歌的搜索引擎中,对网页进行排名。 

    PageRank算法的核心思想如下:

    (1)链接数量:如果一个网页被越多的其他网页链接,说明这个网页越重要,即该网页的PR值(PageRank值)会相对较高;

    (2)链接质量:如果一个网页被一个越高权值的网页链接,也能表明这个网页越重要,即一个PR值很高的网页链接到一个其他网页,那么被链接到的网页的PR值会相应地因此而提高。

    PageRank算法计算公式

    PageRank算法论文The PageRank Citation Ranking: Bringing Order to the Web

    2、TextRank算法

    TextRank算法是一种基于图的用于关键词抽取和文档摘要的排序算法,由谷歌的网页重要性排序算法PageRank算法改进而来,它利用一篇文档内部的词语间的共现信息(语义)便可以抽取关键词,它能够从一个给定的文本中抽取出该文本的关键词、关键词组,并使用抽取式的自动文摘方法抽取出该文本的关键句。

    TextRank算法的基本思想是将文档看作一个词的网络,该网络中的链接表示词与词之间的语义关系。

    TextRank算法计算公式

    TextRank算法论文TextRank: Bringing Order into Texts

    TextRank算法主要包括:关键词抽取、关键短语抽取、关键句抽取。

    (1)关键词抽取(keyword extraction)

    关键词抽取是指从文本中确定一些能够描述文档含义的术语的过程。对关键词抽取而言,用于构建顶点集的文本单元可以是句子中的一个或多个字;根据这些字之间的关系(比如:在一个框中同时出现)构建边。根据任务的需要,可以使用语法过滤器(syntactic filters)对顶点集进行优化。语法过滤器的主要作用是将某一类或者某几类词性的字过滤出来作为顶点集。

    (2)关键短语抽取(keyphrase extration)

    关键词抽取结束后,我们可以得到的N个关键词,在原始文本中相邻的关键词构成关键短语。因此,从get_keyphrases函数的源码中我们可以看到,它先调用get_keywords抽取关键词,然后分析关键词是否存在相邻的情况,最后确定哪些是关键短语。

    (3)关键句抽取(sentence extraction)

    句子抽取任务主要针对的是自动摘要这个场景,将每一个sentence作为一个顶点,根据两个句子之间的内容重复程度来计算他们之间的“相似度”,以这个相似度作为联系,由于不同句子之间相似度大小不一致,在这个场景下构建的是以相似度大小作为edge权重的有权图。

    3、TextRank算法实现

    (1)基于Textrank4zh的TextRank算法实现

    # coding=utf-8
    from textrank4zh import TextRank4Keyword, TextRank4Sentence
    import jieba.analyse
    from snownlp import SnowNLP
    import pandas as pd
    import numpy as np
    
    #关键词抽取
    def keywords_extraction(text):
        tr4w = TextRank4Keyword(allow_speech_tags=['n', 'nr', 'nrfg', 'ns', 'nt', 'nz'])
        # allow_speech_tags   --词性列表,用于过滤某些词性的词
        tr4w.analyze(text=text, window=2, lower=True, vertex_source='all_filters', edge_source='no_stop_words',
                     pagerank_config={'alpha': 0.85, })
        # text    --  文本内容,字符串
        # window  --  窗口大小,int,用来构造单词之间的边。默认值为2
        # lower   --  是否将英文文本转换为小写,默认值为False
        # vertex_source  -- 选择使用words_no_filter, words_no_stop_words, words_all_filters中的哪一个来构造pagerank对应的图中的节点
        #                -- 默认值为`'all_filters'`,可选值为`'no_filter', 'no_stop_words', 'all_filters'
        # edge_source  -- 选择使用words_no_filter, words_no_stop_words, words_all_filters中的哪一个来构造pagerank对应的图中的节点之间的边
        #              -- 默认值为`'no_stop_words'`,可选值为`'no_filter', 'no_stop_words', 'all_filters'`。边的构造要结合`window`参数
    
        # pagerank_config  -- pagerank算法参数配置,阻尼系数为0.85
        keywords = tr4w.get_keywords(num=6, word_min_len=2)
        # num           --  返回关键词数量
        # word_min_len  --  词的最小长度,默认值为1
        return keywords
    
    #关键短语抽取
    def keyphrases_extraction(text):
        tr4w = TextRank4Keyword()
        tr4w.analyze(text=text, window=2, lower=True, vertex_source='all_filters', edge_source='no_stop_words',
                     pagerank_config={'alpha': 0.85, })
        keyphrases = tr4w.get_keyphrases(keywords_num=6, min_occur_num=1)
        # keywords_num    --  抽取的关键词数量
        # min_occur_num   --  关键短语在文中的最少出现次数
        return keyphrases
    
    #关键句抽取
    def keysentences_extraction(text):
        tr4s = TextRank4Sentence()
        tr4s.analyze(text, lower=True, source='all_filters')
        # text    -- 文本内容,字符串
        # lower   -- 是否将英文文本转换为小写,默认值为False
        # source  -- 选择使用words_no_filter, words_no_stop_words, words_all_filters中的哪一个来生成句子之间的相似度。
        # 		  -- 默认值为`'all_filters'`,可选值为`'no_filter', 'no_stop_words', 'all_filters'
        # sim_func -- 指定计算句子相似度的函数
    
        # 获取最重要的num个长度大于等于sentence_min_len的句子用来生成摘要
        keysentences = tr4s.get_key_sentences(num=3, sentence_min_len=6)
        return keysentences
    
    
    def keywords_textrank(text):
        keywords = jieba.analyse.textrank(text, topK=6)
        return keywords
    
    
    if __name__ == "__main__":
        text = "来源:中国科学报本报讯(记者肖洁)又有一位中国科学家喜获小行星命名殊荣!4月19日下午,中国科学院国家天文台在京举行“周又元星”颁授仪式," \
               "我国天文学家、中国科学院院士周又元的弟子与后辈在欢声笑语中济济一堂。国家天文台党委书记、" \
               "副台长赵刚在致辞一开始更是送上白居易的诗句:“令公桃李满天下,何须堂前更种花。”" \
               "据介绍,这颗小行星由国家天文台施密特CCD小行星项目组于1997年9月26日发现于兴隆观测站," \
               "获得国际永久编号第120730号。2018年9月25日,经国家天文台申报," \
               "国际天文学联合会小天体联合会小天体命名委员会批准,国际天文学联合会《小行星通报》通知国际社会," \
               "正式将该小行星命名为“周又元星”。"
        #关键词抽取
        keywords=keywords_extraction(text)
        print(keywords)
    
        #关键短语抽取
        keyphrases=keyphrases_extraction(text)
        print(keyphrases)
    
        #关键句抽取
        keysentences=keysentences_extraction(text)
        print(keysentences)

    运行结果:

    (2)基于jieba的TextRank算法实现

    if __name__ == "__main__":
        text = "来源:中国科学报本报讯(记者肖洁)又有一位中国科学家喜获小行星命名殊荣!4月19日下午,中国科学院国家天文台在京举行“周又元星”颁授仪式," \
               "我国天文学家、中国科学院院士周又元的弟子与后辈在欢声笑语中济济一堂。国家天文台党委书记、" \
               "副台长赵刚在致辞一开始更是送上白居易的诗句:“令公桃李满天下,何须堂前更种花。”" \
               "据介绍,这颗小行星由国家天文台施密特CCD小行星项目组于1997年9月26日发现于兴隆观测站," \
               "获得国际永久编号第120730号。2018年9月25日,经国家天文台申报," \
               "国际天文学联合会小天体联合会小天体命名委员会批准,国际天文学联合会《小行星通报》通知国际社会," \
               "正式将该小行星命名为“周又元星”。"
    
        # 基于jieba的textrank算法实现
        keywords=keywords_textrank(text)
        print(keywords)

    运行结果:

    (3)基于SnowNLP的TextRank算法实现

        # 基于SnowNLP的textrank算法实现
        snlp=SnowNLP(text)
        print(snlp.keywords(6))  #关键词抽取
        print(snlp.summary(3))   #关键句抽取

    运行结果:

    4、PageRank算法与TextRank算法的区别

    • PageRank算法根据网页之间的链接关系构造网络,TextRank算法根据词之间的共现关系构造网络;
    • PageRank算法构造的网络中的边是有向无权边,TextRank算法构造的网络中的边是无向有权边。

     

    参考:TextRank算法的基本原理及textrank4zh使用实例

     

    交流学习资料共享欢迎入QQ群:955817470​​​​​​​

     

    展开全文
  • NLP关键字提取之TextRank算法

    千次阅读 2018-09-06 14:26:53
    谈起自动摘要算法,常见的并且最易实现的当属TF-IDF,但是感觉TF-IDF效果一般,不如TextRank好。 TextRank是在Google的PageRank算法启发下,针对文本里的句子设计的权重算法,目标是自动摘要。它利用投票的原理,让...

    今天看了一下HanLP框架的关键字提取的算法,总的来说很简单,就是互相计算词频的一个算法。

    谈起自动摘要算法,常见的并且最易实现的当属TF-IDF,但是感觉TF-IDF效果一般,不如TextRank好。

    TextRank是在Google的PageRank算法启发下,针对文本里的句子设计的权重算法,目标是自动摘要。它利用投票的原理,让每一个单词给它的邻居(术语称窗口)投赞成票,票的权重取决于自己的票数。这是一个“先有鸡还是先有蛋”的悖论,PageRank采用矩阵迭代收敛的方式解决了这个悖论。TextRank也不例外:

    • PageRank的计算公式:
      这里写图片描述

    • 正规的TextRank公式:
      正规的TextRank公式在PageRank的公式的基础上,引入了边的权值的概念,代表两个句子的相似度。
      这里写图片描述
      但是很明显我只想计算关键字,如果把一个单词视为一个句子的话,那么所有句子(单词)构成的边的权重都是0(没有交集,没有相似性),所以分子分母的权值w约掉了,算法退化为PageRank。所以说,这里称关键字提取算法为PageRank也不为过。

    另外,如果你想提取关键句(自动摘要)的话,请参考姊妹篇《TextRank算法自动摘要的Java实现》

    TextRank的Java实现

    先看看测试数据:

    程序员(英文Programmer)是从事程序开发、维护的专业人员。一般将程序员分为程序设计人员
    和程序编码人员,但两者的界限并不非常清楚,特别是在中国。软件从业人员分为初级程序员、
    高级程序员、系统分析员和项目经理四大类。

    我取出了百度百科关于“程序员”的定义作为测试用例,很明显,这段定义的关键字应当是“程序员”并且“程序员”的得分应当最高。

    首先对这句话分词,这里可以借助各种分词项目,比如HanLP分词,得出分词结果:

    [程序员/n, (, 英文/nz, programmer/en, ), 是/v, 从事/v, 程序/n, 开发/v, 、/w, 
    维护/v, 的/uj, 专业/n, 人员/n, 。/w, 一般/a, 将/d, 程序员/n, 分为/v, 程序/n, 
    设计/vn, 人员/n, 和/c, 程序/n, 编码/n, 人员/n, ,/w, 但/c, 两者/r, 的/uj, 界
    限/n, 并/c, 不/d, 非常/d, 清楚/a, ,/w, 特别/d, 是/v, 在/p, 中国/ns, 。/w, 软
    件/n, 从业/b, 人员/n, 分为/v, 初级/b, 程序员/n, 、/w, 高级/a, 程序员/n, 、/w, 
    系统/n, 分析员/n, 和/c, 项目/n, 经理/n, 四/m, 大/a, 类/q, 。/w]

    然后去掉里面的停用词,这里我去掉了标点符号、常用词、以及“名词、动词、形容词、副词之外的词”。得出实际有用的词语:

    [程序员, 英文, 程序, 开发, 维护, 专业, 人员, 程序员, 分为, 程序, 设计, 人员, 程
    序, 编码, 人员, 界限, 特别, 中国, 软件, 人员, 分为, 程序员, 高级, 程序员, 系统, 
    分析员, 项目, 经理]

    之后建立两个大小为5的窗口,每个单词将票投给它身前身后距离5以内的单词:

    {开发=[专业, 程序员, 维护, 英文, 程序, 人员],
     软件=[程序员, 分为, 界限, 高级, 中国, 特别, 人员],
     程序员=[开发, 软件, 分析员, 维护, 系统, 项目, 经理, 分为, 英文, 程序, 专业, 设计, 高级, 人员, 中国],
     分析员=[程序员, 系统, 项目, 经理, 高级],
     维护=[专业, 开发, 程序员, 分为, 英文, 程序, 人员],
     系统=[程序员, 分析员, 项目, 经理, 分为, 高级],
     项目=[程序员, 分析员, 系统, 经理, 高级],
     经理=[程序员, 分析员, 系统, 项目],
     分为=[专业, 软件, 设计, 程序员, 维护, 系统, 高级, 程序, 中国, 特别, 人员],
     英文=[专业, 开发, 程序员, 维护, 程序],
     程序=[专业, 开发, 设计, 程序员, 编码, 维护, 界限, 分为, 英文, 特别, 人员],
     特别=[软件, 编码, 分为, 界限, 程序, 中国, 人员],
     专业=[开发, 程序员, 维护, 分为, 英文, 程序, 人员],
     设计=[程序员, 编码, 分为, 程序, 人员],
     编码=[设计, 界限, 程序, 中国, 特别, 人员],
     界限=[软件, 编码, 程序, 中国, 特别, 人员],
     高级=[程序员, 软件, 分析员, 系统, 项目, 分为, 人员],
     中国=[程序员, 软件, 编码, 分为, 界限, 特别, 人员],
     人员=[开发, 程序员, 软件, 维护, 分为, 程序, 特别, 专业, 设计, 编码, 界限, 高级, 中国]}

    然后开始迭代投票(java实现):

     for (int i = 0; i < max_iter; ++i)
     {
            Map<String, Float> m = new HashMap<String, Float>();
            float max_diff = 0;
            for (Map.Entry<String, Set<String>> entry : words.entrySet())
            {
                String key = entry.getKey();
                Set<String> value = entry.getValue();
                m.put(key, 1 - d);
                for (String other : value)
                {
                    int size = words.get(other).size();
                    if (key.equals(other) || size == 0) continue;
                    m.put(key, m.get(key) + d / size * (score.get(other) == null ? 0 : score.get(other)));
                }
                max_diff = Math.max(max_diff, Math.abs(m.get(key) - (score.get(key) == null ? 0 : score.get(key))));
            }
            score = m;
            if (max_diff <= min_diff) break;
        }

    排序后的投票结果:

    [程序员=1.9249977,
    人员=1.6290349,
    分为=1.4027836,
    程序=1.4025855,
    高级=0.9747374,
    软件=0.93525416,
    中国=0.93414587,
    特别=0.93352026,
    维护=0.9321688,
    专业=0.9321688,
    系统=0.885048,
    编码=0.82671607,
    界限=0.82206935,
    开发=0.82074183,
    分析员=0.77101076,
    项目=0.77101076,
    英文=0.7098714,
    设计=0.6992446,
    经理=0.64640945]

    程序员果然荣登榜首,并且分数也有区分度,嗯,勉勉强强。

    本文参考自TextRank算法提取关键词的Java实现HanLP

    展开全文
  • 从Page_ranktext_rank的摘要提取 text-rank结果优化和完整的代码可见我的github 链接:https://github.com/ouprince/text-rank 1.关于page-rank page_rank本为解决网页和网页之间的关系,计算网页重要性而提出...
  • https://www.cnblogs.com/clover-siyecao/p/5726480.html 介绍了textrank。   不过我觉得对于长文本,textrank才有用些。短文本的话,估计没有那么多条边。  
  • TextRank

    千次阅读 2019-02-26 11:43:52
    TextRank与PageRank TextRank的灵感来源于大名鼎鼎的PageRank算法,这是一个用作网页重要度排序的算法。 这个算法是基于图的,每个网页可以看作是一个图中的结点,如果网页A能够跳转到网页B,那么则有一条A-&...
  • 简易关键词提取,自动摘要代码,运行速度快
  • 版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 ...
  • TextRank算法详解

    千次阅读 2018-06-22 10:19:40
    TextRank算法是基于Google的PageRank算法的改进。PageRank学习链接TextRank学习链接两个问题:TextRank怎么能最后收敛?可以转化成马尔科夫链。TextRank计算的结果是否可以在决策树中当做权重进行使用?...
  • TextRank学习笔记

    千次阅读 2018-11-04 10:38:41
    TextRank起源与PageRank TextRank的灵感来源于大名鼎鼎的PageRank算法,这是一个用作网页重要度排序的算法。 并且,这个算法也是基于图的,每个网页可以看作是一个图中的结点,如果网页A能够跳转到网页B,那么则有一...
  • 深度学习----NLP-TextRank算法详解

    千次阅读 2019-01-04 10:47:20
    TextRank算法提取关键词3. TextRank算法提取关键词短语4. TextRank生成摘要5. 共现矩阵 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;~~~~~~~~&nbsp;&nbsp;&...
  • TextRank算法

    万次阅读 2016-06-25 00:29:22
    TextRank算法基于PageRank,用于为文本生成关键字和摘要。
  • TextRank算法的基本原理及textrank4zh使用实例

    万次阅读 多人点赞 2018-05-18 17:28:51
    TextRank算法是一种文本排序算法,由谷歌的网页重要性排序算法PageRank算法改进而来,它能够从一个给定的文本中提取出该文本的关键词、关键词组,并使用抽取式的自动文摘方法提取出该文本的关键句。其提出论文是: ...
  • TextRank算法原理简析、代码实现

    千次阅读 2019-05-23 17:40:19
      在介绍TextRank前,我想先给大家介绍下PageRank,实质上个人认为可以把TextRank当做PageRank2.0。   谷歌的两位创始人的佩奇和布林,借鉴了学术界评判学术论文重要性的通用方法,“那就是看论文的引用次数”...
  • textrank算法-python实现

    2018-04-03 10:18:02
    这是一个基于python实现的textrank算法 python版本:2.7.14 文件夹‘candidates’和‘conferences’是数据集 文件夹‘keywords-candidates-textrank’和‘可以words-conferences-textrank’存放运行结果 运行: ...
  • TextRank 算法是一种用于文本的基于图的排序算法。其基本思想来源于谷歌的 PageRank算法, 通过把文本分割成若干组成单元(单词、句子)并建立图模型, 利用投票机制对文本中的重要成分进行排序, 仅利用单篇文档本身的...
  • TextRank算法抽取关键词

    万次阅读 2017-09-17 21:38:40
    PageRank由于TextRank是由大名鼎鼎的Google的PageRank算法转化而来,所以这里先介绍一下PageRank算法。PageRank最开始用来计算网页的重要性。在衡量一个网页的排名时,直觉告诉我们: (1)一个网页被更多网页链接...
  • 该PDF是英文版的,主要介绍了TextRank算法的实现
  • TextRank算法总结

    万次阅读 2017-02-14 10:28:59
    TextRank算法总结 最近在调研自动生成文本方面的内容,突然想到了自动文摘里的textRank,这里我将参考了一些资料并对这些知识点进行了整理总结,初步总结如下: 目录PageRank简介 基于TextRank的关键词提取 基于...
  • TF-IDF算法和TextRank算法的分析比较

    万次阅读 2017-08-31 15:52:50
    TF-IDF算法 TF-IDF(词频-逆文档频率)算法是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中...
  • TextRank 算法是一种用于文本的基于图的排序算法。其基本思想来源于谷歌的 PageRank算法(其原理在本文在下面), 通过把文本分割成若干组成单元(单词、句子)并建立图模型, 利用投票机制对文本中的重要成分进行排序, ...
  • textrank算法介绍

    2018-04-25 13:58:16
    TextRank算法TextRank算法基于PageRank,用于为文本生成关键字和摘要。其论文是: Mihalcea R, Tarau P. TextRank: Bringing order into texts[C]. Association for Computational Linguistics, 2004.先从PageRank...
  • 分词TextRank算法解读

    千次阅读 2018-02-01 22:25:58
    ​ 利用计算机将大量的文本进行处理,产生简洁、精炼内容的过程就是文本摘要,人们可通过阅读摘要来把握文本主要内容,这不仅大大节省时间,更提高阅读效率。但人工摘要耗时又耗力,已不能满足日益增长的信息需求,...
  • textRank算法原理介绍与摘要提取

    千次阅读 2018-10-30 20:17:06
    版权声明:本文为博主原创文章,未经博主允许不得转载。 ... TextRankTextRank 公式在 PageRank 公式的基础上,为图中的边引入...
  • 参考论文:Rada Mihalcea《TextRank:Bring Order into texts》。 TextRank将文本中的语法单元视作图中的节点,如果两个语法单元存在一定语法关系(例如共现),则这两个语法单元在图中就会有一条边相互连接,通过...
  • 上文说了PageRank的实现方式,一鼓作气, 这次就把TextRank的原理和实现方式写一写 TextRank的产生来自于PageRank,中心思想是一样的,只不过在PageRank里,网页与网页的关系,在TextRank里变成了词与词的关系。 ...
  • TextRank算法的改进及在政法全文检索系统中的应用,TextRank算法是受PageRank算法的启示
  • 作者:Prateek Joshi翻译:王威力校对:丁楠雅本文约3300字,建议阅读10分钟。本文介绍TextRank算法及其在多篇单领域文本数据中抽取句子组成摘要中的应用...
  • 使用TextRank算法为文本生成关键字和摘要 发表于1年前(2014-12-01 21:31) 阅读(10282) | 评论(27) 155人收藏此文章, 我要收藏 赞15 摘要 TextRank算法基于PageRank,用于为文本生成关键字和...

空空如也

1 2 3 4 5 ... 20
收藏数 27,151
精华内容 10,860
关键字:

textrank