ML基礎——讓人腦殼疼的中文分詞算法

2021-02-13 TechFlow

在前文當中,我們介紹了搜尋引擎的大致原理。有錯過或者不熟悉的同學,可以點擊下方的連結回顧一下前文的內容。

在介紹爬虫部分的時候,我們知道,爬蟲在爬取到網頁的內容之後,會先進行一些處理。首先要做的就是過濾掉HTML當中的各種標籤信息,只保留最原生的網頁內容。之後,程序會對這些文本內容提取關鍵詞

今天我們就來講講關鍵詞提取當中最重要的一個部分——中文分詞

在世界上眾多的語言當中,中文算是比較特殊的一種。許多語言自帶分詞信息,比如英文,機器學習寫作machine learning。machine和learning之間自帶一個空格作為分隔。但是中文不是這樣,漢字之間沒有任何分隔符。意味著程序沒有辦法直接對文本進行分割。

那麼我們怎麼知道「機器學習」這四個字應該分割成機器和學習而不是機和器學習或者是機器學和習呢?

這就需要中文分詞算法。

目前常用的分詞算法主要分為兩大類,一種是基於詞表的規則分詞算法。另一種則是在機器學習以及深度學習興起之後流行起來的統計分詞算法。我們先從比較容易理解的規則分詞算法開始講起。

規則分詞算法的核心是詞表,我們維護一個儘可能大的詞表, 當中儘可能多的包含各種中文的詞語。在切分語句的時候,我們將句子當中的每個短語都去詞表當中檢索。如果能夠檢索到,說明這的確是一個詞語,則進行切分,否則則不切分。

這個很好理解對吧,我們繼續往下。

但是我們切分語句的時候,其實有兩種順序,既可以正向切分,也可以反向切分。根據切分方向的不同,產生了兩種比較類似的算法。

  正向最大匹配算法  


正向最大匹配算法的思路非常簡單,我們每次儘量找儘可能長的詞語。假設中文的詞庫當中最長的詞語長度是n個字,那麼我們每次從文本的前n個字開始查找詞表, 如果找到了,那麼顯然這n個字就是一個單獨的單詞。如果沒找到,那麼縮減一位,查找前n-1個字,如此循環往復,直到在詞表當中找到單詞為止。

這時候, 我們從匹配結束的位置繼續往下,一直到整個句子分詞完畢。整個過程非常簡單,理論上來說我們人類閱讀句子的時候,就是按照這個順序。但是這個算法並不是完美的,當中隱藏著問題。

舉個最經典的例子,假設當前的句子是「南京市長江大橋」。假設我們詞庫當中單詞的最長長度是5,那麼我們第一次切分的結果是「南京市長江」,詞表當中並沒有這個詞,於是會切分「南京市長」,詞表當中的確有這個詞,那麼整個句子就會切分成「南京市長」和「江大橋」這兩個部分。如果「江大橋」不被當做人名,那麼會繼續切分成「」和「大橋」。

這顯然是不對的,會發生這個問題的原因也很簡單,因為中文當中存在歧義。尤其是摻雜人名的時候,因為人名數不勝數,不可能都包容在詞表當中。如果真的包容了,也會很有問題。

  逆向最大匹配算法  

為了解決正向匹配算法當中的問題,人們又想出了逆向最大匹配算法。思路和正向匹配幾乎一模一樣,僅僅將切分的順序從前面開始改成了從後面開始而已。

每次我們獲取句子當中最後n個字,進行詞表匹配。如果沒有匹配中,那麼去掉這n個字當中的第一個字,將後面的n-1個字繼續匹配。直到能匹配上為止。

在實際應用當中,正相匹配的錯誤率約為1/169,而逆向匹配的錯誤率為1/245,顯然逆向匹配要更好一些。這也是有原因的,因為漢語當中偏正短語較多,詞語的重心往往落在後面,比如之前的」南京市長江大橋「如果按照逆向匹配,就很容易識別出」南京市「和」長江大橋「了。

