本文檔翻譯自
srilm手冊
ngram-discount.7.html
NAME
ngram-discount – 這里主要說明
srilm中實現的平滑算法
NOTATION
a_z 代表以
a為起始詞,以
z為結束詞的
ngram,其中
_代表
0個或多個詞
p(a_z) 前
n-1個詞為
a_的情況下,第
n個詞為
z的條件概率
a_ n元
a_z的前
n-1個詞構成的前綴
_z n元
a_z的后
n-1個詞構成的后綴
c(a_z) n元
a_z在訓練語料中出現的次數
n(*_z) 符合
*_z這一模式的獨立
n元數目,“
*_z”中‘
*’代表通配符
n1,n[1] 出現次數為
1的
ngram數目
DESCRIPTION
Ngram語言模型主要用於估計前
n-1詞為
a_的情況下,第
n個詞為
z的概率,即概率
Pr(z|a_),為簡單起見,一般使用
P(a_z)表示。估算概率最直接的方式就是分別在訓練集中統計
c(a_z)和
c(a_),然后求如下公式,即得到相關概率運算結果:
(
1)
p(a_z) = c(a_z)/c(a_)
如上的概率估算方法又稱為最大似然估計方法。該方法比較直觀易懂,但存在一個不足點就是對於語料中不存在的
n元,其概率估算結果將為
0。為了避免該情況的發生,可以通過將觀察到的
ngram一部分概率分布出去,並將這部分概率值分配到未觀察到的
ngram上。這種概率重新分配方式即為通常所說的平滑
(smoothing)或折扣
(discounting)。
大部分平滑算法都可以使用如下公式來表示
(
2)
p(a_z) = (c(a_z) > 0) ? f(a_z) : bow(a_) p(_z)
若
ngram a_z在訓練集中發生了,則直接使用概率
f(a_z),該概率值一般都小於最大似然估計概率值結果,這樣留下的一部分概率值可用於訓練語料中未覆蓋到的
n元
a_*。不同的平滑算法區別主要在於采用何種折扣方法對最大似然估計結果進行折扣。
應用公式(
2)計算概率
p(a_z)時,若
ngram a_z在訓練語料中沒有出現,則直接使用低階概率分布
p(_z)
,若歷史
a_在訓練語料中沒有出現,即
c(a_) = 0,這時可以直接使用
p(_z)作為當前
ngram的概率值,即
bow(a_) = 1;否則需要將
bow(a_)乘到
p(_z)上,以保證概率分布的歸一性,即:
Sum_z p(a_z) = 1
假設
Z為詞典中所有詞構成的集合,
Z0為詞典中所有滿足條件
c(a_z) = 0的詞構成的集合,
Z1為詞典中所有滿足條件
c(a_z) > 0的詞構成的集合。在
f(a_z)計算好的情況下,
bow(a_)可以通過如下方式估算得到:
(3) Sum_Z p(a_z) = 1
Sum_Z1 f(a_z) + Sum_Z0 bow(a_) p(_z) = 1
bow(a_) = (1 - Sum_Z1 f(a_z)) / Sum_Z0 p(_z)
= (1 - Sum_Z1 f(a_z)) / (1 - Sum_Z1 p(_z))
= (1 - Sum_Z1 f(a_z)) / (1 - Sum_Z1 f(_z))
上式中分母
Sum_Z0 p(_z)代表在歷史“
_”條件下,所有滿足條件
c(a_z) = 0的詞概率之和,而
Z1為詞典中所有滿足條件
c(a_z) > 0的詞構成的集合,因此存在如下的關系
Sum_Z0 p(_z) + Sum_Z1 p(_z) = 1
因為
Z0和
Z1構成了
ngram “
_z”所有可能的情況。因此有:
Sum_Z0 p(_z) = 1 - Sum_Z1 p(_z)
平滑一般采用以下兩種策略中的一種
1) 回退平滑
當
ngrma 統計結果
c(a_z) > 0,回退平滑算法以
c(a_z)為基礎計算
p(a_z) ,否則在
c(a_z) = 0的情況,回退平滑算計算
p(a_z)時只考慮
c
(_z);
2) 插值平滑
插值平滑算法在
c(a_z) > 0的情況下,計算
p(a_z)時,除了考慮
c(a_z)之外,還需要考慮低階的
ngram,如
c(_z)等。
插值平滑算法可用如下公式來表示
(4) p(a_z) = g(a_z) + bow(a_) p(_z)
其中
g(a_z)在
c(a_z) = 0的情況下,為
0。和回退平滑算法一樣,在
c(a_z)>0的情況下,插值平滑算法也需要從
g(a_z)中折扣掉一部分概率,用於
c(a_z) = 0的所有
z構成的
ngram。
折扣平滑算法的
bow(a_)計算公式:
(5) Sum_Z p(a_z) = 1
Sum_Z1 g(a_z) + Sum_Z bow(a_) p(_z) = 1
bow(a_) = 1 - Sum_Z1 g(a_z)
插值平滑算法,同樣可以用公式
(2)的表示方式表示,如下所示:
(6) f(a_z) = g(a_z) + bow(a_) p(_z)
p(a_z) = (c(a_z) > 0) ? f(a_z) : bow(a_) p(_z)
SRILM中的大部分平滑算法同時擁有回退和插值兩種方式。根據以往的經驗,一般插值方式的效果要優於回退方式。平滑算法方面,
kneser-ney平滑要優於其他的平滑算法。
OPTIONS
本部分主要介紹
ngram-count中各個折扣算法的公式。介紹各折扣算法時,首先介紹各折扣算法的動機,然后介紹如何根據
counts值計算公式(
2)中
f(a_z)和
bow(a_)。
需要注意的是一些
counts由於
-gtmin參數的原因,可能在統計模型不存在;參考下一部份
Warning 4
大部分模型中,回退版本是默認的平滑方式,而插值版本可以通過
-interpolate獲取。在插值平滑方式中,公式(
4)中
g(a_z) 和
bow(a_)同樣根據
counts值計算得到。
每一個折扣參數選項后面都可以跟一個(
1-9)的數字,用來表示只對某一個特定元數的
ngram做折扣計算,具體可以參看
ngram-count用戶手冊。
-cdiscount D
Ney 的絕對折扣(
absolute discounting)使用參數
D作為折扣常數。
D必須要介於
0和
1之間。如果
z 1代表所有滿足
c(a_z) > 0的單詞
z的集合,則有如下等式存在:
f(a_z) = (c(a_z) - D) / c(a_)
p(a_z) = (c(a_z) > 0) ? f(a_z) : bow(a_) p(_z) ; Eqn.2
bow(a_) = (1 - Sum_Z1 f(a_z)) / (1 - Sum_Z1 f(_z)) ; Eqn.3
上面為回退平滑的計算公式,對於插值平滑,有如下計算公式:
g(a_z) = max(0, c(a_z) - D) / c(a_)
p(a_z) = g(a_z) + bow(a_) p(_z) ; Eqn.4
bow(a_) = 1 - Sum_Z1 g(a_z) ; Eqn.5
= D n(a_*) / c(a_)
折扣系數
D建議可以通過如下公式計算獲取
D = n1 / (n1 + 2*n2)
上式中
n1代表出現次數為
1次的
ngram數目
n2代表出現次數為
2次的
ngram數目
-kndiscount 和
–ukndiscount
Kneser-Ney折扣。前一個參數對應於
modified Kneser-Ney折扣,而后一個參數對應於最初的
Kneser-Ney折扣。
Kneser-Ney折扣算法和絕對折扣算法比較相似,該算法同樣是在
ngram統計量
count上減去一個常數
D計算折扣概率。
modified Kneser-Ney和
Kneser-Ney的不同點就在於如何計算該常數
D。
Kneser-Ney折扣的主要思想是為低階的
ngram使用一個修改后的概率估計(
modified
probability estimation)方法。具體來說,
n元低階的修正概率(
modified probability)和訓練
語料中該低階的不同前驅詞數量成比例。通過折扣和歸一化運算,有如下公式:
f(a_z) = (c(a_z) - D0) / c(a_) ;; for highest order N-grams
f(_z) = (n(*_z) - D1) / n(*_*) ;; for lower order N-grams
其中
n(*_z)代表不同的
*_z數量,這里
*代表獨立詞通配符。
D0和
D1代表兩個不同的折扣
常數,這是因為不同元數的
ngram使用不同的常數。最終的條件概率和回退權重可以通過
如下公式(
2)和(
3)計算:
p(a_z) = (c(a_z) > 0) ? f(a_z) : bow(a_) p(_z) ; Eqn.2
bow(a_) = (1 - Sum_Z1 f(a_z)) / (1 - Sum_Z1 f(_z)) ; Eqn.3
對於插值平滑有如下計算公式
p(a_z) = g(a_z) + bow(a_) p(_z) ; Eqn.4
假設
z1為集合
{z: c(a_z) > 0},對於高階
ngram有:
g(a_z) = max(0, c(a_z) - D) / c(a_)
bow(a_) = 1 - Sum_Z1 g(a_z)
= 1 - Sum_Z1 c(a_z) / c(a_) + Sum_Z1 D / c(a_)
= D n(a_*) / c(a_)
假設
z2為集合
{z: n(*_z) > 0},對於低階
ngram有:
g(_z) = max(0, n(*_z) - D) / n(*_*)
bow(_) = 1 - Sum_Z2 g(_z)
= 1 - Sum_Z2 n(*_z) / n(*_*) + Sum_Z2 D / n(*_*)
= D n(_*) / n(*_*)
最初的
Knser-Ney折扣算法(
-ukndiscount)對於任何
ngram使用同一常數
D進行折扣計算,該折扣常數根據如下公式計算獲取:
D = n1 / (n1 + 2*n2)
上式中
n1代表出現次數為
1次的
ngram數目
n2代表出現次數為
2次的
ngram數目
Chen和
Goodman的
Modified Kneser-Ney折扣(
-kndiscount)算法對於每一個
ngram均使用三個折扣常數,一個用於出現次數為
1次的
ngram,一個用於出現次數為
2次的
ngram,一個用於出現次數為
3次和
3次以上的
ngram,公式如下所示:
Y = n1/(n1+2*n2)
D1 = 1 - 2Y(n2/n1)
D2 = 2 - 3Y(n3/n2)
D3+ = 3 - 4Y(n4/n3)
Warning
SRILM中
Kneser-Ney折扣算法實際修改了低階
ngram的出現次數(
counts)。因此當使用
-write參數輸出
-kndiscount和
-ukndiscount折扣算法下所有
ngram的出現次數(
counts)時,只有最高階的
ngram和以
開始的ngram的出現次數(counts)為c(a_z),其他的ngram的出現次數為修改后的值n(*_z),參考Warning2
-wbdiscount
Witten-Bell折扣算法。直觀理解該算法就是分配給低階的權重應該和在當前歷史(
a_)后接的不同詞的統計量成比例,用公式可以表示如下:
bow(a_) = n(a_*) / (n(a_*) + c(a_))
上式中
n(a_*)代表訓練語料中歷史
a_后接的不同種類的詞條數。
Witten-Bell開始只是一個插值折扣平滑算法,因此在參數
-interpolate下,有:
g(a_z) = c(a_z) / (n(a_*) + c(a_))
p(a_z) = g(a_z) + bow(a_) p(_z) ; Eqn.4
不加
-interpolate參數,即得到了一個回退平滑版本的
Witter-Bell折扣平滑算法,該算法中
f(a_z)和插值算法中的
g(a_z)計算方法一樣。
f(a_z) = c(a_z) / (n(a_*) + c(a_))
p(a_z) = (c(a_z) > 0) ? f(a_z) : bow(a_) p(_z) ; Eqn.2
bow(a_) = (1 - Sum_Z1 f(a_z)) / (1 - Sum_Z1 f(_z)) ; Eqn.3
-ndiscount
Ristad自然折扣算法,該算法目前在
SRILM中只存在回退平滑版本,不存在插值平滑版本,因此
-interpolate對該算法無任何影響。該算法具體可參考“
A natural law of succession”。
c(a_z) c(a_) (c(a_) + 1) + n(a_*) (1 - n(a_*))
f(a_z) = -------- -------------------------------------------------
c(a_) c(a_)^2 + c(a_) + 2 n(a_*)
p(a_z) = (c(a_z) > 0) ? f(a_z) : bow(a_) p(_z) ; Eqn.2
bow(a_) = (1 - Sum_Z1 f(a_z)) / (1 - Sum_Z1 f(_z)) ; Eqn.3
-count-lm
暫不介紹
-addsmooth D
通過對每個
ngram出現次數加上一個常量
D來達到平滑效果。
p(a_z) = (c(a_z) + D) / (c(a_) + D n(*))
default
若用戶未指定任何折扣算法,則
ngram-count默認采用
Good-Turing折扣算法(
Katz平滑算法)。
Good-Turing折扣算法認為,對於發生次數為
r的
ngram,應該認為其發生次數為
r'次,其中:
r' = (r+1) n[r+1]/n[r]
上式中
n[r]代表所有發生次數為
r次的
ngram數目。
對於較大的
r,可以認為
r是一個可信的統計結果,因此不做上面的折扣計算,默認情況下
unigram中的
r只要大於
1,其他
ngram中的
r只要大於
7就認為可信,這時采用最大似然估計概率值。這些限制可以通過使用
-gtnmax參數來控制。
f(a_z) = (c(a_z) / c(a_)) if c(a_z) > gtmax
對於出現次數滿足
1 <= c(a_z) <= gtmax:的
ngram有如下折扣公式:
n[gtmax + 1]
A = (gtmax + 1) ----------------
n[1]
n[c(a_z) + 1]
c'(a_z) = (c(a_z) + 1) -----------------
n[c(a_z)]
c(a_z) (c'(a_z) / c(a_z) - A)
f(a_z) = -------- ----------------------
c(a_) (1 - A)
-interpolate參數對上述公式沒有任何影響,因此只有回退平滑版本:
p(a_z) = (c(a_z) > 0) ? f(a_z) : bow(a_) p(_z) ; Eqn.2
bow(a_) = (1 - Sum_Z1 f(a_z)) / (1 - Sum_Z1 f(_z)) ; Eqn.3
FILE FORMATS
通過使用如下的命令,
SRILM可以根據一個文本文件統計生成
ngram Count文件
ngram-count -order N -text file.txt -write file.cnt
-order參數指定要統計的
ngram的最大長度。
file.txt文件一定要一句話一行,且其中詞與詞之間通過空格隔開。輸出文件
file.cnt中一行包含一個
ngram后接一個
table鍵,后接統計到的出現次數:
a_z c(a_z)
Warning 1
SRILM 默認會在
file.txt文件中每個句子首尾分別加上句子開始標記
和句子結束標記,因此不需要再
file.txt文件中每個句子加上這兩個標記。
筆者注:新版本的
SRILM系統中,可以通過
-no-sos和
-no-eos控制不加這兩個符號。
Warning 2
SRILM中
Kneser-Ney折扣算法實際修改了低階
ngram的出現次數(
counts)。因此當使用
-write參數輸出
-kndiscount和
-ukndiscount折扣算法下所有
ngram的出現次數(
counts)時,只有最高階的
ngram和以
開始的ngram的出現次數(counts)為c(a_z),其他的ngram的出現次數為修改后的值n(*_z)。
對於大多平滑算法而言(除
-count-lm),
SRILM都使用
ARPA格式生成和使用
N-gram模型。生成一個模型文件的最簡單的方法如下所示:
ngram-count -order N -text file.txt -lm file.lm
ARPA格式的模型文件
file.lm每一行為一個
ngram及其相關信息,具體格式如下:
log10(f(a_z)) a_z log10(bow(a_z))
根據公式(
2),第一項
log10(f(a_z))代表
ngram a_z 的概率值以
10為底的對數結果,后面更一個
ngram,
ngram中每一個單詞通過空格隔開,最后一項為以
a_z 開始的
(n+1)grams的回退系數求以
10為底的對數結果。
Warning 3
不管是回退還是插值平滑,統一使用
ARPA格式來表示,即插值平滑的相關系數根據公式(
6)轉換為回退表示。
Warning 4
並不是所有的
ngram都有參數指定的最高元。參數
-gtmin, -gt1min, ..., -gt9min用於指定最小出現多少次的
n元才會被包含在語言模型中。默認情況下,所有的一元和二元都會被包含進語言模型,高階的
ngram只會包含出現次數大於等於
2的
ngram。(
Some exceptions arise, because if one N-gram is included in the model file, all its prefix N-grams have to be included as well. This causes some higher order 1-count N-grams to be included when using KN discounting, which uses modified counts as described in Warning 2.)(這句話未翻譯)
Warning 5
並不是模型中的所有
ngram都有回退值,最高階的
ngram並不需要回退值。對於其他的低階
ngram來說,其存在回退值是因為其構成了某個更高階
ngram的前綴。對於其他的低階
ngram來說回退值默認為
1,取以
10為底的對數后即為
0。
來源:http://blog.chinaunix.net/uid-20658401-id-1587798.html