本文档翻译自
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