TD-IDF是基于詞頻的算法,而TextRank是基于圖 形的算法。
TextRank是受到PageRank算法的啟發(fā)。
PageRank主要用于對在線搜索結(jié)果中的網(wǎng)頁進(jìn)行排序。
PageRank對于每個網(wǎng)頁頁面都給出一個正實數(shù),表示網(wǎng)頁的重要程度,PageRank值越高,表示網(wǎng)頁越重要,在互聯(lián)網(wǎng)搜索的排序中越可能被排在前面。同樣,被鏈接的網(wǎng)頁的PageRank值也會相應(yīng)的因此而提高。
假設(shè)整個互聯(lián)網(wǎng)是一個有向圖,節(jié)點(diǎn)是網(wǎng)頁,每條邊是轉(zhuǎn)移概率。網(wǎng)頁瀏覽者在每個頁面上依照連接出去的超鏈接,以等概率跳轉(zhuǎn)到下一個網(wǎng)頁,并且在網(wǎng)頁上持續(xù)不斷地進(jìn)行這樣的隨機(jī)跳轉(zhuǎn),這個過程形成了一階馬爾科夫鏈,比如下圖:
PageRank的核心公式是PageRank值的計算公式。公式如下:
其中,PR(Vi)表示結(jié)點(diǎn)Vi的rank值,In(Vi)表示結(jié)點(diǎn)Vi的前驅(qū)結(jié)點(diǎn)集合,Out(Vj)表示結(jié)點(diǎn)Vj的后繼結(jié)點(diǎn)集合。
這個公式來自于《統(tǒng)計學(xué)習(xí)方法》,等號右邊的平滑項(通過某種處理,避免一些突變的畸形值,盡可能接近實際情況)不是(1-d),而是(1-d)/n。
阻尼系數(shù)d(damping factor)的意義是,在任意時刻,用戶到達(dá)某頁面后并繼續(xù)向后瀏覽的概率。1-d就是用戶停止點(diǎn)擊,隨機(jī)跳到新URL的概率。
加平滑項是因為有些網(wǎng)頁沒有跳出去的鏈接,那么轉(zhuǎn)移到其他網(wǎng)頁的概率將會是0,這樣就無法保證存在馬爾科夫鏈的平穩(wěn)分布。
于是,我們假設(shè)網(wǎng)頁以等概率(1/n)跳轉(zhuǎn)到任何網(wǎng)頁,再按照阻尼系數(shù)d,對這個等概率(1/n)與存在鏈接的網(wǎng)頁的轉(zhuǎn)移概率進(jìn)行線性組合,那么馬爾科夫鏈一定存在平穩(wěn)分布,一定可以得到網(wǎng)頁的PageRank值。
所以PageRank的定義意味著網(wǎng)頁瀏覽者按照以下方式在網(wǎng)上隨機(jī)游走:以概率d按照存在的超鏈接隨機(jī)跳轉(zhuǎn),以等概率從超鏈接跳轉(zhuǎn)到下一個頁面;或以概率(1-d)進(jìn)行完全隨機(jī)跳轉(zhuǎn),這時以等概率(1/n)跳轉(zhuǎn)到任意網(wǎng)頁。
PageRank的計算是一個迭代過程,先假設(shè)一個初始的PageRank分布,通過迭代,不斷計算所有網(wǎng)頁的PageRank值,直到收斂為止,也就是:
和基于詞頻( TF-IDF )相比,TextRank進(jìn)一步考慮了文檔內(nèi)詞條之間的語義關(guān)系。 也就是說考慮到額這個詞條的上下文,如果這個詞的上下文都是一些很重要的詞,那么這個詞大概率也是很重要的詞。
基本原理:
TextRank
TextRank 算法是一種用于文本的基于圖的排序算法。其基本思想來源于谷歌的 PageRank算法, 通過把文本分割成若干組成單元(單詞、句子)并建立圖模型, 利用投票機(jī)制對文本中的重要成分進(jìn)行排序, 僅利用單篇文檔本身的信息即可實現(xiàn)關(guān)鍵詞提取、文摘。和 LDA、HMM 等模型不同, TextRank不需要事先對多篇文檔進(jìn)行學(xué)習(xí)訓(xùn)練, 因其簡潔有效而得到廣泛應(yīng)用。
TextRank 一般模型可以表示為一個有向有權(quán)圖 G =(V, E), 由點(diǎn)集合 V和邊集合 E 組成, E 是V ×V的子集。圖中任兩點(diǎn) Vi , Vj 之間邊的權(quán)重為 wji , 對于一個給定的點(diǎn) Vi, In(Vi) 為 指 向 該 點(diǎn) 的 點(diǎn) 集 合 , Out(Vi) 為點(diǎn) Vi 指向的點(diǎn)集合。點(diǎn) Vi 的得分定義如下:
其中, d 為阻尼系數(shù), 取值范圍為 0 到 1, 代表從圖中某一特定點(diǎn)指向其他任意點(diǎn)的概率, 一般取值為 0.85。使用TextRank 算法計算圖中各點(diǎn)的得分時, 需要給圖中的點(diǎn)指定任意的初值, 并遞歸計算直到收斂, 即圖中任意一點(diǎn)的誤差率小于給定的極限值時就可以達(dá)到收斂, 一般該極限值取 0.0001。
1. 基于TextRank的關(guān)鍵詞提取
關(guān)鍵詞抽取的任務(wù)就是從一段給定的文本中自動抽取出若干有意義的詞語或詞組。TextRank算法是利用局部詞匯之間關(guān)系(共現(xiàn)窗口)對后續(xù)關(guān)鍵詞進(jìn)行排序,直接從文本本身抽取。其主要步驟如下:
?。?)把給定的文本T按照完整句子進(jìn)行分割,即
?。?)對于每個句子
?。?)構(gòu)建候選關(guān)鍵詞圖G = (V,E),其中V為節(jié)點(diǎn)集,由(2)生成的候選關(guān)鍵詞組成,然后采用共現(xiàn)關(guān)系(co-occurrence)構(gòu)造任兩點(diǎn)之間的邊,兩個節(jié)點(diǎn)之間存在邊僅當(dāng)它們對應(yīng)的詞匯在長度為K的窗口中共現(xiàn),K表示窗口大小,即最多共現(xiàn)K個單詞。
(4)根據(jù)上面公式,迭代傳播各節(jié)點(diǎn)的權(quán)重,直至收斂。
?。?)對節(jié)點(diǎn)權(quán)重進(jìn)行倒序排序,從而得到最重要的T個單詞,作為候選關(guān)鍵詞。
?。?)由(5)得到最重要的T個單詞,在原始文本中進(jìn)行標(biāo)記,若形成相鄰詞組,則組合成多詞關(guān)鍵詞。例如,文本中有句子“Matlab code for plotting ambiguity function”,如果“Matlab”和“code”均屬于候選關(guān)鍵詞,則組合成“Matlab code”加入關(guān)鍵詞序列。
from gensim.corpora import Dictionary import wordcloud import pandas as pd import jieba import jieba.analyse import matplotlib.pyplot as plt from nltk.corpus import brown from sklearn.feature_extraction.text import CountVectorizer # 數(shù)據(jù)準(zhǔn)備 # ============================================================================================================ # raw = pd.read_table('./金庸-射雕英雄傳txt精校版.txt',names=['txt'],encoding='GBK') # print(raw) # 加入章節(jié)標(biāo)識 # 章節(jié)判斷用變量預(yù)處理 def m_head(tmpstr): return tmpstr[:1] #取第一個字 def m_mid(tmpstr): return tmpstr.find("回 ") # 用apply函數(shù)將下面的屬性加入到對應(yīng)列 raw['head'] = raw.txt.apply(m_head) raw['mid'] = raw.txt.apply(m_mid) raw['len'] = raw.txt.apply(len) # 章節(jié)判斷 chapnum = 0 for i in range(len(raw)): if raw['head'][i] == "第" and raw['mid'][i] >0 and raw['len'][i]<30: chapnum += 1 if chapnum >= 40 and raw['txt'][i] == "附錄一:成吉思汗家族": chapnum=0 raw.loc[i,'chap'] = chapnum # 刪除臨時變量 del raw['head'] del raw['mid'] del raw['len'] # 段落聚合 根據(jù)章節(jié)聚合 rawgrp = raw.groupby('chap') chapter = rawgrp.agg(sum) chapter = chapter[chapter.index != 0] # 設(shè)定分詞以及清理停用詞函數(shù) # 先用pandas將停用詞讀出,存到變量w中,最后取出w,轉(zhuǎn)為list stoplist = list(pd.read_csv('停用詞.txt',names=['w'],sep='aaa',encoding='utf-8',engine='python').w) # 清理停用詞哈數(shù) def m_cut(intxt): return [w for w in jieba.cut(intxt) if w not in stoplist and len(w)>1] countvec = CountVectorizer() analyze = countvec.build_analyzer() # 使用空格分開 t = analyze('郭靖 和 哀牢山 三十六 劍 。') # 默認(rèn)刪去停用詞列表中的詞和符號 print(t) # ['郭靖', '哀牢山', '三十六'] # # ============================================================================================================ # 數(shù)據(jù)準(zhǔn)備結(jié)束 # TextRank算法的jieba實現(xiàn) # 對射雕英雄傳的第一章進(jìn)行關(guān)鍵詞抓取,取前20個 t = jieba.analyse.textrank( chapter.txt[1], topK=20,#詞頻前20 withWeight=True ) # 默認(rèn)是過濾詞性的 也就是allowPOS=('ns','n','vn','v') 默認(rèn)值 print(t) # 這個結(jié)果和前面的TF-IDF結(jié)果差異較大,因為TextRank算法過濾掉了一些詞性,只保留了名詞和動詞 # [('官兵', 1.0), ('武官', 0.9334143199050102), ('丘處機(jī)', 0.7358359699167335), ('娘子', 0.6744231421648419), ('丈夫', 0.5830294283456839), ('金兵', 0.5781198085682175), ('臨安', 0.5770670188243039), ('說道', 0.5770566609658306), ('小人', 0.5090129786491732), ('只見', 0.4571074590990817), ('皇帝', 0.44602714989497655), ('出來', 0.44153726005111005), ('妻子', 0.3806600930485957), ('道人', 0.37477396448704836), ('道長', 0.3700338339927484), ('百姓', 0.326847924487172), ('短劍', 0.30052710293852547), ('雙手', 0.29602787925127344), ('心想', 0.29137224579945303), ('貧道', 0.28869640746976294)]