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

2022-09-11 06:03:12 字數 3944 閱讀 2681

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

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

中文分詞概述

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

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

基於詞典的分詞方法

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

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

正向最大匹配

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

逆向最大匹配

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

雙向最大匹配

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

最少詞數分詞

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

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

基於統計的分詞方法

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

常用的統計學習方法有:隱馬爾可夫模型(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。

生成的dag如下:

然後採用動態規劃求出的最大概率路徑為:

最大概率路徑按句子索引倒序排列,但分詞時會從索引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模型進行分詞,否則的話,會對單字序列每個字進行分詞。

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

python中文分詞 結巴分詞

中文分詞是中文文字處理的乙個基礎性工作,結巴分詞利用進行中文分詞。其基本實現原理有三點 基於trie樹結構實現高效的詞圖掃瞄,生成句子中漢字所有可能成詞情況所構成的有向無環圖 dag 採用了動態規劃查詢最大概率路徑,找出基於詞頻的最大切分組合 對於未登入詞,採用了基於漢字成詞能力的hmm模型,使用了...

結巴中文分詞

人工智慧領域文字分類中最基本的就是分詞,分詞中最基礎的莫過於結巴分詞。分詞,顧名思義就是把一句話劃分成若干的詞語,只不過如今我們是讓電腦自動進行分詞。結巴中文分詞支援的三種模式分別為 1.全模式 把句子中所有成詞的詞語都掃瞄出來,速度非常快,但不能消除歧義。分詞結果 jieba.cut 文字名稱,c...

python中文分詞工具 結巴分詞jieba

支援三種分詞模式 精確模式,試圖將句子最精確地切開,適合文字分析 全模式,把句子中所有的可以成詞的詞語都掃瞄出來,速度非常快,但是不能解決歧義 搜尋引擎模式,在精確模式的基礎上,對長詞再次切分,提高召回率,適合用於搜尋引擎分詞。支援繁體分詞 支援自定義詞典 基於字首詞典實現高效的詞圖掃瞄,生成句子中...