中文分詞概述及結巴分詞原理


詞是中文表達語義的最小單位,自然語言處理的基礎步驟就是分詞,分詞的結果對中文信息處理至為關鍵。

本文先對中文分詞方法進行一下概述,然后簡單講解一下結巴分詞背后的原理。

 

中文分詞概述

 

簡單來說,中文分詞根據實現特點大致可分為兩個類別:

基於詞典的分詞方法、基於統計的分詞方法。

 

基於詞典的分詞方法

 

基於詞典的分詞方法首先會建立一個充分大的詞典,然后依據一定的策略掃描句子,若句子中的某個子串與詞典中的某個詞匹配,則分詞成功。

常見的掃描策略有:正向最大匹配、逆向最大匹配、雙向最大匹配和最少詞數分詞。

 

正向最大匹配

對輸入的句子從左至右,以貪心的方式切分出當前位置上長度最大的詞,組不了詞的字單獨划開。其分詞原理是:詞的顆粒度越大,所能表示的含義越精確。

 

逆向最大匹配

原理與正向最大匹配相同,但順序不是從首字開始,而是從末字開始,而且它使用的分詞詞典是逆序詞典,其中每個詞條都按逆序方式存放。在實際處理時,先將句子進行倒排處理,生成逆序句子,然后根據逆序詞典,對逆序句子用正向最大匹配。

 

雙向最大匹配

將正向最大匹配與逆向最大匹配組合起來,對句子使用這兩種方式進行掃描切分,如果兩種分詞方法得到的匹配結果相同,則認為分詞正確,否則,按最小集處理。

 

最少詞數分詞

即一句話應該分成數量最少的詞串,該方法首先會查找詞典中最長的詞,看是不是所要分詞的句子的子串,如果是則切分,然后不斷迭代以上步驟,每次都會在剩余的字符串中取最長的詞進行分詞,最后就可以得到最少的詞數。

 

總結:基於詞典的分詞方法簡單、速度快,效果也還可以,但對歧義和新詞的處理不是很好,對詞典中未登錄的詞沒法進行處理。

 

基於統計的分詞方法

 

基於統計的分詞方法是從大量已經分詞的文本中,利用統計學習方法來學習詞的切分規律,從而實現對未知文本的切分。隨着大規模語料庫的建立,基於統計的分詞方法不斷受到研究和發展,漸漸成為了主流。

常用的統計學習方法有:隱馬爾可夫模型(HMM)、條件隨機場(CRF)和基於深度學習的方法。

 

HMM和CRF

這兩種方法實質上是對序列進行標注,將分詞問題轉化為字的分類問題,每個字有4種詞位(類別):詞首(B)、詞中(M)、詞尾(E)和單字成詞(S)。由字構詞的方法並不依賴於事先編制好的詞典,只需對分好詞的語料進行訓練即可。當模型訓練好后,就可對新句子進行預測,預測時會針對每個字生成不同的詞位。其中HMM屬於生成式模型,CRF屬於判別式模型。

 

基於深度學習的方法

神經網絡的序列標注算法在詞性標注、命名實體識別等問題上取得了優秀的進展,這些端到端的方法也可以遷移到分詞問題上。與所有深度學習的方法一樣,該方法需要較大的訓練語料才能體現優勢,代表為BiLSTM-CRF。

 

總結:基於統計的分詞方法能很好地處理歧義和新詞問題,效果比基於詞典的要好,但該方法需要有大量人工標注分好詞的語料作為支撐,訓練開銷大,就分詞速度而言不如前一種。

 

在實際應用中一般是將詞典與統計學習方法結合起來,既發揮詞典分詞切分速度快的特點,又利用了統計分詞結合上下文識別生詞、自動消除歧義的優點。結巴分詞正是這一類的代表,下面簡要介紹一下它的實現算法。

 

結巴分詞原理

 

官方Github上對所用算法的描述為:

基於前綴詞典實現高效的詞圖掃描,生成句子中漢字所有可能成詞情況所構成的有向無環圖 (DAG);

采用了動態規划查找最大概率路徑, 找出基於詞頻的最大切分組合;

對於未登錄詞,采用了基於漢字成詞能力的 HMM 模型,使用了 Viterbi 算法。

下面逐一介紹:

 

構造前綴詞典

結巴分詞首先會依照統計詞典dict.txt構造前綴詞典。dict.txt含有近35萬的詞條,每個詞條占用一行,其中每一行有3列,第一列為詞條,第二列為對應的詞頻,第三列為詞性,構造前綴詞典需要用到前兩列。

具體做法為:首先定義一個空的python字典,然后遍歷dict.txt的每一行,取詞條作為字典的鍵,詞頻作為對應的鍵值,然后遍歷該詞條的前綴,如果前綴對應的鍵不在字典里,就把該前綴設為字典新的鍵,對應的鍵值設為0,如果前綴在字典里,則什么都不做。

這樣等遍歷完dict.txt后,前綴詞典就構造好了。在構造前綴詞典時,會對統計詞典里所有詞條的詞頻做一下累加,累加值等計算最大概率路徑時會用到。

 

生成有向無環圖(DAG)

