1. 程式人生 > >條件隨機場-應用

條件隨機場-應用

model 數字 文件路徑 style 數據文件 1.5 exp ram 交叉驗證

  今天介紹CRFs在中文分詞中的應用

  工具:CRF++,可以去 https://taku910.github.io/crfpp/ 下載,訓練數據和測試數據可以考慮使用bakeoff2005,這是鏈接 http://sighan.cs.uchicago.edu/bakeoff2005/

  首先需要了解一些概念

  字標記法——統計分詞模型常用的方法,可以將分詞問題轉化為分類問題。這裏我們介紹一下4-tag字標記法,4-tag指的是文檔中的每個字都對應一個標記,一共有4類標記,分別是:B、M、E、S,分別代表一個字處於詞的開始位置、中間位置、 結束位置,以及一個單子構成一個詞。以“我是中國人”為例來說明,標記完的結果是

我 S

是 S

中 B

國 M

人 E

  這樣給文檔中的每個字都賦予一個標記,那麽我們可以將分詞任務視為一個分類問題--將文檔中的每個字分別賦予一個類標記。

然而,如果將分詞僅僅視為一個分類任務來考慮,那麽得到的結果很可能不太理想,因為分詞需要考慮上下文,如果僅考慮字本身的特征,還是無法得到想要的效果,而CRFs模型天然考慮了上下文特征,通常在需要考慮上下文特征的序列標註問題中能取得不錯的效果。

在CRFs模型中,我們將一句話視為一個最大團(最大團的概念可以回顧下CRF第一篇),這樣我們只需要求得所有候選詞序列的聯合概率分布的最大值(每個詞對應一個隨機變量),那麽就可以得到一個分詞的標註序列。

n-gram模型——用於限定我們考慮特征的範圍,以uni-gram和bi-gram為例來說明,uni-gram窗口大小為1(cut-off=1)只考慮單字的特征,bi-gram窗口大小為2(cut-off=2)考慮兩個連續字的特征,比如“我是中國人”,bi-gram在取每個字的特征的時候,只分別考慮“我是”、“是中”、“中國”、“國人”、“人”範圍內的特征。筆者推測這樣劃分的原理應該是句子馬爾科夫鏈的性質——一個字只和它周圍的若幹字有關聯,越遠,關聯越弱。

  下面介紹CRF++工具包

  CRF++工具包輸入數據的格式是這樣的:

1  D  B
2 D M
月 W E
3 D B
1 D M

日 W E
, S S
中 W B
共 W M
中 W M
央 W E
  第一列是文檔中的字,第二列是字的特征(比如我們規定數字用D表示,普通字用W表示,標點符號用S表示等),第三列是4-tag字標記。
CRF++引入了特征模板的概念,用於擴展特征集(顯然上面的輸入數據格式能提供的特征太少了),模板這樣定義的(以上面的輸入數據為例,假設當前字符為“共”)
template expanded feature
%x[0,0]
%x[0,1] W
%x[-1,0]
%x[-2,1] S
%x[0,0]/%x[0,1] 共/W
ABC%x[0,1]123 ABCW123
  %x[row,column]row是相對當前字符的行下標,column是列下標。

  特征模板長這樣:
# Unigram
U00:%x[-2,0]
U01:%x[-1,0]
U02:%x[0,0]
U03:%x[1,0]
U04:%x[2,0]
U05:%x[-1,0]/%x[0,0]
U06:%x[0,0]/%x[1,0]

U10:%x[-2,1]
U11:%x[-1,1]
U12:%x[0,1]
U13:%x[1,1]
U14:%x[2,1]
U15:%x[-2,1]/%x[-1,1]
U16:%x[-1,1]/%x[0,1]
U17:%x[0,1]/%x[1,1]
U18:%x[1,1]/%x[2,1]

U20:%x[-2,1]/%x[-1,1]/%x[0,1]
U21:%x[-1,1]/%x[0,1]/%x[1,1]
U22:%x[0,1]/%x[1,1]/%x[2,1]

# Bigram
B

  其中U01這些是特征ID,空行沒任何意義,#Unigram #Bigram這些是解釋說明,指的是下面用的是哪類模型。

  訓練的話,可以在命令行進入項目根目錄之後(或者添加環境變量方便在任意位置識別訓練程序)輸入
  crf_learn template_file train_file model_file
  crf_learn是訓練程序,template_file指的是模板路徑,train_file指的是訓練數據路徑,model_file指的是生成的模型文件路徑(目錄+文件)
  有4個可選參數,分別是
-a CRF-L2 or CRF-L1:
  選擇L1正則化還是L2正則化(正則化的目的是防止過擬合,一般而言,L2正則化更優,因為L1正則化偏向於減少項的個數,而L2正則化偏向於降低每一項前面的系數,使之趨向於0,而不是減少為0)

-c float

  這個參數設置CRF的hyper-parameter。c的數值越大,CRF擬合訓練數據的程度越高。這個參數可以調整過擬合和欠擬合之間的平衡度。這個參數可以通過交叉驗證等方法尋找較優的參數。

-f NUM

  這個參數設置特征的cut-off threshold。CRF++使用訓練數據中至少NUM次出現的特征。默認值為1。當使用CRF++到大規模數據時,只針對特定數據的特征可能會有幾百萬,這個選項就會在這樣的情況下起到作用。

-p NUM

  如果電腦有多個CPU,那麽那麽可以通過多線程提升訓練速度。NUM是線程數量。

  所以我們在命令行訓練數據也可以這樣寫:
crf_learn -f 3 -c 1.5 template_file train_file model_file
  下面是測試數據的命令行:
crf_test -m model_file test_files
  model_file指的是模型文件的路徑,test_files指的是測試數據文件的路徑,這裏就不需要指定模板文件的路徑了,因為其路徑已經寫入模型文件中
測試數據的文件格式與訓練數據文件格式相同,運行測試命令會增加第四列,表示預測的各個字符的標記,然後可以用程序將其轉化為我們想要的分詞形式即可。
由於訓練時間太長,筆者決定下期發布相關代碼,敬請期待!

條件隨機場-應用