SRILM Ngram 折扣平滑算法

關於n-gram 語言模型,大部分在這篇博客裏 記過了,    SRILM 語言模型格式解讀 , 其實看完了,ngram的大概用法都比較清楚了,
可是關於平滑算法,一直很模糊,就曉得一個"劫富濟貧" ,也不知 回退 ,插值,折扣,平滑,都說的什麼東西,模模糊糊的,找了不少資料,仍是看官方文檔吧,看具體公式,就明白了.
 
看所有翻譯 參考 :    Ngram 折扣平滑算法 ,本文裏夾帶着本身的一些理解. 
本文檔翻譯自 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 數目 , 不論是幾元的, 只要出現1次,就算在內 
舉個例子:   語料爲
ABC 2
DBC 3
則:
c(*_C)=5
n(*_C)=2
n2=1

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)
 
平滑通常採用如下兩種策略中的一種
  •   回退平滑
      當 ngrma 統計結果  c( a_ z) > 0,回退平滑算法以  c( a_ z) 爲基礎計算  p( a_ z) ,不然在  c( a_ z) = 0 的狀況,回退平滑算計算  p( a_ z) 時只考慮  c(_ z);
  • 插值平滑
   插值平滑算法在  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 平滑要優於其餘的平滑算法。 
ps:公式2,3  是回退平滑的計算方式  , 公式4,5 是插值平滑的計算方式. 通常狀況下 任何一個平滑算法均可以分爲回退 和 插值  ,即 backoff  和 interpolate
 

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 爲集合 { zc( 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 爲集合 { zn(*_ 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 就認爲可信,這時採用最大似然估計機率值。這些限制能夠經過使用  -gt n max 參數來控制。
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。
相關文章
相關標籤/搜索