當然和正向匹配一樣,逆向匹配也不是完美的,同樣存在許多反例

  雙向最大匹配  

雙向最大匹配的原理也很簡單,就是將正向和負向結合起來。互相各取所長,因為這兩種算法的切分思路剛好相反,從邏輯上來看是存在互補的可能的。

實際上也的確如此,根據研究顯示,約有90%的中文句子,正向和逆向的切分結果是完全匹配並且正確的。大約有9%的句子是兩個算法結果不一致,並且是有一種是正確的。只有1%不到的句子,兩個算法的結果都錯誤的。

算法的思路也很簡單,就是將正向匹配和逆向匹配的結果進行對比。如果一致,那麼直接就認為是正確答案,如果不一致,則選擇其中切分出來單詞數量較少的。

比如前文當中」南京市長江大橋「兩種切分結果分別是」南京「,「市長」,「江」,「大橋」和「南京市」,「長江大橋」,那麼算法會選擇後者。

  統計分詞算法  

基於統計的分詞算法也不難理解,我們用統計學中出現的概率來代表分詞方案的正確性

假設句子是T,一種分詞方案是。那麼

顯然,我們要計算出當中所有的條件概率是不可能的,因為參數空間太大數據過於稀疏

不過好在我們可以進行化簡,理論上來說當前句子某個位置會出現什麼單詞,可能和其他所有單詞都有關係。但是我們可以簡化這個關係,我們可以簡單認為每個單詞之和之前出現的兩個詞語有關

也就是說,

這樣樣本空間大大減少,我們枚舉可能存在的分詞情況,通過統計的方法找到其中出現概率最大的值即可。

  深度學習分詞算法  

在深度學習普及了之後, 市面上出現了許多種基於深度學習的中文分詞算法。本文選擇其中最簡單的一種作為介紹。

目前常用的模型是BiLSTM,即雙向的LSTM模型。LSTM模型的好處是可以學到時間序列的信息,在文本當中,能夠學習到上下文直接詞語的內在聯繫。BiLSTM是雙向LSTM模型,既考慮了句子的正序,也考慮了句子的逆序,有些類似於前文當中說的雙向最大匹配算法

模型的輸入是一個句子當中所有漢字向量化的集合,有點類似於Word2vec的做法(這裡看不懂的同學可以跳過,後面會有專門介紹Word2vec的文章),以及每個字的類別。每個字的類別一共有四種,分別是s(single),即單字成詞,b(begin),某個詞語的開始,m(middle),某個詞語的中間部分和e(end),即每個詞語的結尾。

預測的時候,模型一樣讀入每個字對應的embedding,模型的預測結果是每個字屬於每個類別的概率。最後,根據模型的預測結果,對整個文本完成分詞。和之前幾種算法相比,這種算法的準確率更高,但是它也有自己的問題。最大的問題是非常依賴人工標註的結果,想要模型有好的結果,需要的訓練樣本量非常大,因此帶來的人力成本很高。中文分詞是非常小的一個點,但是卻至關重要,凡事和文本有關的領域都離不開它。好在絕大多數情況下,我們並不需要自己手動實現分詞算法,因為如今市面上已經有了許多免費開源的分詞引擎,像是著名的庖丁、jieba等等。不過儘管如此,深入了解其中的算法原理,依然很有必要。如果覺得文章有所幫助,請轉發或者點擊下方的「在看」,你們的支持是我最好的回報。

