開源天然語言處理工具包hanlp中CRF分詞實現詳解

 

 

CRF簡介算法

CRF是序列標註場景中經常使用的模型,比HMM能利用更多的特徵,比MEMM更能抵抗標記偏置的問題。函數

[gerative-discriminative.png] spa

CRF訓練3d

這類耗時的任務,仍是交給了用C++實現的CRF++。關於CRF++輸出的CRF模型,請參考《CRF++模型格式說明》。 blog

CRF解碼table

解碼採用維特比算法實現。而且稍有改進,用中文僞碼與白話描述以下:模板

首先任何字的標籤不只取決於它本身的參數,還取決於前一個字的標籤。可是第一個字前面並無字,何來標籤?因此第一個字的處理稍有不一樣,假設第0個字的標籤爲X,遍歷X計算第一個字的標籤,取分數最大的那一個。遍歷

如何計算一個字的某個標籤的分數呢?某個字根據CRF模型提供的模板生成了一系列特徵函數,這些函數的輸出值乘以該函數的權值最後求和得出了一個分數。該分數只是「點函數」的得分,還需加上「邊函數」的得分。邊函數在本分詞模型中簡化爲f(s’,s),其中s’爲前一個字的標籤,s爲當前字的標籤。因而該邊函數就能夠用一個4*4的矩陣描述,至關於HMM中的轉移機率。im

實現了評分函數後,從第二字開始便可運用維特比後向解碼,爲全部字打上BEMS標籤。 查詢

實例

仍是取經典的「商品和服務」爲例,首先HanLP的CRFSegment分詞器將其拆分爲一張表:

 

null表示分詞器尚未對該字標註。

代碼

上面說了這麼多,其實個人實現很是簡練:

 

標註結果

標註後將table打印出來:

最終處理

 

將BEMS該合併的合併,獲得:

[商品/null, 和/null, 服務/null]

而後將詞語送到詞典中查詢一下,沒查到的暫時看成nx,並記下位置(由於這是個新詞,爲了表示它的特殊性,最後詞性設爲null),再次使用維特比標註詞性:

[商品/n, 和/cc, 服務/vn]

新詞識別

 

CRF對新詞有很好的識別能力,好比:

CRFSegment segment = new CRFSegment();

segment.enablePartOfSpeechTagging(true);

System.out.println(segment.seg("你看過穆赫蘭道嗎"));

輸出

 

CRF標註結果

你   S   

看   S   

過   S   

穆   B   

赫   M   

蘭   M   

道   E   

嗎   S   

[你/rr, 看/v, 過/uguo, 穆赫蘭道/null, 嗎/y]

 

null表示新詞。

相關文章
相關標籤/搜索