今天介紹的內容是最短路徑分詞。最近換回了thinkpad x1,緣由是mac的13.3寸的屏幕看代碼實在是不方便,也多是人老了吧,^_^。等把HanLP詞法分析介紹結束後,仍是會換回macbook pro的。我的有強迫症,只要看或寫Java或C/C++代碼或者用開發機的化,仍是喜歡在windows下工做。看論文特別是理論的研究仍是習慣用mac了。感受開發仍是windows比較順手,理論研究仍是mac比較順手。java
基本思想:首先根據詞典,找出字串中全部可能的詞(也稱全切分),而後構造詞語切分有向無環圖(也稱做粗分詞圖或粗分詞網)。每一個詞對應圖中的一條有向邊。若賦給相應的邊長一個權值(該權值能夠是常數,也能夠是所構成的詞的屬性值),而後根據該切分圖,在起點到終點的全部路徑中,求出長度值(包括權值)爲最短的一條路徑,這條路徑上包含的詞就是該句子的切分結果。若每一個結點處記錄N個最短路徑值,則該方法也稱N-最短路徑算法。node
爲進一步提升切分精度,在詞典中增長詞的屬性值,即給每一個詞也給權重。這樣每一個詞在漢字串中的權重不一樣(即構成的有向圖的邊不爲等長)。最簡單的詞的權重能夠用詞頻表示,高頻詞的權重大,低頻詞的權重小。具體的權重值能夠經過大規模語料庫得到。git
雖然HanLP中提供了dijkstra算法的實現,可是當前HanLP中最短路徑分詞使用的是viterbi算法。github
例子:他說的確實在理算法
遍歷計算過程和回溯分詞過程windows
(1) node列與to列blog
node列的詞語爲粗分詞網中全部的詞,to列爲在node列爲詞word_node的狀況下,後邊接的全部可能的詞word_to。第1個詞語前邊有一個「始」詞,最後一個詞語後邊有一個「末」詞。開發
(2) begin2node_w的計算macbook
表示從「始」到node詞的最短路徑權值。能夠從待計算值所在行的node列讀取出word詞,在to列中以待計算值所在行開始向上查找word,找到word所在行後(以首次遇到的詞爲準),begin2to_w列所對應的值就是待計算值。見圖中下劃線。第一個詞對「始-他」的begin2node_w的值爲0。it
(3) node2to_w的計算
由node+w構成的2gram串的機率,也就是轉移機率,計算公式爲
計算的HanLP代碼爲https://github.com/hankcs/HanLP/blob/master/src/main/java/com/hankcs/hanlp/utility/MathUtility.java calculateWeight(Vertex from, Vertex to)。「始」的頻次取爲MAX_FREQUENCY,「始-他」的共現頻次值爲「他」做爲句首的頻次,「理-末」的共現頻次值爲「理」做爲句末的頻次。
(4) begin2to_w_n的計算
表示從「始」到to詞的最短路徑權值。begin2to_w_n = begin2node_w + node2to_w。
(5) begin2to_w_o
表示記錄在to詞下的,到to詞的最短路徑權值,它的初始值爲0,以後由begin2to_w來更新。
(6) from
表示詞語to的前驅詞。
能夠看錶中(7,9),(8,10),(11,13),(12,14),(15,16),(17,18)成對行來驗證該公式,其中只有(17.18)行知足了第3個式子。
(6)和(7)的HanLP實現代碼https://github.com/hankcs/HanLP/blob/master/src/main/java/com/hankcs/hanlp/seg/common/Vertex.java updateFrom(Vertex from)
(8) 回溯肯定分詞路徑
從「末」開始向前回溯,末->理->在->確實->的->說->他,能夠看錶中黃色單元格進行驗證。
通過(6)、(7)兩步,能夠確保粗分詞網中任意詞的前驅都是最短路徑的。
遍歷計算過程和回溯過程的HanLP代碼https://github.com/hankcs/HanLP/blob/master/src/main/java/com/hankcs/hanlp/seg/Viterbi/ViterbiSegment.java viterbi(WordNet wordNet)