原文地址:关于数据平滑的一些理解作者:龙龙强
前段时间看论文时,论文里面采用了Kneser-Ney平滑算法对未登录词和稀有词进行了处理。看到这个陌生的名词,心里不由产生了几个问题,什么是平滑算法,它是干什么用的,什么是Kneser-Ney,它有什么特殊之处,利用平滑算法对于未登录词和稀有词处理后会产生什么样的效果。带着这些疑问,我阅读了宗成庆的《统计自然语言理解》和他的课件,看课件时感觉大概知道什么意思了,但是一看书,具体到公式,头都蒙了,发现原来这是一个非常有历史的研究领域,鉴于本人并不是具体做这块研究的,真要深究下去,估计硕士就耗在这上面了,所以只是做了一知半解,将一点心得分享给大家。
数据平滑的产生和统计学习分不开。在统计学习中,往往会涉及到计算概率的问题,对于一个事物发生的可能性,具体点说就是一个词出现的可能性,我们是无法得到的,因为现实世界中的文本那么多,你怎么可能统计出一个文本的可能性,那么我们只有计算它的近似值,我们通过统计一个大的语料库中词出现的概率来近似它在真实世界中的概率,这种方法我们称作最大似然估计(MLE)。既然是估计,那么就会出现误差,因为我们的语料库是有限的,不能覆盖所有,而且会有倾斜,一些词在语料库中出现的可能性明显比真实世界小很多,这是显而易见的,对于一些未出现的词或者稀有的词,特别是未出现的词,我们不能说他的概率为0,那么太不合理了,只能说概率很低。因为大家知道在n元语言模型中,我们算一句话总体的概率,并不能因为某一个词的概率为0,整体就为0了,所有我们要给那些未出现的情况给点概率,但是此时我们要保证所有情况的总体概率为1。怎么办呢?
这里引出了数据平滑的基本思想:“劫富济贫”,也就是说把语料库中已有的那些情况的概率减去一部分然后分给语料库中未出现的情况。这又引出了几个问题:劫谁、怎么劫,怎么济。下面就围绕这四个问题介绍下几种常见的数据平滑算法,最后在对比他们之间的优劣。
其实撇开一些限制条件,大家看到怎样消除概率为0的未出现情况,最简单的想法就是加个1,让它不为0,不就行了,这就是最简单的加法平滑法,但是说句实话,虽然看似解决问题,但是不合理呀,效果也很差,所有不做考虑,下面讲些正统的做法。
首先要提的是Gooding Turing算法,对于n元语法来说,它劫的是所有n元语法,怎么劫,就是劫多少,假若说一个n元语法出现的次数为r,那么它就按比例缩小次数,公式这里就不说了。劫出来的概率怎么分,针对所有测试集中未出现的情况平均分。这里有同学该问了,分的时候是不是不太合理呀,并不是每个未出现的词真实的概率都一样呀,这就引出了下一个算法。
Katz平滑算法,它的思路就是在劫的时候不是所有n元语法都劫,出现次数很多的n元语法可靠性很高,出现误差的可能性不大,但是出现次数少的n元语法则可能和现实世界差别有点大,所有针对出现次数大于5的n元语法,不打折扣。而对于小于5次的n元语法乘以一个折扣率d,然后分给未出现的情况。上面已经说了,在分概率的时候不能平均分,这里提出了一个思想,如果n元语法模型对应的n-1元语法模型出现的概率高,那么n元语法模型相应的概率也高,例如 I am cool 和 think i do。加入cool和do都是未出现,但是我们肯定认为I am cool这个3元语法模型的概率要比think i do高,因为I am出现的概率要高。这里就用了一个很重要的思想,利用低阶语言模型的概率来推算高阶的未出现的语言模型的概率,这个过程是可以迭代计算的,一直算到1元模型或者0元模型(概率为平均值)。这里会有同学想了,既然高阶模型的概率和低阶模型相关性很大,那么在计算已经出现的高阶模型概率时,我们是不是也可以考虑一下低阶模型的概率呢?想法很不错,这又引入了下一个算法。
讲到这里,其实可以简单做一个小的分类:在计算语料库中出现过的n元模型时,如果不考虑低阶语言模型的概率,只针对未出现的n元模型采用低阶模型来计算,那么这就是上面的katz算法,称为后备模型,而如果都考虑的话,那就是插值模型。下面的Jelinek Mereer平滑算法和Witten Bell平滑算法就是插值模型,它的计算公式可以简单描述为(n元模型的平滑概率=m×n元模型的最大似然概率+(1-m)×n-1元模型的平滑概率),按比例进行了分裂。具体怎么计算m,有很多方法,其中一个方法叫做留存插值法,就是一部分语料用来计算先验概率就是最大似然估计,剩余的用来训练参数m,评价的标注就是使留存数据的困惑度最小。讲到这里其实差不多了,但是同志们该问主讲的Kneser-Ney平滑算法还没介绍,别急,由于比较重要,下面就专门讲。
Kneser-Ney平滑算法比较有意思,有原版的和修正的,原版的采用了后备模型,而修正的采用了插值模型。还记得两者的区别吗,就是后备模型在计算未出现的n元语法模型时才考虑低阶模型的概率。这里特别要讲一个怎么劫的问题,Kneser-Ney平滑算法是后备模型,它采用的是绝对减值法,就是对所有的出现的n元语法模型减去一个固定的次数D,然后在按照n-1元语法模型的概率分布分给未出现的n元语法模型。修正后的Kneser-Ney算法和上面的插值模型不同的是,它也才采用了绝对减值法,而上面的插值模型是没有减值的,只是按比例分出去了。但是修正后的算法采用的绝对减值法和原版的又不一样,不是都减去同样的量。而是按照n元语法出现的次数的不同分为1、2和大于等于3次,三种情况减去的量不同。
到现在,主流的平滑算法都介绍一遍了。下面就根据实验,对每个算法进行比较吧。S.F Chen和J.Goodman利用布朗语料、北美商务新闻语料和广播新闻语料,以测试集的交叉熵(计算估计分布和真实分布的相似度)和语音识别结果的词错误率为评价指标,采用留存插值法的Jelinek-Mercer算法作为参考标准,对上面几种算法进行了评估。
实验结果表明:不管训练语料多少,对于二元和三元语法,Knerser-Ney算法和其修正版效果都是最好的。其他的算法比较来说,在数据稀疏的情况下,JM由于Katz,在大量语料的情况下,Katz又由于JM。通过研究,两位作者总结了以下几个对数据平滑效果产生影响的因素:(1)修正的后备分布(2)绝对减值优于线性减值(3)对于较低的非零计数(就是出现次数较少的n元语法,就是罕见的情况),插值模型优于后备模型(4)增加算法的自由参数,通过留存数据优化这些参数。
其实数据平滑并不只应用于统计自然语言理解领域。所有涉及到统计学习的领域,需要处理未出现情况和出现较少的情况,都可以采用数据平滑的思想来解决问题。 以上,就是个人对数据平滑的一点理解,如果因此给你带来不便,略表歉意,假若能有所帮助,深感荣幸。
稀疏问题的解决——数据平滑
在自然语言处理的N元模型中,用最大似然估计(MLE)作为某个字符串出现的概率,这样会造成数据稀疏问题,并且使得MLE值偏离真实概率。这个问题与N元语法自身有关,他们不能估计长距离的上下文,总是倾向于过低地估计哪些在训练语料库中不是彼此向邻近出现的符号串的概率。
平滑就是给那些“零概率和低概率的N元语法”指派非零概率的方法。平滑分为打折和回退,打折是指将某个非零N元语法的计数降下来,把这部分概率量指派给那些训练语料库中出现次数为零或很低的事件。回退指用根据N-1元语法计数来建立N元语法模型。
问题描述
N-gram存在问题,训练语料毕竟是有限的,这样导致很多事件,如trigram中,w1 w2 w3根本没有出现过。根据最大似然估计,这些事件的概率为零。然而这些事件的真实概率并不一定为零。这个问题被成为数据稀疏问题。
-- MLE给训练样本中未观察到的事件赋以0概率。
-- 若某n-gram在训练语料中没有出现,则该n-gram的概率必定是0。
-- 解决的办法是扩大训练语料的规模。但是无论怎样扩大训练语料,都不可能保证所有的词在训练语料中均出现。
-- 由于训练样本不足而导致所估计的分布不可靠的问题,称为数据稀疏问题。
-- 在NLP领域中,数据稀疏问题永远存在,不太可能有一个足够大的训练语料,因为语言中的大部分词都属于低频词。
Zipf 定律:
(1)告诉我们语言中只有很少的常用词,语言中大部分词都是低频词(不常用的词)。
(2)解释是Principle of Least effort(讲话的人和听话的人都想省力的平衡);说话人只想使用少量的常用词进行交流;听话人只想使用没有歧义的词(量大低频)进行交流。
(3)对于语言中的大多数词,它们在语料中的出现是稀疏的.只有少量词语料库可以提供它们规律的可靠样本。
定义
把在训练样本中出现多的事件的概率适当减小,把减小得到的概率密度分配给训练语料中没有出现过的事件。这个过程有时也称为减值(Discounting)。
--减值法
修改训练样本中的事件的实际计数,是样本中不同时间的概率之和小于1,剩余的概率量分配给未见概率。
--调整方法:最大似然规则
(1)他可保证模型中任何概率均不为0;
(2)数据平滑使模型参数概率分布趋向于更加均匀。低概率(包括0概率)被调高,高概率被调低。
--数据平滑技术
(1)加法平滑
Add-one
1.每一种情况出现的次数加1。
2.规定任何一个n-gram在训练语料至少出现一次(即规定没有出现过的n-gram在训练语料中出现了一次),则: new_count(n-gram) = old_count(n-gram) + 1
3.没有出现过的n-gram的概率不再是0
例如,对于uni-gram,设w1, w2, w3 三个词,概率分别为:1/3, 0, 2/3,加1后情况?
2/6, 1/6, 3/6
Add-delta平滑
Lidstone’s 不是加1,而是加一个小于1的正数 , 通常= 0.5,此时又称为Jeffreys-Perks Law或ELE 效果比Add-one好,但是仍然不理想。
(2)Good-turning平滑
【来自wiki】
Good-Turing基本思想是:用观察计数较高的N元语法数重新估计概率量的大小,并把它指派给那些具有零计数或者较低计数的N元语法。
涉及的符号含义为:
:某个N元语法出现的频数。
:出现次数为c的 N-gram 词组的个数,是频数的频数即:
:Good-Turing平滑计数:
Katz所做改进
Katz认为,实际上,并非对于所有的计数C都使用打折估计的计数是可靠的,假定对较大的计数是可靠的(对于某个阈值k,c>k),他建议取k的值为5,即:
当引入某个K时,C*的正确等式为:(Katz,1987)
Good-Turing常常与Katz回退法一起使用,实际上所有的回退语言模型都必须打折。其他打常见平滑法还有:加1平滑,Witten-Bell打折法,留存估计,删除估计,Add-delta等。
【解释】基本思想:利用高频率n-gram的频率调整低频的n-gram的频率。
具体操作:假设N 是样本数据的大小, nr是在N元模型的训练集中正好出现r 次的事件的数目(在这里,事件为N元对 ),nr表示有多少个N元对出现了r次
Good-Turing估计适合单词量大并具有大量的观察数据的情况下使用,在观察数据不足的情况下,本身出现次数就是不可靠的,利用它来估计出现次数就更不可靠了。缺乏利用低元模型对高元模型进行线性插值的思想。
【例子】
为了更好地理解古德-图灵(Good-Turing)估计法,以一个例子来讲解。
训练集合:T={<s>what is it what is small?}|T|=8
验证集合:V={what is it small ? <s> flying birds are a bird.}, |V|=12
在训练集合上,我们得到:p(<s>)=p(it)=p(small)=p(?)=0.125, p(what)=p(is)=0.25,其他为0
如果不经过平滑处理,则验证集上两句子的概率分别为:p(what is it?)=(0.25*2)*(0.125*2)≈0.001 p(it is flying.)=0.125*0.25*(0*2)=0
现在用古德-图灵算法进行平滑处理,如下:
首先计算,各发生r次N元组类别的数目,依次为N(0)=6,N(1)=4,N(2)=2,N(i)=0 ,i>2:
其次,重新估计各概率值。
对于发生0次的事件概率:Pr(.)=p(flying)=p(birds)=p(are)=p(bird)=p(a)=(0+1)*N(0+1)/(8*N(0))=1*4/(8*6)≈0.083
对于发生1次的时间概率:Pr(it)=p(<s>)=p(small)=p(?)=(1+1)*N(1+1)/(8*N(1))=2*2/(8*4)=0.125
对于发生两次的时间概率:Pr(what)=Pr(is)=(2+1)*N(2+1)/(8*N(2))=3*0/(8*2)=0: 保持原值0.25
归一化处理,6*P0+4*P1+2*P2=1.5。.
所以,归一化处理后,p’(it)=p’(<s>)=p’(small)=p’(?)= 0.125/1.5 ≈0.08, p’(what)=p’(is)= 0.25/1.5 ≈0.17,
p’(.)=p’(birds)=p’(are)=p’(bird)=p’(a) = 0.083/1.5 ≈0.06
因此:p’(what is it?)=(0175*2)*(0.08*2)≈0.0002 p’(it is flying.) ≈ 0.08*0.17*(0.06*2)≈0.00004
(3)Backing-off平滑
(4)Jelinek-mercer平滑
线性插值平滑(Linear Interpolation Smoothing)方法通常也被称作Jelinek-Mercer 平滑。Jelinek 和Mercer 在1980 年首先提出了这种数据平滑算法的思想,Brown 在1992 年给出了线性插值的平滑公式:
该参数平滑技术的基本思想是利用低元n-gram 模型对高元n-gram 模型进行线性插值。用降元的方法来弥补高元的数据稀疏问题,数据估计有一定的可靠性。但是参数估计较困难。
(5)Katz平滑
(6)Church-gale平滑