一、背景
近期研究了一下語言模型,同事推薦了一個比較好用的工具包kenlm,記錄下使用過程。
二、使用kenlm訓練 n-gram
1.工具介紹:http://kheafield.com/code/kenlm/
2.工具包的下載地址:http://kheafield.com/code/kenlm.tar.gz
3.解壓后運行,./bjam 進行編譯
4.使用如下命令進行訓練:bin/lmplz -o 5 --verbose_header --text data/chat_log.txt --arpa result/log.arpa --vocab_file result/log.vocab
備注:4.1 文件必須是分詞以后的文件。
4.2 -o后面的5表示的是5-gram,一般取到3即可,但可以結合自己實際情況判斷。
三、使用kenlm判斷一句話概率
使用kenlm主要就是對arpa文件內容的運行,下面解析下該文件的內容。
1.arpa文件
\1-grams: -6.5514092 <unk> 0 0 <s> -2.9842114 -1.8586434 </s> 0 -2.88382 ! -2.38764 -2.94351 world -0.514311 -2.94351 hello -0.514311 -6.09691 guys -0.15553 \2-grams: -3.91009 world ! -0.351469 -3.91257 hello world -0.24 -3.87582 hello guys -0.0312 \3-grams: -0.00108858 hello world ! -0.000271867 , hi hello ! \end\
1.1 介紹該文件需要引入一個新的概念,back_pro. 超詳細的介紹見 --> http://blog.csdn.net/visionfans/article/details/50131397
三個字段分別是:Pro word back_pro (注:arpa文件中給出的數值都是以10為底取對數后的結果)
1.2 需要特別介紹三個特殊字符。<s>、</s>和<unk>
一看便知,<s>和</s>結對使用,模型在計算概率時對每句話都進行了處理,將該對標記加在一句話的起始和結尾。這樣就把開頭和結尾的位置信息也考慮進來。
如“我 喜歡 吃 蘋果” --> "<s> 我 喜歡 吃 蘋果 </s>"。
<unk>表示unknown的詞語,對於oov的單詞可以用它的值進行替換。
2.n-gram概率計算
2.1 一元組w1
直接在arpa文件中查找,如果有則直接返回它的pro,否則返回<unk>的pro。
2.2 二元組w1w2
直接在arpa文件中查找,有則直接返回它的pro,否則返回back_pro(w1)*pro(w2)的結果。當然此處都去過log,直接加減即可。
2.3 三元組w1w2w3
這個說起來比較麻煩,畫個圖。

其中有一點大家可能會比較疑惑。為什么文件中存在二元組w1w2,要輸出 back_pro(w1w2)*pro(w2w3),而沒有w1w2,則可以直接輸出pro(w2w3)。因為直觀理解,有w1w2出現,概率pro(w1w2w3)的數值應該更大些。其實此處是用pro(w2w3)來近似代替pro(w1w2w3)的值。
我在arpa文件中選了前2000個一元組的pro和back_pro畫出下圖,由圖我們可知,一個單詞或者詞組的pro和back_pro是負相關的。所以當二元組w1w2沒有出現時,我們認為pro(w1w2)的特別小,相應地back_pro的值就會變大,而取完log以后的結果就為0,在加法中可以直接忽略該項。

3. sentence pro計算
句子的計算就不需我多說了,一般情況下都只用到三元組。
4.衡量指標
4.1 衡量的指標暫時只考慮了困惑度(perplexity),定義如下:


取完對數后計算超級方便,對數運算真乃利器也!!!