相關焦點

  • 中文分詞算法技術的原理和理論運用
    現在的計劃是等新站全部的展示樣式出來之後,便會進行整體大框架規劃,包括老站,而這裡想說的就是關於分詞技術理論的簡單介紹。分詞技術就是搜尋引擎針對用戶提交查詢的關鍵詞串進行的查詢處理後根據用戶的關鍵詞串用各種匹配方法進行分詞的一種技術。由於國內主要以中文搜尋引擎為主,這裡的分詞技術為中文分詞技術。
  • 海量新聞信息處理中的中文分詞算法研究
    但是我們知道,分析中文的信息,除了要有良好的數據處理能力,還有一個非常重要的方面就是中文的自然語言處理能力。 我們知道,基於網絡輿情監控風險評估系統的算法是基於WEB文本挖掘一些基本的模型與算法:如TF-IDF模型,關聯規則的Apriori算法,監督學習中SVM算法等等。
  • 【分詞】從why到how的中文分詞詳解,從算法原理到開源工具
    中的"Hey"和"you"是需要與身後的標點分隔開的為什麼需要分詞?能不能不分詞?中文分詞難在哪?從古至今的分詞算法:詞典到預訓練從中到外的分詞工具對於中文來說,如果不進行分詞,那麼神經網絡將直接基於原始的漢字序列進行處理和學習。
  • 為什麼中文分詞比英文分詞更難?有哪些常用算法?(附代碼)
    如在以下例子中,兩種分拆方式代表的語義都有可能:南京市|長江|大橋南京|市長|江大橋為了解決分詞中的歧義性,許多相關算法被提出並在實踐中取得了很好的效果。下面將對中文分詞和英文分詞進行介紹。01 中文分詞在漢語中,句子是單詞的組合。
  • 【NLP】為什麼中文分詞比英文分詞更難?有哪些常用算法?(附代碼)
    如在以下例子中,兩種分拆方式代表的語義都有可能:南京市|長江|大橋南京|市長|江大橋為了解決分詞中的歧義性,許多相關算法被提出並在實踐中取得了很好的效果。下面將對中文分詞和英文分詞進行介紹。01 中文分詞在漢語中,句子是單詞的組合。
  • 【結巴分詞】淺談結巴分詞算法原理
    dict.txt文件一覽在基於詞典的中文分詞方法中,詞典匹配算法是基礎。為了保證切分速度,需要選擇一個好的查找詞典算法。這裡介紹詞典的Tre樹組織結構。一些人可能會想到把dict.txt中所有的詞彙全部刪掉,然後再試試結巴能不能分詞。結果會發現,結巴依然能夠分詞,不過分出來的詞,大部分的長度為2。這個就是第三條的任務,基於HMM來預測分詞了,我們得會兒再說。
  • NLP的中文分詞面試指南
    在NLP領域裡,中文分詞對於處在中文語言環境的我們來說,是基礎中的基礎,核心中的核心,涉及到的知識點覆蓋面很廣。所以很多關於NLP的面試中都會問到中文分詞的問題,很多NLP任務都依賴中文分詞的結果,同時中文分詞所使用的技術可以很好的應用到其它領域,比如:語音識別、實體識別等等。
  • 淺談結巴分詞算法原理
    dict.txt文件一覽在基於詞典的中文分詞方法中,詞典匹配算法是基礎。為了保證切分速度,需要選擇一個好的查找詞典算法。一些人可能會想到把dict.txt中所有的詞彙全部刪掉,然後再試試結巴能不能分詞。結果會發現,結巴依然能夠分詞,不過分出來的詞,大部分的長度為2。這個就是第三條的任務,基於HMM來預測分詞了,我們得會兒再說。
  • 中文分詞文章索引和分詞數據資源分享
    ,除了基於深度學習的分詞方法還沒有探討外,「古典」機器學習時代的中文分詞方法都有涉及,從基於詞典的中文分詞(最大匹配法),到基於統計的分詞方法(HMM、最大熵模型、條件隨機場模型CRF),再到Mecab、NLTK中文分詞,都有所涉及。
  • 分詞|Python最好的中文分詞庫
    在使用這個庫之前,我相信有很多的讀者一定很想知道jieba背後的工作原理,jieba具體應用的算法如下:基於前綴詞典實現高效的詞圖掃描,生成句子中漢字所有可能成詞情況所構成的有向無環圖 (DAG);採用了動態規劃查找最大概率路徑, 找出基於詞頻的最大切分組合;對於未登錄詞,採用了基於漢字成詞能力的 HMM 模型,使用了 Viterbi 算法。
  • 【分詞】中文分詞的古今中外,你想知道的都在這裡
    中的"Hey"和"you"是需要與身後的標點分隔開的為什麼需要分詞?能不能不分詞?中文分詞難在哪?從古至今的分詞算法:詞典到預訓練從中到外的分詞工具對於中文來說,如果不進行分詞,那麼神經網絡將直接基於原始的漢字序列進行處理和學習。
  • nodejs 中文分詞模塊 node-segment
    模塊以盤古分詞組件中的詞庫為基礎,算法設計也部分參考了盤古分詞組件中的算法。
  • 技術專欄-結巴中文分詞介紹
    內容導讀結巴中文分詞涉及到的算法包括: (1) 基於Trie樹結構實現高效的詞圖掃描,生成句子中漢字所有可能成詞情況所構成的有向無環圖(DAG); (2) 採用了動態規劃查找最大概率路徑, 找出基於詞頻的最大切分組合; (3) 對於未登錄詞,採用了基於漢字成詞能力的HMM模型,使用了Viterbi算法。
  • jieba - 最好的 Python 中文分詞組件
    搜尋引擎模式:在精確模式的基礎上,對長詞再次切分,提高召回率,適合用於搜尋引擎分詞。paddle模式: 利用PaddlePaddle深度學習框架,訓練序列標註(雙向GRU)網絡模型實現分詞。jieba安裝jieba提供了幾種安裝模式。
  • 手把手教你用Jieba做中文分詞
    Jieba並不是只有分詞這一個功能,它是一個開源框架,提供了很多在分詞之上的算法,如關鍵詞提取、詞性標註等。Jieba官方提供了Python、C++、Go、R、iOS等多平臺多語言支持,不僅如此,還提供了很多熱門社區項目的擴展插件,如ElasticSearch、solr、lucene等。在實際項目中,使用Jieba進行擴展十分容易。
  • 資源 | Python中文分詞工具大合集
    安裝這些模塊其實很簡單,只要按官方文檔的方法安裝即可,以下做個簡單介紹,主要是在Python3.x & Ubuntu16.04 的環境下測試及安裝這些中文分詞器。再附加介紹12款其他的中文分詞工具或者中文分詞模塊,最後的兩款fnlp和ansj是比較棒的java中文分詞工具,貌似還沒有python接口,記錄一下。這些中文分詞工具我沒有測試,感興趣的同學可以動手試試。
  • 中文分詞工具評估:chinese-segmentation-evaluation
    專欄地址:http://www.52nlp.cn/author/tiandiweizun中文分詞工具評估項目地址:https:這裡有一個Java開源項目cws_evaluation,對中文分詞做了評比,但有幾點不足:(1). 只有java版本,但是機器學習主要是基於python的 (2).效果指標為行完美率和字完美率,該指標不妥,特別是句子越長,越無意義,(3). 每種分詞工具評測的算法太多了,這裡僅評比了默認的分詞算法。
  • NLP快速入門:手把手教你用HanLP做中文分詞
    中文分詞技術作為中文自然語言處理的第一項核心技術,是眾多上層任務的首要基礎工作,同時在日常的工作中起著基礎性的作用。本文將講解如何在Python環境下調用HanLP包進行分詞,並結合Python語言簡約的特性,實現一行代碼完成中文分詞。
  • R | 教程 jiebaR中文分詞
    導言jiebaR是"結巴"中文分詞的R語言版本,支持最大概率法(Maximum Probability),隱式馬爾科夫模型(Hidden Markov Model),索引模型(QuerySegment),混合模型(MixSegment),共四種分詞模式。本次推送將介紹R中jiebaR程序包關於中文分詞的具體方法。
  • 中文分詞之HMM模型詳解
    (viterbi算法)參數(ObservedSet)已知的情況下,求解(TransProbMatrix,EmitRobMatrix,InitStatus)。(Baum-Welch算法)其中,第三種問題最玄乎也最不常用,第二種問題最常用,【中文分詞】,【語音識別】, 【新詞發現】, 【詞性標註】 都有它的一席之地。