用正則表達式分割句子后,對每一個單獨的子句會生成一個有向無環圖。

具體方式為:先定義一個空的python字典,然后遍歷子句,當前子句元素的索引會作為字典的一個鍵,對應的鍵值為一個python列表(初始為空),然后會以當前索引作為子串的起始索引,不斷向后遍歷生成不同的子串,如果子串在前綴詞典里且鍵值不為0的話,則把子串的終止索引添加到列表中。

這樣等遍歷完子句的所有字后,對應的DAG就生成好了。(子串的鍵值如果是0,則說明它不是一個詞條)

 

計算最大概率路徑

DAG的起點到終點會有很多路徑,需要找到一條概率最大的路徑,然后據此進行分詞。可以采用動態規划來求解最大概率路徑。

具體來說就是:從子句的最后一個字開始,倒序遍歷子句的每個字,取當前字對應索引在DAG字典中的鍵值(一個python列表),然后遍歷該列表,當前字會和列表中每個字兩兩組合成一個詞條,然后基於詞頻計算出當前字到句尾的概率,以python元組的方式保存最大概率,元祖第一個元素是最大概率的對數,第二個元素為最大概率對應詞條的終止索引。

詞頻可看作DAG中邊的權重,之所以取概率的對數是為了防止數值下溢。有了最大概率路徑,分詞結果也就隨之確定。

 

對未登錄詞采用HMM模型進行分詞

當出現沒有在前綴詞典里收錄的詞時,會采用HMM模型進行分詞。HMM模型有5個基本組成:觀測序列、狀態序列、狀態初始概率、狀態轉移概率和狀態發射概率。分詞屬於HMM的預測問題,即已知觀測序列、狀態初始概率、狀態轉移概率和狀態發射概率的條件下,求狀態序列。結巴分詞已經內置了訓練好的狀態初始概率、狀態轉移概率和狀態發射概率。

句子會作為觀測序列,當有新句子進來時,具體做法為:先通過Viterbi算法求出概率最大的狀態序列,然后基於狀態序列輸出分詞結果(每個字的狀態為B、M、E、S之一)。

 

至此,結巴分詞的原理就簡單介紹完了。

 

最后舉一個簡單的例子:

假如待分詞的句子為: “這幾天都在學自然語言處理”。

首先依據前綴詞典生成DAG:

{  0: [0],

   1: [1, 2],

   2: [2, 3],

   3: [3],

   4: [4],

   5: [5],

   6: [6, 7, 9],

   7: [7],

   8: [8, 9],

   9: [9],

  10: [10, 11],

  11: [11]  }

句子元素對應的索引會作為字典的鍵,對應鍵值的第一項與當前索引相同,其余項會與當前索引組成詞條,這個詞條在前綴詞典里且對應鍵值不為0。

生成的DAG如下:

 

然后采用動態規划求出的最大概率路徑為:

{12: (0, 0),

 11: (-9.073726763747516, 11),

 10: (-8.620554852761583, 11),

  9: (-17.35315508178225, 9),

  8: (-17.590039287472578, 9),

  7: (-27.280113467960604, 7),

  6: (-22.70346658402771, 9),

  5: (-30.846092652642497, 5),

  4: (-35.25970621827743, 4),

  3: (-40.95138241952608, 3),

  2: (-48.372244833381465, 2),

  1: (-50.4870755319817, 2),

  0: (-55.92332690525722, 0)}

最大概率路徑按句子索引倒序排列,但分詞時會從索引0開始順序遍歷句子。

具體做法為:

首先遍歷0,0對應的鍵值最后一項為0,即詞的長度為1,遇到長度為1的詞時(即單字)先不分,繼續往后看,然后遍歷1,1對應的鍵值最后一項為2,即詞的長度為2,這時會把索引為0的單字作為詞分割出來,然后接着把索引1、2對應的詞分割出來,然后遍歷3,3對應的鍵值最后一項為3,屬於單字,先不分,索引4、5同理,然后遍歷6,6對應的鍵值最后一項為9,即詞的長度為4,注意,這里索引3、4、5對應的單字序列(即“都在學”)如果不在前綴詞典中或者在前綴詞典中但鍵值為0,則會對單字序列采用HMM模型進行分詞,否則的話,會對單字序列每個字進行分詞,分好之后把索引6、7、8、9對應的詞分割出去,然后遍歷10,10對應的鍵值最后一項為11,即詞的長度為2,直接把索引10、11對應的詞分割出去,至此分詞結束。

 

總結一下:

在遇到長度>=2的詞之前會把它前面出現的所有單字保存下來。

如果保存下來的單字序列長度為0,則直接把當前詞分割出去;

如果保存下來的單字序列長度為1,則直接把單字作為詞分割出去,然后把后面詞分割出去;

如果保存下來的單字序列長度>1,會分兩種情況:假如單字序列不在前綴詞典中或者在前綴詞典中但鍵值為0,則會對單字序列采用HMM模型進行分詞,否則的話,會對單字序列每個字進行分詞。

 

最后分好的詞為:['這',  '幾天',  '都',  '在',  '學',  '自然語言',  '處理']。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM