自然語言處理工具hanlp關鍵詞提取圖解TextRank演算法
看一個博主(亞當 -adam)的關於hanlp關鍵詞提取演算法TextRank的文章,還是非常好的一篇實操經驗分享,分享一下給各位需要的朋友一起學習一下!
TextRank是在Google的PageRank演算法啟發下,針對文字里的句子設計的權重演算法,目標是自動摘要。它利用投票的原理,讓每一個單詞給它的鄰居(術語稱視窗)投贊成票,票的權重取決於自己的票數。這是一個“先有雞還是先有蛋”的悖論,PageRank採用矩陣迭代收斂的方式解決了這個悖論。 本博文通過 hanlp關鍵詞提取的一個Demo,並通過圖解的方式來講解TextRank的演算法。
1 //長句子
2 String content = "程式設計師(英文Programmer)是從事程式開發、維護的專業人員。" +
3 "一般將程式設計師分為程式設計人員和程式編碼人員," +
4 "但兩者的界限並不非常清楚,特別是在中國。" +
5 "軟體從業人員分為初級程式設計師、高階程式設計師、系統" +
6 "分析員和專案經理四大類。";
最後提取的關鍵詞是: [程式設計師, 程式, 分為, 人員, 軟體]
下面來分析為什麼會提取出這5個關鍵詞
第一步:分詞
把 content 通過一個的分詞演算法進行分詞,這裡採用的是Viterbi演算法也就是HMM演算法 。 分詞後(當然首先應把停用詞、標點、副詞之類的去除)的結果是:
[程式設計師, 英文, Programmer, 從事, 程式, 開發, 維護, 專業, 人員, 程式設計師, 分為, 程式, 設計, 人員, 程式, 編碼, 人員, 界限, 並不, 非常, 清楚, 特別是在, 中國, 軟體, 從業人員, 分為, 程式設計師, 高階, 程式設計師, 系統分析員, 專案經理, 四大]
第二步:構造視窗
hanlp的實現程式碼如下:
Map<String, Set<String>> words = new TreeMap<String, Set<String>>();
Queue<String> que = new LinkedList<String>();
for (String w : wordList)
{
if (!words.containsKey(w))
{
words.put(w, new TreeSet<String>());
}
// 複雜度O(n-1)
if (que.size() >= 5)
{
que.poll();
}
for (String qWord : que)
{
if (w.equals(qWord))
{
continue;
}
//既然是鄰居,那麼關係是相互的,遍歷一遍即可
words.get(w).add(qWord);
words.get(qWord).add(w);
}
que.offer(w);
}
這個程式碼的功能是為分個詞構造視窗,這個詞前後各四個詞就是這個詞的視窗,如詞分詞後一個詞出現了多次,像 [程式設計師],那就是把每次出現取一次視窗,然後把各次結果合併去重,最後結果是: 程式設計師 =[Programmer, 專業, 中國, 人員, 從業人員, 從事, 分為, 四大, 開發, 程式, 系統分析員, 維護, 英文, 設計, 軟體, 專案經理, 高階]。 最後形成的視窗:
1 Map<String, Set<String>> words =
2
3 {Programmer=[從事, 開發, 程式, 程式設計師, 維護, 英文], 專業=[人員, 從事, 分為, 開發, 程式, 程式設計師, 維護], 中國=[從業人員, 分為, 並不, 清楚, 特別是在, 程式設計師, 軟體, 非常], 人員=[專業, 分為, 並不, 開發, 清楚, 界限, 程式, 程式設計師, 維護, 編碼, 設計, 非常], 從業人員=[中國, 分為, 清楚, 特別是在, 程式設計師, 軟體, 高階], 從事=[Programmer, 專業, 開發, 程式, 程式設計師, 維護, 英文], 分為=[專業, 中國, 人員, 從業人員, 特別是在, 程式, 程式設計師, 系統分析員, 維護, 設計, 軟體, 高階], 四大=[程式設計師, 系統分析員, 專案經理, 高階], 並不=[中國, 人員, 清楚, 特別是在, 界限, 程式, 編碼, 非常], 開發=[Programmer, 專業, 人員, 從事, 程式, 程式設計師, 維護, 英文], 清楚=[中國, 人員, 從業人員, 並不, 特別是在, 界限, 軟體, 非常], 特別是在=[中國, 從業人員, 分為, 並不, 清楚, 界限, 軟體, 非常], 界限=[人員, 並不, 清楚, 特別是在, 程式, 編碼, 非常], 程式=[Programmer, 專業, 人員, 從事, 分為, 並不, 開發, 界限, 程式設計師, 維護, 編碼, 英文, 設計], 程式設計師=[Programmer, 專業, 中國, 人員, 從業人員, 從事, 分為, 四大, 開發, 程式, 系統分析員, 維護, 英文, 設計, 軟體, 專案經理, 高階], 系統分析員=[分為, 四大, 程式設計師, 專案經理, 高階], 維護=[Programmer, 專業, 人員, 從事, 分為, 開發, 程式, 程式設計師], 編碼=[人員, 並不, 界限, 程式, 設計, 非常], 英文=[Programmer, 從事, 開發, 程式, 程式設計師], 設計=[人員, 分為, 程式, 程式設計師, 編碼], 軟體=[中國, 從業人員, 分為, 清楚, 特別是在, 程式設計師, 非常, 高階], 非常=[中國, 人員, 並不, 清楚, 特別是在, 界限, 編碼, 軟體], 專案經理=[四大, 程式設計師, 系統分析員, 高階], 高階=[從業人員, 分為, 四大, 程式設計師, 系統分析員, 軟體, 專案經理]}
第三步:迭代投票
每個詞最後的投票得分由這個詞的視窗進行多次迭代投票決定,迭代的結束條件就是大於最大迭代次數這裡是 200次,或者兩輪之前某個詞的權重小於某一值這裡是0.001f。看下程式碼:
Map<String, Float> score = new HashMap<String, Float>();
//依據TF來設定初值
for (Map.Entry<String, Set<String>> entry : words.entrySet()){
score.put(entry.getKey(),sigMoid(entry.getValue().size()));
}
System.out.println(score);
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 element : value)
{
int size = words.get(element).size();
if (key.equals(element) || size == 0) continue;
m.put(key, m.get(key) + d / size * (score.get(element) == null ? 0 : score.get(element)));
}
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;
}
System.out.println(score);
return score;
}
投票的原理拿 Programmer=[從事, 開發, 程式, 程式設計師, 維護, 英文],這個詞來說明,Programmer最後的得分是由[從事, 開發, 程式, 程式設計師, 維護, 英文],這6個詞依次投票決定的,每個詞投出去的分數是和他本身的權重相關的。
1、投票開始前每個詞初始化了一個權重, score.put(entry.getKey(),sigMoid(entry.getValue().size())),這個權重是0到1之間,公式是
1 //value是每個詞視窗的大小
2 public static float sigMoid(float value) {
3 return (float)(1d/(1d+Math.exp(-value)));
4 }
這個函式的公式和影像如下 ,因為value一定是大於0的,所以sigMod值屬於(0,1)
初始化後的分詞是: {特別是在=0.99966466, 程式設計師=0.99999994, 編碼=0.99752736, 四大=0.98201376, 英文=0.9933072, 非常=0.99966466, 界限=0.99908894, 系統分析員=0.9933072, 從業人員=0.99908894, 程式=0.99999774, 專業=0.99908894, 專案經理=0.98201376, 設計=0.9933072, 從事=0.99908894, Programmer=0.99752736, 軟體=0.99966466, 人員=0.99999386, 清楚=0.99966466, 中國=0.99966466, 開發=0.99966466, 並不=0.99966466, 高階=0.99908894, 分為=0.99999386, 維護=0.99966466}
進行迭代投票,第一輪投票, [Programmer, 專業, 中國, 人員, 從業人員, 從事, 分為, 四大, 開發, 程式, 系統分析員, 維護, 英文, 設計, 軟體, 專案經理, 高階]依給次*程式設計師*投票,得分如下:
[Programmer]給[程式設計師]投票後,[]程式設計師]的得分:
[專業]給[程式設計師]投票
這樣 [Programmer, 專業, 中國, 人員, 從業人員, 從事, 分為, 四大, 開發, 程式, 系統分析員, 維護, 英文, 設計, 軟體, 專案經理, 高階]依次給[程式設計師]投票,投完票後,再給其它的詞進行投票,本輪結束後,判斷是否達到最大迭代次數200或兩輪之間分數差值小於0.001,如果滿足則結束,否則繼續進行迭代。
最後的投票得分是: {特別是在=1.0015739, 程式設計師=2.0620303, 編碼=0.78676623, 四大=0.6312981, 英文=0.6835063, 非常=1.0018439, 界限=0.88890904, 系統分析員=0.74232763, 從業人員=0.8993066, 程式=1.554001, 專業=0.88107216, 專案經理=0.6312981, 設計=0.6702926, 從事=0.9027207, Programmer=0.7930236, 軟體=1.0078223, 人員=1.4288887, 清楚=0.9998723, 中國=0.99726284, 開發=1.0065585, 並不=0.9968608, 高階=0.9673803, 分為=1.4548829, 維護=0.9946941},分數最高的關鍵詞就是要提取的關鍵詞
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31524777/viewspace-2636423/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 自然語言處理工具hanlp自定義詞彙新增圖解自然語言處理HanLP圖解
- HanLP 自然語言處理 for nodejsHanLP自然語言處理NodeJS
- HanLP 關鍵詞提取演算法分析詳解HanLP演算法
- NLP自然語言處理中的hanlp分詞例項自然語言處理HanLP分詞
- Hanlp自然語言處理中的詞典格式說明HanLP自然語言處理
- Hanlp自然語言處理工具之詞法分析器HanLP自然語言處理詞法分析
- 入門自然語言處理必看:圖解詞向量自然語言處理圖解
- 配置Hanlp自然語言處理進階HanLP自然語言處理
- 自然語言處理工具hanlp定製使用者詞條自然語言處理HanLP
- 自然語言處理工具HanLP-N最短路徑分詞自然語言處理HanLP分詞
- 自然語言處理:分詞方法自然語言處理分詞
- 開源自然語言處理工具包hanlp中CRF分詞實現詳解自然語言處理HanLPCRF分詞
- hanlp自然語言處理包的基本使用--pythonHanLP自然語言處理Python
- python呼叫自然語言處理工具hanlp記錄Python自然語言處理HanLP
- Hanlp自然語言處理工具的使用演練HanLP自然語言處理
- 自然語言處理之jieba分詞自然語言處理Jieba分詞
- 詞!自然語言處理之詞全解和Python實戰!自然語言處理Python
- 如何編譯執行HanLP自然語言處理包編譯HanLP自然語言處理
- 自然語言處理工具包HanLP的Python介面自然語言處理HanLPPython
- 中文自然語言處理工具hanlp隱馬角色標註詳解自然語言處理HanLP
- 自然語言處理NLP(6)——詞法分析自然語言處理詞法分析
- 自然語言處理工具python呼叫hanlp的方法步驟自然語言處理PythonHanLP
- 自然語言處理入門基礎之hanlp詳解自然語言處理HanLP
- hanlp自然語言處理包的人名識別程式碼解析HanLP自然語言處理
- Spring Boot中對自然語言處理工具包hanlp的呼叫詳解Spring Boot自然語言處理HanLP
- 自然語言處理工具python呼叫hanlp中文實體識別自然語言處理PythonHanLP
- 自然語言處理工具pyhanlp分詞與詞性標註自然語言處理HanLP分詞詞性標註
- NPL---自然語言處理單詞界定問題自然語言處理
- Pyhanlp自然語言處理中的新詞識別HanLP自然語言處理
- 自然語言處理之:搭建基於HanLP的開發環境自然語言處理HanLP開發環境
- 自然語言處理(NLP)路線圖 - kdnuggets自然語言處理
- 自然語言處理中的分詞問題總結自然語言處理分詞
- Python 自然語言處理(基於jieba分詞和NLTK)Python自然語言處理Jieba分詞
- 12 種自然語言處理的開源工具自然語言處理開源工具
- 自然語言處理工具包 HanLP在 Spring Boot中的應用自然語言處理HanLPSpring Boot
- 自然語言處理工具HanLP-基於層疊HMM地名識別自然語言處理HanLPHMM地名識別
- 自然語言處理工具hanlp 1.7.3版本更新內容一覽自然語言處理HanLP
- 自然語言處理(NLP)系列(一)——自然語言理解(NLU)自然語言處理