深度學習將會變革NLP中的中文分詞

 2016-08-08 19:03:00.0

雷鋒網按:本文轉自ResysChina高翔,文章主要介紹了1)區分中文分詞的方法;2)用深度學習的方法來解決中文分詞的好處及其具體應用。


現有分詞介紹

自然語言處理(NLP,Natural Language Processing)是一個信息時代最重要的技術之一,簡單來講,就是讓計算機能夠理解人類語言的一種技術。在其中,分詞技術是一種比較基礎的模塊。對於英文等拉丁語系的語言而言,由於詞之間有空格作爲詞邊際表示,詞語一般情況下都能簡單且準確的提取出來。而中文日文等文字,除了標點符號之外,字之間緊密相連,沒有明顯的詞邊界,因此很難將詞提取出來。分詞的意義非常大,在中文中,單字作爲最基本的語義單位,雖然也有自己的意義,但表意能力較差,意義較分散,而詞的表意能力更強,能更加準確的描述一個事物,因此在自然語言處理中,通常情況下詞(包括單字成詞)是最基本的處理單位。在具體的應用上,比如在常用的搜索引擎中,term如果是詞粒度的話,不僅能夠減少每個term的倒排列表長度,提升系統性能,並且召回的結果相關性高更準確。比如搜索query「的確」,如果是單字切分的話,則有可能召回「你講的確實在理」這樣的doc。分詞方法大致分爲兩種:基於詞典的機械切分,基於統計模型的序列標註切分兩種方式。

基於詞典的方法

基於詞典的方法本質上就是字符串匹配的方法,將一串文本中的文字片段和已有的詞典進行匹配,如果匹配到,則此文字片段就作爲一個分詞結果。但是基於詞典的機械切分會遇到多種問題,最爲常見的包括歧義切分問題和未登錄詞問題

1. 歧義切分

歧義切分指的是通過詞典匹配給出的切詞結果和原來語句所要表達的意思不相符或差別較大,在機械切分中比較常見,比如下面的例子:「結婚的和尚未結婚的人」,通過機械切分的方式,會有兩種切分結果:1,「結婚/的/和/尚未/結婚/的/人」;2,「結婚/的/和尚/未/結婚/的/人」。可以明顯看出,第二種切分是有歧義的,單純的機械切分很難避免這樣的問題。

2. 未登錄詞識別

未登錄詞識別也稱作新詞發現,指的是詞沒有在詞典中出現,比如一些新的網絡詞彙,如「網紅」,「走你」;一些未登錄的人名,地名;一些外語音譯過來的詞等等。基於詞典的方式較難解決未登錄詞的問題,簡單的case可以通過加詞典解決,但是隨着字典的增大,可能會引入新的bad case,並且系統的運算複雜度也會增加。

3. 基於詞典的機械分詞改進方法

爲了解決歧義切分的問題,在中文分詞上有很多優化的方法,常見的包括正向最大匹配,逆向最大匹配,最少分詞結果,全切分後選擇路徑等多種算法。

4. 最大匹配方法

正向最大匹配指的是從左到右對一個字符串進行匹配,所匹配的詞越長越好,比如「中國科學院計算研究所」,按照詞典中最長匹配原則的切分結果是:「中國科學院/計算研究所」,而不是「中國/科學院/計算/研究所」。但是正向最大匹配也會存在一些bad case,常見的例子如:「他從東經過我家」,使用正向最大匹配會得到錯誤的結果:「他/從/東經/過/我/家」。

逆向最大匹配的順序是從右向左倒着匹配,如果能匹配到更長的詞,則優先選擇,上面的例子「他從東經過我家」逆向最大匹配能夠得到正確的結果「他/從/東/經過/我/家」。但是逆向最大匹配同樣存在badcase:「他們昨日本應該回來」,逆向匹配會得到錯誤的結果「他們/昨/日本/應該/回來」。

針對正向逆向匹配的問題,將雙向切分的結果進行比較,選擇切分詞語數量最少的結果。但是最少切分結果同樣有bad case,比如「他將來上海」,正確的切分結果是「他/將/來/上海」,有4個詞,而最少切分結果「他/將來/中國」只有3個詞。

