基於TextRank提取關鍵詞、關鍵短語、摘要

1、TextRank原理

TextRank是一種用來作關鍵詞提取的算法,也能夠用於提取短語和自動摘要。由於TextRank是基於PageRank的,因此首先簡要介紹下PageRank算法。html

1. PageRank算法

  PageRank設計之初是用於Google的網頁排名的,以該公司創辦人拉里·佩奇(Larry Page)之姓來命名。Google用它來體現網頁的相關性和重要性,在搜索引擎優化操做中是常常被用來評估網頁優化的成效因素之一。PageRank經過互聯網中的超連接關係來肯定一個網頁的排名,其公式是經過一種投票的思想來設計的:若是咱們要計算網頁A的PageRank值(如下簡稱PR值),那麼咱們須要知道有哪些網頁連接到網頁A,也就是要首先獲得網頁A的入鏈,而後經過入鏈給網頁A的投票來計算網頁A的PR值。這樣設計能夠保證達到這樣一個效果:當某些高質量的網頁指向網頁A的時候,那麼網頁A的PR值會由於這些高質量的投票而變大,而網頁A被較少網頁指向或被一些PR值較低的網頁指向的時候,A的PR值也不會很大,這樣能夠合理地反映一個網頁的質量水平。那麼根據以上思想,佩奇設計了下面的公式:git

 

該公式中,Vi表示某個網頁,Vj表示連接到Vi的網頁(即Vi的入鏈),S(Vi)表示網頁Vi的PR值,In(Vi)表示網頁Vi的全部入鏈的集合,Out(Vj)表示網頁,d表示阻尼係數,是用來克服這個公式中「d *」後面的部分的固有缺陷用的:若是僅僅有求和的部分,那麼該公式將沒法處理沒有入鏈的網頁的PR值,由於這時,根據該公式這些網頁的PR值爲0,但實際狀況卻不是這樣,全部加入了一個阻尼係數來確保每一個網頁都有一個大於0的PR值,根據實驗的結果,在0.85的阻尼係數下,大約100屢次迭代PR值就能收斂到一個穩定的值,而當阻尼係數接近1時,須要的迭代次數會陡然增長不少,且排序不穩定。公式中S(Vj)前面的分數指的是Vj全部出鏈指向的網頁應該平分Vj的PR值,這樣纔算是把本身的票分給了本身連接到的網頁。github

2. TextRank算法

2.1 TextRank算法提取關鍵詞

  TextRank是由PageRank改進而來,其公式有頗多類似之處,這裏給出TextRank的公式:算法

      

能夠看出,該公式僅僅比PageRank多了一個權重項Wji,用來表示兩個節點之間的邊鏈接有不一樣的重要程度。TextRank用於關鍵詞提取的算法以下:ide

  1)把給定的文本T按照完整句子進行分割,即  函數

  2)對於每一個句子,進行分詞和詞性標註處理,並過濾掉停用詞,只保留指定詞性的單詞,如名詞、動詞、形容詞,即,其中 ti,j 是保留後的候選關鍵詞。優化

  3)構建候選關鍵詞圖G = (V,E),其中V爲節點集,由(2)生成的候選關鍵詞組成,而後採用共現關係(co-occurrence)構造任兩點之間的邊,兩個節點之間存在邊僅當它們對應的詞彙在長度爲K的窗口中共現,K表示窗口大小,即最多共現K個單詞。搜索引擎

  4)根據上面公式,迭代傳播各節點的權重,直至收斂。spa

  5)對節點權重進行倒序排序,從而獲得最重要的T個單詞,做爲候選關鍵詞。.net

  6)由5獲得最重要的T個單詞,在原始文本中進行標記,若造成相鄰詞組,則組合成多詞關鍵詞。

2.2 TextRank算法提取關鍵詞短語

  提取關鍵詞短語的方法基於關鍵詞提取,能夠簡單認爲:若是提取出的若干關鍵詞在文本中相鄰,那麼構成一個被提取的關鍵短語。

2.3 TextRank生成摘要

  將文本中的每一個句子分別看作一個節點,若是兩個句子有類似性,那麼認爲這兩個句子對應的節點之間存在一條無向有權邊。考察句子類似度的方法是下面這個公式:

   

公式中,Si,Sj分別表示兩個句子,Wk表示句子中的詞,那麼分子部分的意思是同時出如今兩個句子中的同一個詞的個數,分母是對句子中詞的個數求對數之和。分母這樣設計能夠遏制較長的句子在類似度計算上的優點。

咱們能夠根據以上類似度公式循環計算任意兩個節點之間的類似度,根據閾值去掉兩個節點之間類似度較低的邊鏈接,構建出節點鏈接圖,而後計算TextRank值,最後對全部TextRank值排序,選出TextRank值最高的幾個節點對應的句子做爲摘要。

