本文档翻译自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
因为Z0Z1构成了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数量,这里*代表独立词通配符。D0D1代表两个不同的折扣
常数,这是因为不同元数的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

Ngram折扣平滑算法的更多相关文章

  1. SRILM Ngram 折扣平滑算法

    关于n-gram 语言模型,大部分在这篇博客里 记过了,   SRILM 语言模型格式解读 , 其实看完了,ngram的大概用法都比较清楚了, 但是关于平滑算法,一直很模糊,就晓得一个"劫富 ...

  2. maya中的顶点平滑算法(vertex smooth algorithm)

    继上文继续写.有了顶点迭代器之后就可以利用MItMeshVertex类的getConnectedVertices方法来获取相连点并代入平滑算法. 选择什么样的平滑算法呢?本人比较懒,直接打开了计算机图 ...

  3. 时间序列挖掘-预测算法-三次指数平滑法(Holt-Winters)——三次指数平滑算法可以很好的保存时间序列数据的趋势和季节性信息

    from:http://www.cnblogs.com/kemaswill/archive/2013/04/01/2993583.html 在时间序列中,我们需要基于该时间序列当前已有的数据来预测其在 ...

  4. 语言模型 N-gram 与其平滑方法推导

    N-gram N-gram 作为一个名词表示的是一个给定文本/音频样本中有n项(音素,音节,字母,单词)的一个连续序列. 数学表达 N-gram 模型表示的是当前这个 word \(w_i\) 依赖于 ...

  5. 平滑算法:三次样条插值(Cubic Spline Interpolation)

    https://blog.csdn.net/left_la/article/details/6347373 感谢强大的google翻译. 我从中认识到了航位推算dead reckoning,立方体样条 ...

  6. matlab学习之降噪平滑算法

    平滑降噪测试,代码如下 % 平滑降噪 % FFT变换和小波变换 clc clf clear length_of_sig=128; x=linspace(0,2*pi,length_of_sig); % ...

  7. [转]语言模型训练工具SRILM

    SRILM是一个建立和使用统计语言模型的开源工具包,从1995年开始由SRI 口语技术与研究实验室(SRI Speech Technology and Research Laboratory)开发,现 ...

  8. 平滑处理Smooth之图像预处理算法-OpenCV应用学习笔记三

    大清早的我们就来做一个简单有趣的图像处理算法实现,作为对图像处理算法学习的开端吧.之所以有趣就在于笔者把算法处理的各个方式的处理效果拿出来做了对比,给你看到原图和各种处理后的图像你是否能够知道那幅图对 ...

  9. SRILM的使用及平滑方法说明

    1.简介 SRILM是通过统计方法构建语言模型,主要应用于语音识别,文本标注和切分,以及机器翻译等. SRILM支持语言模型的训练和评测,通过训练数据得到语言模型,其中包括最大似然估计及相应的平滑算法 ...

随机推荐

  1. 浅谈 vue实例 和 vue组件

    vue实例: import Vue from 'vue'; import app from './app'; import myRouter from './routers'; new Vue({ e ...

  2. Hadoop生态圈-使用phoenix的API进行JDBC编程

    Hadoop生态圈-使用phoenix的API进行JDBC编程 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.

  3. CIDR 无类别域间路由

    参考百度百科 1.全称 CIDR的全称是Classless Inter-Domain Routing 2.作用 CIDR将路由集中起来,使一个IP地址代表主要骨干提供商服务的几千个IP地址,从而减轻I ...

  4. CF&&CC百套计划3 Codeforces Round #204 (Div. 1) D. Jeff and Removing Periods

    http://codeforces.com/problemset/problem/351/D 题意: n个数的一个序列,m个操作 给出操作区间[l,r], 首先可以删除下标为等差数列且数值相等的一些数 ...

  5. HDU 2188 基础bash博弈

    基础的bash博弈,两人捐钱,每次不超过m,谁先捐到n谁胜. 对于一个初始值n,如果其不为(m+1)的倍数,那么先手把余数拿掉,后继游戏中不管如何,后手操作后必定会有数余下,那么先手必胜,反之后手必胜 ...

  6. [转载]memset()的效率

    http://blog.csdn.net/hackbuteer1/article/details/7343189 void *memset(void *s, int ch, size_t n); 作用 ...

  7. [整理]内存重叠之memcpy、memmove

    函数原型: void *memcpy( void *dest, const void *src, size_t count ); void *memmove( void* dest, const vo ...

  8. 字符加密 cipher

    评测传送门 Description: Valentino 函数的定义: 对于一个由数字和小写字母组成的字符串 S,两个整数 K,M,将 S 视为一个 P 进制数,定义: Valentino(S, K, ...

  9. Spring4笔记5--基于注解的DI(依赖注入)

    基于注解的DI(依赖注入): 对于 DI 使用注解,将不再需要在 Spring 配置文件中声明 Bean 实例.只需要在 Spring 配置文件中配置组件扫描器,用于在指定的基本包中扫描注解. < ...

  10. AS中一些不经常用到的快捷键

    1 书签 添加/移除书签 Ctrl+shift+F11 展示书签 shift+F11 下一个书签  shift+加号 上一个书签  shift+减号 2 折叠/展开代码块 展开代码块  ctrl+加号 ...