5. 全切分路徑選擇方法

全切分方法就是將所有可能的切分組合全部列出來,並從中選擇最佳的一條切分路徑。關於路徑的選擇方式,一般有n最短路徑方法,基於詞的n元語法模型方法等。

n最短路徑方法的基本思想就是將所有的切分結果組成有向無環圖,每個切詞結果作爲一個節點,詞之間的邊賦予一個權重,最終找到權重和最小的一條路徑作爲分詞結果。

基於詞的n元語法模型可以看作是n最短路徑方法的一種優化,不同的是,根據n元語法模型,路徑構成時會考慮詞的上下文關係,根據語料庫的統計結果,找出構成句子最大模型概率。一般情況下,使用unigram和bigram的n元語法模型的情況較多。

基於序列標註的分詞方法

針對基於詞典的機械切分所面對的問題,尤其是未登錄詞識別,使用基於統計模型的分詞方式能夠取得更好的效果。基於統計模型的分詞方法,簡單來講就是一個序列標註問題。

在一段文字中,我們可以將每個字按照他們在詞中的位置進行標註,常用的標記有以下四個label:B,Begin,表示這個字是一個詞的首字;M,Middle,表示這是一個詞中間的字;E,End,表示這是一個詞的尾字;S,Single,表示這是單字成詞。分詞的過程就是將一段字符輸入模型,然後得到相應的標記序列,再根據標記序列進行分詞。舉例來說:「達觀數據位是企業大數據服務商」,經過模型後得到的理想標註序列是:「BMMESBEBMEBME」,最終還原的分詞結果是「達觀數據/是/企業/大數據/服務商」。

在NLP領域中,解決序列標註問題的常見模型主要有HMM和CRF。

HMM

HMM(HiddenMarkov Model)隱馬爾科夫模型應用非常廣泛,基本的思想就是根據觀測值序列找到真正的隱藏狀態值序列。在中文分詞中,一段文字的每個字符可以看作是一個觀測值,而這個字符的詞位置label(BEMS)可以看作是隱藏的狀態。使用HMM的分詞,通過對切分語料庫進行統計,可以得到模型中5大要要素:起始概率矩陣,轉移概率矩陣,發射概率矩陣,觀察值集合,狀態值集合。在概率矩陣中,起始概率矩陣表示序列第一個狀態值的概率,在中文分詞中,理論上M和E的概率爲0。轉移概率表示狀態間的概率,比如B->M的概率,E->S的概率等。而發射概率是一個條件概率,表示當前這個狀態下,出現某個字的概率,比如p(人|B)表示在狀態爲B的情況下人字的概率。