參考:

http://www.javashuo.com/article/p-orynkjst-p.html

http://blog.csdn.net/u013041398/article/details/52473994

 

2、包安裝

sudo pip install textrank4zh

 

3、提取關鍵詞、關鍵短語、摘要

from textrank4zh import TextRank4Keyword, TextRank4Sentence

text = "xxxxxx"  # text = codecs.open(text_file, "r", "utf-8").read()

tr4w = TextRank4Keyword()
tr4w.analyze(text=text, window=5, lower=True)

print "關鍵詞:"
for item in tr4w.get_keywords(num=20, word_min_len=1):
    print item.word, item.weight

print "關鍵短語:\n", ", ".join(tr4w.get_keyphrases(keywords_num=20, min_occur_num=2))

tr4s = TextRank4Sentence()
tr4s.analyze(text=text, lower=True, source="all_filters")

print "摘要:"
for item in tr4s.get_key_sentences(num=3):
    print item.index, item.weight, item.sentence   # index是語句在文本中位置,weight是權重

 

查看源碼,TextRank4Keyword的說明:

class TextRank4Keyword(object):    
    def __init__(self, stop_words_file = None, 
                 allow_speech_tags = util.allow_speech_tags, 
                 delimiters = util.sentence_delimiters):
        """
        Keyword arguments:
        stop_words_file  --  str,指定中止詞文件路徑(一行一箇中止詞),若爲其餘類型,則使用默認中止詞文件
        delimiters       --  默認值是`?!;?!。;…\n`,用來將文本拆分爲句子。
        
        Object Var:
        self.words_no_filter      --  對sentences中每一個句子分詞而獲得的兩級列表。
        self.words_no_stop_words  --  去掉words_no_filter中的中止詞而獲得的兩級列表。
        self.words_all_filters    --  保留words_no_stop_words中指定詞性的單詞而獲得的兩級列表。
        """
        
    def analyze(self, text, 
                window = 2, 
                lower = False,
                vertex_source = 'all_filters',
                edge_source = 'no_stop_words',
                pagerank_config = {'alpha': 0.85,}):
        """分析文本
        Keyword arguments:
        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'`。關鍵詞也來自`vertex_source`。
        edge_source     --  選擇使用words_no_filter, words_no_stop_words, words_all_filters中的哪個來構造pagerank對應的圖中的節點之間的邊。
                            默認值爲`'no_stop_words'`,可選值爲`'no_filter', 'no_stop_words', 'all_filters'`。邊的構造要結合`window`參數。
        """
        
    def get_keywords(self, num = 6, word_min_len = 1):
        """獲取最重要的num個長度大於等於word_min_len的關鍵詞。
        Return:
        關鍵詞列表。
        """
    
    def get_keyphrases(self, keywords_num = 12, min_occur_num = 2): 
        """獲取關鍵短語。
        獲取 keywords_num 個關鍵詞構造的可能出現的短語,要求這個短語在原文本中至少出現的次數爲min_occur_num。
        Return:
        關鍵短語的列表。
        """      

 

TextRank4Sentence的說明:

class TextRank4Sentence(object):
    def __init__(self, stop_words_file = None, 
                 allow_speech_tags = util.allow_speech_tags,
                 delimiters = util.sentence_delimiters):
        """
        Keyword arguments:
        stop_words_file  --  str,中止詞文件路徑,若不是str則是使用默認中止詞文件
        delimiters       --  默認值是`?!;?!。;…\n`,用來將文本拆分爲句子。
        
        Object Var:
        self.sentences               --  由句子組成的列表。
        self.words_no_filter         --  對sentences中每一個句子分詞而獲得的兩級列表。
        self.words_no_stop_words     --  去掉words_no_filter中的中止詞而獲得的兩級列表。
        self.words_all_filters       --  保留words_no_stop_words中指定詞性的單詞而獲得的兩級列表。
        """
        
    def analyze(self, text, lower = False, 
              source = 'no_stop_words', 
              sim_func = util.get_similarity,
              pagerank_config = {'alpha': 0.85,}):
        """
        Keyword arguments:
        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             --  指定計算句子類似度的函數。
        """
            
    def get_key_sentences(self, num = 6, sentence_min_len = 6):
        """獲取最重要的num個長度大於等於sentence_min_len的句子用來生成摘要。
        Return:
        多個句子組成的列表。
        """

 

參考:

letiantian/TextRank4ZH: 從中文文本中自動提取關鍵詞和摘要

實踐篇:基於TFIDF和TextRank的關鍵詞提取

相關文章
相關標籤/搜索