有了三個矩陣和兩個集合後,HMM問題最終轉化成求解隱藏狀態序列最大值的問題,求解這個問題最長使用的是Viterbi算法,這是一種動態規劃算法,具體的算法可以參考維基百科詞條,在此不詳細展開。(https://en.wikipedia.org/wiki/Viterbi_algorithm)

深度學習將會變革NLP中的中文分詞

圖1:HMM模型示意圖

CRF

CRF(Conditionalrandom field,條件隨機場)是用來標註和劃分結構數據的概率化結構模型,通常使用在模式識別和機器學習中,在自然語言處理和圖像處理等領域中得到廣泛應用。和HMM類似,當對於給定的輸入觀測序列X和輸出序列Y,CRF通過定義條件概率P(Y|X),而不是聯合概率分佈P(X,Y)來描述模型。CRF算法的具體算法可以參考維基百科詞條。(https://en.wikipedia.org/wiki/Conditional_random_field)

深度學習將會變革NLP中的中文分詞

圖2:不同概率模型之間的關係及演化圖

在實際應用中有很多工具包可以使用,比如CRF++,CRFsuite,SGD,Wapiti 等,其中CRF++的準確度較高。在分詞中使用CRF++時,主要的工作是特徵模板的配置。CRF++支持unigram,bigram兩種特徵,分別以U和B開頭。舉例來講U00:%x[-2,0]表示第一個特徵,特徵取值是當前字的前方第二個字,U01:%x[-1,0]表示第二個特徵,特徵取值當前字前一個字,U02:%x[0,0]表示第三個特徵,取當前字,以此類推。特徵模板可以支持多種特徵,CRF++會根據特徵模板提取特徵函數,用於模型的建立和使用。特徵模板的設計對分詞效果及訓練時間影響較大,需要分析嘗試找到適用的特徵模板。

深度學習介紹

隨着AlphaGo的大顯神威,Deep Learning(深度學習)的熱度進一步提高。深度學習來源於傳統的神經網絡模型。傳統的神經網絡一般由輸入層,隱藏層,輸出層組成,其中隱藏層的數目按需確定。深度學習可以簡單的理解爲多層神經網絡,但是深度學習的卻不僅僅是神經網絡。深度模型將每一層的輸出作爲下一層的輸入特徵,通過將底層的簡單特徵組合成爲高層的更抽象的特徵來進行學習。在訓練過程中,通常採用貪婪算法,一層層的訓練,比如在訓練第k層時,固定訓練好的前k-1層的參數進行訓練,訓練好第k層之後的以此類推進行一層層訓練。

深度學習將會變革NLP中的中文分詞

圖3:AlphaGo的神經網絡模型的訓練過程及架構

深度學習將會變革NLP中的中文分詞

 圖4:Google Tensorflow官網的神經網絡演示示意圖

深度學習在很多領域都有所應用,在圖像和語音識別領域中已經取得巨大的成功。從2012年開始,LSVRC(LargeScale Visual Recognition Challenge)比賽中,基於Deep Learningd計算框架一直處於領先。2015年LSVRC(http://www.image-net.org/challenges/LSVRC/2015/results)的比賽中,微軟亞洲研究院(MSRA)在圖像檢測(Objectdetection),圖像分類定位(Object Classification+localization)上奪冠,他們使用的神經網絡深達152層。

在NLP中的應用

在自然語言處理上,深度學習在機器翻譯、自動問答、文本分類、情感分析、信息抽取、序列標註、語法解析等領域都有廣泛的應用。2013年末google發佈的word2vec工具,可以看做是深度學習在NLP領域的一個重要應用,雖然word2vec只有三層神經網絡,但是已經取得非常好的效果。通過word2vec,可以將一個詞表示爲詞向量,將文字數字化,更好的讓計算機理解。使word2vec模型,我們可以方便的找到同義詞或聯繫緊密的詞,或者意義相反的詞等。

深度學習將會變革NLP中的中文分詞

圖5:基於微信數據製作的word2vec模型測試: 編程

 深度學習將會變革NLP中的中文分詞

圖6:基於微信數據製作的word2vec模型測試:韋德

詞向量介紹

詞向量的意思就是通過一個數字組成的向量來表示一個詞,這個向量的構成可以有很多種。最簡單的方式就是所謂的one-hot向量。假設在一個語料集合中,一共有n個不同的詞,則可以使用一個長度爲n的向量,對於第i個詞(i=0…n-1),向量index=i處值爲1外,向量其他位置的值都爲0,這樣就可以唯一的通過一個[0,0,1,…,0,0]形式的向量表示一個詞。one-hot向量比較簡單也容易理解,但是有很多問題,比如當加入新詞時,整個向量的長度會改變,並且存在維數過高難以計算的問題,以及向量的表示方法很難體現兩個詞之間的關係,因此一般情況下one-hot向量較少的使用。

如果考慮到詞和詞之間的聯繫,就要考慮詞的共現問題。最簡單的是使用基於文檔的向量表示方法來給出詞向量。基本思想也很簡單,假設有n篇文檔,如果某些詞經常成對出現在多篇相同的文檔中,我們則認爲這兩個詞聯繫非常緊密。對於文檔集合,可以將文檔按順編號(i=0…n-1),將文檔編導作爲向量索引,這樣就有一個n維的向量。當一個詞出現在某個文檔i中時,向量i處值爲1,這樣就可以通過一個類似[0,1,0,…,1,0]形式的向量表示一個詞。基於文檔的詞向量能夠很好的表示詞之間的關係,但是向量的長度和語料庫的大小相關,同樣會存在維度變化問題。

考慮一個固定窗口大小的文本片段來解決維度變化問題,如果在這樣的片段中,兩個詞出現了,就認爲這兩個詞有關。舉例來講,有以下三句話: 「我\喜歡\你」,「我\愛\運動」,「我\愛\攝影」,如果考慮窗口的大小爲1,也就是認爲一個詞只和它前面和後面的詞有關,通過統計共現次數,我們能夠得到下面的矩陣:

深度學習將會變革NLP中的中文分詞

圖7:基於文本窗口共現統計出來的矩陣

可以看到這是一個n*n的對稱矩陣X,這個矩陣的維數會隨着詞典數量的增加而增大,通過SVD(Singular Value Decomposition,奇異值分解),我們可以將矩陣維度降低,但仍存在一些問題: 矩陣X維度經常改變,並且由於大部分詞並不是共現而導致的稀疏性,矩陣維度過高計算複雜度高等問題。

Word2vec是一個多層的神經網絡,同樣可以將詞向量化。在Word2vec中最重要的兩個模型是CBOW(Continuous Bag-of-Word)模型和Skip-gram(Continuous Skip-gram)模型,兩個模型都包含三層: 輸入層,投影層,輸出層。CBOW模型的作用是已知當前詞Wt的上下文環境(Wt-2,Wt-1,Wt+1,Wt+2)來預測當前詞,Skip-gram模型的作用是根據當前詞Wt來預測上下文(Wt-2,Wt-1,Wt+1,Wt+2)。在模型求解中,和一般的機器學習方法類似,也是定義不同的損失函數,使用梯度下降法尋找最優值。Word2vec模型求解中,使用了Hierarchical Softmax方法和NegativeSampling兩種方法。通過使用Word2vec,我們可以方便的將詞轉化成向量表示,讓計算機和理解圖像中的每個點一樣,數字化詞的表現。

LSTM模型介紹

深度學習有很多種不同類型的網絡,在圖像識別領域,CNN(Convolutional Neural Network,卷積神經網絡)使用的較多,而在NLP領域,考慮到上下文的RNN(Recurrent Neural Networks,循環神經網絡)取得了巨大的成功。在傳統的神經網絡中,從輸入層到隱藏層到輸出層,層之間是全連接的,但是每層內部的節點之間是無連接的。因爲這樣的原因,傳統的神經網絡不能利用上下文關係, 而在自然語言處理中,上下文關係非常重要,一個句子中前後詞並不獨立,不同的組合會有不同的意義,比如」優秀」這個詞,如果前面是」不」字,則意義完全相反。RNN則考慮到網絡前一時刻的輸出對當前輸出的影響,將隱藏層內部的節點也連接起來,即當前時刻一個節點的輸入除了上一層的輸出外,還包括上一時刻隱藏層的輸出。RNN在理論上可以儲存任意長度的轉態序列,但是在不同的場景中這個長度可能不同。比如在詞的預測例子中: 1,「他是億萬富翁,他很?」; 2,「他的房子每平米物業費40元,並且像這樣的房子他有十幾套,他很?」。從這兩個句子中我們已經能猜到?代表「有錢」或其他類似的詞彙,但是明顯,第一句話預測最後一個詞時的上線文序列很短,而第二段話較長。如果預測一個詞彙需要較長的上下文,隨着這個距離的增長,RNN將很難學到這些長距離的信息依賴,雖然這對我們人類相對容易。在實踐中,已被證明使用最廣泛的模型是LSTM(Long Short-Term Memory,長短時記憶)很好的解決了這個問題。

LSTM最早由Hochreiter及 Schmidhuber在1997年的論文中提出。首先LSTM也是一種RNN,不同的是LSTM能夠學會遠距離的上下文依賴,能夠存儲較遠距離上下文對當前時間節點的影響。

所有的RNN都有一串重複的神經網絡模塊。對於標準的RNN,這個模塊都比較簡單,比如使用單獨的tanh層。LSTM擁有類似的結構,但是不同的是,LSTM的每個模塊擁有更復雜的神經網絡結構:4層相互影響的神經網絡。在LSTM每個單元中,因爲門結構的存在,對於每個單元的轉態,使得LSTM擁有增加或減少信息的能力。

深度學習將會變革NLP中的中文分詞

圖8:標準RNN模型中的重複模塊包括1層結構

深度學習將會變革NLP中的中文分詞

圖9:LSTM模型中的重複模塊包括4層結構

深度學習庫keras介紹

Keras(http://keras.io)是一個非常易用的深度學習框架,使用python語言編寫,是一個高度模塊化的神經網絡庫,後端同時支持Theano和TensorFlow,而Theano和TensorFlow支持GPU,因此使用keras可以使用GPU加速模型訓練。Keras中包括了構建模型常用的模塊,如Optimizers優化方法模塊,Activations激活函數模塊,Initializations初始化模塊,Layers多種網絡層模塊等,可以非常方便快速的搭建一個網絡模型,使得開發人員可以快速上手,並將精力放在模型設計而不是具體實現上。常見的神經網絡模型如CNN,RNN等,使用keras都可以很快搭建出來,開發人員只需要將數據準備成keras需要的格式丟進網絡訓練即可。如果對keras中自帶的layer有更多的需求,keras還可以自己定製所需的layer。

Keras在NLP中的應用

Keras項目中的example自帶了多個示例,包括經典的mnist手寫識別測試等,其中和NLP相關的示例有很多,比如基於imdb數據的情感分析、文本分類、序列標註等。其中lstm_text_generation.py示例可以用來參考設計序列標註問題,這個示例試圖通過LSTM學習尼采的作品,通過序列標註的思想來訓練一個文本生成器模型。下面着重看一下兩個關鍵點:模型數據格式及模型設計。

訓練數據準備

深度學習將會變革NLP中的中文分詞

這段代碼是數據準備的情況。將尼采全文進行數據切割,每40個字符爲一個片段,將緊接這個片段的字符作爲預測值,來進行訓練。字符片段的間隔爲3。

模型設計

深度學習將會變革NLP中的中文分詞

在模型設計上,主要是使用了兩層LSTM,每層的輸出維度爲512,並在每層LSTM後面加入了Dropout層,來防止過擬合。整個模型的輸入維度是字符類別的個數,輸入字符串長度是40,模型的輸出維度也是字符類別長度。整個模型表達的意思是每輸入40個字符,就會從模型中輸出一個預測的字符。因爲LSTM的對長依賴term的記憶性,因此在上下文很長(40個字符)的情況下也可以表現的很好。

基於深度學習方式的分詞嘗試

基於上面的知識,可以考慮使用深度學習的方法進行中文分詞。分詞的基礎思想還是使用序列標註問題,將一個句子中的每個字標記成BEMS四種label。模型整的輸入是字符序列,輸出是一個標註序列,因此這是一個標準的sequenceto sequence問題。因爲一個句子中每個字的上下文對這個字的label類型影響很大,因此考慮使用RNN模型來解決。

環境介紹

測試硬件是Macbook Pro 2014 Mid高配版,帶NvidiaGT 750M GPU,雖然GPU性能有限,但通過測試性能還是強過mac自帶的i7 CPU。使用GPU進行模型運算,需要安裝Nvidia的cuda相關程序及cuDNN庫,會有較大的性能提升。軟件方面使用python2.7,安裝好了keras,theano及相關庫。關於keras使用GPU訓練的環境搭建問題,可以參考這篇文章(Run Keras on Mac OS with GPU,http://blog.wenhaolee.com/run-keras-on-mac-os-with-gpu/)

模型訓練

模型訓練使用的是經典的bakeoff2005中的微軟研究院的切分語料,將其中的train部分拿過來做訓練,將test作爲最終的測試。

訓練數據準備

首先,將訓練樣本中出現的所有字符全部映射成對應的數字,將文本數字化,形成一個字符到數據的映射。在分詞中,一個詞的label受上下文影響很大,因此參考之前提到的lstm_text_generation.py示例,我們將一個長度爲n個字符的輸入文本處理成n個長度爲k的向量,k爲奇數。舉例來說,當k=7時,表示考慮了一個字前3個字和後三個字的上下文,將這個七個字作爲一個輸入,輸出就是這個字的label類型(BEMS)。

基礎模型建立

參考lstm_text_generation.py 中的模型搭建方式,我們採用一層的LSTM構建網絡,代碼如下,

深度學習將會變革NLP中的中文分詞

其中,輸入的維度input_dim 是字符類別總數,hidden_node 是隱藏層的結點個數。在上面的模型中,第一層輸入層Embedding的作用是將輸入的整數向量化。在現在這個模型中,輸入是一個一維向量,裏面每個值是字符對應的整數,Embedding層就可以將這些整數向量化,簡單來講就是生成了每個字的字向量。接下來緊跟着一層是LSTM,它輸出維度也是隱藏層的結點個數。Dropout層的作用是讓一些神經節點隨機不工作,來防止過擬合現象。Dense層是最後的輸出,這裏nb_classes的數目是4,代表一個字符的label。

模型建立好後開始訓練,重複20次,訓練的結果如下:

深度學習將會變革NLP中的中文分詞

圖10:基礎模型(1層LSTM優化器RMSprop)訓練20次

訓練好後,我們使用msr_test的測試數據進行分詞,並將最終的分詞結果使用icwb2自帶的腳本進行測試,結果如下:

深度學習將會變革NLP中的中文分詞

圖11:基礎模型F Score: 0.845

可以看到基礎模型的F值一般,比傳統的CRF效果差的較多,因此考慮優化模型。

效果改進

模型參數調整

首先想到的是模型參數的調整。Keras官方文檔中提到,RMSprop優化方法在RNN網絡中通常是一個好的選擇,但是在嘗試了其他的優化器後,比如Adam,發現可以取得更好的效果:

深度學習將會變革NLP中的中文分詞

圖12:1層LSTM優化器Adam訓練20次

可以看到,Adam在訓練過程中的精度就已經高於RMSprop,使用icwb2的測試結果爲:

深度學習將會變革NLP中的中文分詞

圖11:修改優化器Adam後的模型F Score: 0.889

模型結構改變

現在網絡結構較簡單,只有一層LSTM,參考文檔示例中的模型設計,考慮使用兩層的LSTM來進行測試,修改後的代碼如下:

深度學習將會變革NLP中的中文分詞

 注意,第一層LSTM有個return_sequences =True可以將最後一個結果出入到輸出序列,保證輸出的tensor是3D的,因爲LSTM的輸入要求是3D的tensor。

兩層LSTM模型訓練過程如下:

深度學習將會變革NLP中的中文分詞

圖12:2層LSTM優化器Adam訓練20次的模型

可以看到,兩層LSTM使得模型更加複雜,訓練時常也增加不少。模型訓練後,使用icwb2的測試結果爲:

深度學習將會變革NLP中的中文分詞

圖13:兩層LSTM的模型F Score: 0.889

可以看到,隨着模型的複雜,雖然F Score無提升,但是其他的指標有一定的提升。一般來說,神經網絡在大量訓練數據下也會有更好的效果,後續會繼續嘗試更大數據集更復雜模型的效果。

總結和展望

使用深度學習技術,給NLP技術給中文分詞技術帶來了新鮮血液,改變了傳統的思路。深度神經網絡的優點是可以自動發現特徵,大大減少了特徵工程的工作量,隨着深度學習技術的進一步發展,在NLP領域將會發揮更大的作用。達觀數據將在已有成熟的NLP算法及模型基礎上,逐漸融合基於深度神經網絡的NLP模型,在文本分類、序列標註、情感分析、語義分析等功能上進一步優化提升效果,來更好爲客戶服務。

雷鋒網(公衆號:雷鋒網)注:本文由ResysChina授權轉載,如需轉載請聯繫原作者。

深度學習將會變革NLP中的中文分詞

文章來源:雷鋒網