出处:
http://blog.csdn.net/longxinchen_ml/article/details/50646528
http://blog.csdn.net/han_xiaoyang/article/details/50646667
声明:版权全部,转载请联系作者并注明出处
1. 引言:朴素贝叶斯的局限性
我们在之前文章《NLP系列(2)_用朴素贝叶斯进行文本分类(上)》探讨过。朴素贝叶斯的局限性来源于其条件独立假设。它将文本看成是词袋子模型。不考虑词语之间的顺序信息。就会把“武松打死了老虎”与“老虎打死了武松”认作是一个意思。那么有没有一种方法提高其对词语顺序的识别能力呢?有,就是本节要接到的N-gram语言模型。
2. N-gram语言模型是啥?
2.1从假设性独立到联合概率链规则
照抄我们前文垃圾邮件识别中的条件独立假设,长这个样子:
P((“我”,“司”,“可”,“办理”,“正规发票”,“保真”,“增值税”,“发票”,“点数”,“优惠”)|S)
=P(“我”|S)×P(“司”|S)×P(“可”|S)×P(“办理”|S)×P(“正规发票”|S)
×P(“保真”|S)×P(“增值税”|S)×P(“发票”|S)×P(“点数”|S)×P(“优惠”|S)
为了简化起见,我们以字母
P(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10)
=P(x1)P(x2)P(x3)P(x4)P(x5)P(x6)P(x7)P(x8)P(x9)P(x10)
=P(“我”)P(“司”)P(“可”)P(“办理”)...P(“优惠”)
假设不满足独立性假设,上面的等号就不成立。 那么有没有一个不依赖于不论什么其它的假设,而能够原原本本地把全部的语序信息都考虑进来的恒等式呢?有,它就是联合概率链规则(chain rule) :
P(x1,x2,x3,x4,x5,…,xn)
=P(x1)P(x2|x1)P(x3|x1,x2)...P(xn|x1,x2,...,xn−1)
2.2 从联合概率链规则到n-gram语言模型
上面的联合概率链规则公式虽然考虑到了全部的词和词之间的依赖关系。可是非常复杂,在实际生活中差点儿没办法使用,于是我们就想了非常多办法去近似这个公式。效果又要求比独立性假设好。比方我们要讲到的语言模型n-gram就是一个这样的简化。
假设我们考虑一个词语对上一个词语的依赖关系,公式就简化成了例如以下形式,我们把它叫做二元语法(bigram。2-gram):
P(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10)
=P(x1)P(x2|x1)P(x3|x2)P(x4|x3)..P(x10|x9)
=P(“我”)P(“司”|“我”)P(“可”|“司”)P(“办理”|“可”)...P(“优惠”|“点数”)
假设把依赖词长度再拉长一点。考虑一个词对前两个词的依赖关系,就叫做三元语法(trigram。3-gram),公式例如以下:
P(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10)
=P(x1)P(x2|x1)P(x3|x1,x2)P(x4|x2,x3)×...×P(x10|x8,x9)
=P(“我”)P(“司”|“我”)P(“可”|“我”,“司”)P(“办理”|“司”,“可”)...P(“优惠”|“发票”,“点数”)
假设我们再考虑长一点,考虑n个词语之间的关系,恩恩。这就是n-gram的由来。歪果仁果然取名字简单粗暴又好记…
事实上以上几个简化后的公式,就是著名的马尔科夫假设(Markov Assumption):下一个词的出现仅依赖于它前面的一个或几个词。
这相对于联合概率链规则,事实上是一个有点粗糙的简化。只是非常好地体现了就近思路。离得较远和关系比較弱的词语就被简化和省略了。实际应用中,这些简化后的n-gram语法比独立性假设还是强非常多的。
事实上能够把独立性假设理解成为1-gram。
2.3 如何选择依赖词的个数“n”?
选择依赖词的个数“n”主要与计算条件概率有关。
理论上,仅仅要有足够大的语料,n越大越好,毕竟这样考虑的信息很多其它嘛。
条件概率非常好算,统计一下各个元组出现的次数就能够,比方:
P(“优惠”|“发票”,“点数”)=(“发票”,“点数”,“优惠”)出现的次数(“发票”,“点数”)出现的次数
但我们实际情况往往是训练语料非常有限。非常easy产生数据稀疏,不满足大数定律,算出来的概率失真。比方(“发票”,“点数”,“优惠”)在训练集中竟没有出现,就会导致零概率问题。
又比方在英文语料库IBM, Brown中。三四百兆的语料,其測试语料14.7%的trigram和2.2%的bigram在训练语料中竟未出现!
还有一方面,假设n非常大。參数空间过大,产生维数灾难,也无法有用。
假设词表的大小为
这么多的參数。预计内存就不够放了。
那么。如何选择依赖词的个数n呢?从前人的经验来看:
- 经验上。trigram用的最多。虽然如此。原则上,能用bigram解决,绝不使用trigram。n取≥4的情况较少。
- 当n更大时:对下一个词出现的约束信息很多其它,具有更大的辨别力。
- 当n更小时:在训练语料库中出现的次数很多其它,具有更可靠的统计信息。具有更高的可靠性、有用性。
3. N-gram实际应用举例
说了这么N-gram语言模型的背景知识,咱们再来看看N-gram语言模型在自然语言处理中有哪些常见应用。
PS:此部分以原理介绍为多。详细的技术实现细节请參考文中链接或者google。
3.1 词性标注
词性标注是一个典型的多分类问题。常见的词性包括名词、动词、形容词、副词等。
而一个词可能属于多种词性。
如“爱”,可能是动词,可能是形容词,也可能是名词。
可是一般来说,“爱”作为动词还是比較常见的。所以能够统一给“爱”分配为“动词”。这样的最简单粗暴的思想非常好实现。假设准确率要求不高则也比較经常使用。它仅仅须要基于词性标注语料库做一个统计就够了,连贝叶斯方法、最大似然法都不要用。词性标注语料库通常是由专业人员搜集好了的,长以下这个样子。
当中斜线后面的字母表示一种词性,词性越多说明语料库分得越细:
须要比較以下各概率的大小,选择概率最大的词性就可以:
P(词性i|“爱")=“爱"作为“词性i”的次数“爱"出现的次数。i=1,2,3...
但这样的方法没有考虑上下文的信息。
而一般来说。形容词后面接名词居多。而不接动词,副词后面才接动词,而不接名词。 考虑到词性会受前面一两个词的词性的影响,能够引入2-gram模型提升匹配的准确度。 我们匹配以下这句话(已被空格分好词)中“爱”的词性:
“闷骚的 李雷 非常 爱 韩梅梅”
将公式进行以下改造,比較各概率的大小,选择概率最大的词性:
P(词性i|“非常”的词性(副词)。“爱")=前面被“副词”修饰的“爱"作为“词性i”的次数前面被“副词”修饰的“爱"出现的次数。i=1,2,3...
计算这个概率须要对语料库进行统计。但前提是你得先推断好“非常”的词性。由于採用2-gram模型,进而就须要提前推断“李雷”的词性,须要推断“闷骚的”词性。可是“闷骚的”作为第一个词语,已经找不比它更靠前的词语了。
这时就能够考虑用之前最简单粗暴的方法推断“闷骚的”的词性,统一推断为形容词就可以。
PS:词性标注是自然语言处理中的一项基础性工作。有其细节实现远比我们介绍地更加丰富。感兴趣的同学能够看看这篇文章《NLTK读书笔记 — 分类与标注》
3.2 垃圾邮件识别
是的,亲,你!
没。看!
错!能够用N-gram进行垃圾邮件识别。并且是朴素贝叶斯方法的进化版。以下我们用直观的样例探讨一下其在分类问题上是怎么发挥作用的。一个可行的思路例如以下:
- 先对邮件文本进行断句。以句尾标点符号(“。” “!” “?”等)为分隔符将邮件内容拆分成不同的句子。
- 用N-gram分类器(立即提到)推断每个句子是否为垃圾邮件中的敏感句子。
- 当被推断为敏感句子的数量超过一定数量(比方3个)的时候。觉得整个邮件就是垃圾邮件。
咳咳,有同学问N-gram分类器是什么鬼,这个分类器靠谱么。N-gram分类器是结合贝叶斯方法和语言模型的分类器。这里用
P(Yi|X)∝P(X|Yi)P(Yi)。i=1,2
比較i=1和2时两个概率值的大小就可以得到
P(Yi|X)∝P(X|Yi)P(Yi)。i=1,2
∝P(x1|Yi)P(x2|x1。Yi)P(x3|x2,Yi)...P(x10|x9,Yi)P(Yi)
∝P(“我”|Yi)P(“司”|“我”,Yi)P(“可”|“司”。Yi)...P(“优惠”|“点数”,Yi)P(Yi)
公式中的条件概率也比較好求,举个样例:
P(“优惠”|“点数”,Yi)=在类别Yi中,(“点数”,“优惠”)出现的次数在类别Yi中。“点数”出现的次数
剩下的就须要在语料库中间做一个的统计就是了。由于这样的方法考虑到了词语前面的一个词语的信息。同一时候也考虑到了部分语序信息。因此区分效果会比单纯用朴素贝叶斯方法更好。
多提几句,N-gram方法在实际应用中有一些tricks须要注意:
- 3-gram方法的公式与上面相似。
此处省略。从区分度来看,3-gram方法更好些。
- 句子开头的词,比方本例中的“我”,由于要考虑其本身作为开头的特征。能够考虑在其前面再加入一个句子起始符号如
“<s>” ,这样我们就不必单独计算P(“我”|Yi) ,而是替换为计算P(“我”|“<s>”,Yi) 。形式上与2-gram统一。 这样统计和预測起来都比較方便。 - 一般地,假设採用N-gram模型。能够在文本开头加入n-1个虚拟的開始符号,这样在全部情况下预測下一个词的可依赖词数都是一致的。
- 与朴素贝叶斯方法一样,N-gram模型也会发生零概率问题,也须要平滑技术。 别着急。以下立即讨论到。
3.3 中文分词
之前说过。中文分词技术是“中文NLP中,最最最重要的技术之中的一个”,重要到某搜索引擎厂有专门的team在集中精力优化这一项工作。重要到能影响双语翻译10%的准确度。能影响某些query下搜索引擎几分之中的一个的广告收入。只是简单的分词实现方式中,包括的原理事实上也非常易懂。
说起来,中文分词也能够理解成一个多分类的问题。 这里用
咱们继续套用贝叶斯公式:
P(Yi|X)∝P(X|Yi)P(Yi);i=1,2,3...
比較这些概率的大小,找出使得
而上面贝叶斯公式中
于是能够将
P(Yi|X)∝P(Yi)。i=1,2,3...
也就是说我们仅仅要取最大化的
于是有:
P(Y1)=P(“我司”。“可”。“办理”。“正规发票”)
=P(“我司”)P(“可”|“我司”)P(“办理”|“可”)P(“正规发票”|“办理”)
另外一种分词方案的概率为:
P(Y2)=P(“我”,“司可办”,“理正规”,“发票”)
=P(“我”)P(“司可办”|“我”)P(“理正规”|“司可办”)P(“发票”|“理正规”)
由于在语料库中“司可办”与“理正规”一起连续出现的概率为0,于是
3.4机器翻译与语音识别
除了上述说到的应用,N-gram语言模型在机器翻译和语音识别等顶级NLP应用中也有非常大的用途。
当然,机器翻译和语音识别是非常复杂的过程。N-gram语言模型仅仅是当中的一部分。可是缺少它整个过程却进行不下去。对于这两个应用我们不打算罗列大量的公式。而仅仅是举些样例,让大家了解一下语言模型是怎么发挥作用的。
对于机器翻译而言。比方中译英,我们对于同一句话『李雷出如今电视上』。得到的三个译文:
- LiLei appeared in TV
- In LiLei appeared TV
- LiLei appeared on TV
其相应短语的翻译概率是一致的,从短语翻译的角度我们无法评定哪句才是正确的翻译结果。这时候,假设我们再使用语言模型(比方机器翻译里面最常见的是3-gram)。我们计算会得到最后一句话的概率:
P(“LiLei”|“<s>”,“<s>”)P(“appeared”|“LiLei”,“<s>”)P(“on”|“LiLei”,“appeared”)P(“TV”|“appeared”,“on”)
它高于第一句和第二句的概率:
P(“LiLei”|“<s>”,“<s>”)P(“appeared”|“LiLei”,“<s>”)P(“in”|“LiLei”,“appeared”)P(“TV”|“appeared”,“in”)
P(“in”|“<s>”,“<s>”)P(“LiLei”|“in”,“<s>”)P(“appeared”|“LiLei”,“in”)P(“TV”|“appeared”,“appeared”)
因此我们选择第三句作为正确的答案。这也表明大量语料上的语言模型能够在一定程度上,体现出我们表达某种语言时候的说话习惯。
相应到语音识别问题中。我们也会遇到相同的问题,对于以下的2个句子:
- I went to a party
- Eye went two a bar tea
或者相应下述2个句子:
- 你如今在干什么?
- 你西安载感什么?
其相应的发音是全然一致的。这时假设我们借助于语言模型,我们会算出这句话的概率:
P(“I”|“<s>”,“<s>”)P(“went”|“I”,“<s>”)P(“to”|“I”,“went”)
×P(“a”|“went”,“to”)P(“party”|“to”,“a”)
它大于:
P(“Eye”|“<s>”,“<s>”)P(“went”|“Eye”,“<s>”)P(“two”|“Eye”,“went”)
×P(“a”|“went”,“two”)P(“bar”|“two”,“a”)P(“tea”|“a”,“bar”) ,
而这句话的概率:
P(“你”|“<s>”,“<s>”)P(“现在”|“你”,“<s>”)P(“在”|“你”,“现在”)P(“干什么”|“在”,“现在”)
它远大于
P(“你”|“<s>”,“<s>”)P(“西安”|“你”,“<s>”)P(“载”|“西安”,“你”)P(“感”|“西安”,“载”)P(“什么”|“感”,“载”)
因此我们会选择I went to a party 和 你如今在干什么作为正确的语音识别结果。
上面仅仅是简单的举例,可是大家应该看出来了。在机器翻译和语音识别中。N-gram语言模型有着至关重要的地位。相同在如今最顶级的计算机视觉任务『图片内容表述』中,语言模型也发挥着至关关键的数据。语言模型的重要性可见一斑。
4. 平滑技术
如今我们能够比較专门探讨平滑技术了。
为了解决零概率问题呢,我们须要给 “未出现的n-gram条件概率分布一个非零预计值,相应得须要减少已出现n-gram条件概率分布。且经数据平滑后一定保证概率和为1”。
这就是平滑技术的基本思想。
4.1 拉普拉斯平滑
这是最古老的一种平滑方法,又称加一平滑法。其保证每个n-gram在训练语料中至少出现1次。以计算概率
P(“优惠”|“发票”,“点数”)=(“发票”,“点数”,“优惠”)出现的次数+1(“发票”,“点数”)出现的次数+所有不重复的三元组的个数
在全部不反复的三元组的个数远大于(“发票”,“点数”)出现的次数时。即训练语料库中绝大部分n-gram都是未出现的情况(一般都是如此),拉普拉斯平滑有“喧宾夺主”的现象。效果不佳。
4.2 古德图灵(Good Turing)平滑
通过对语料库的统计,我们能够知道出现
- 出现0次的n元组也不能觉得其是0次,应该给它一个比較小的预计值,比方为
d0 次。 - 为了保证总共的(出现和未出现的)n元组的次数不变。其它全部已出现的n元组的次数r应该打一个折扣,比方为
dr 次。 - 然后再用新的
dr 去计算各个条件概率。
所以问题的关键是计算
∑r=0∞dr×Nr=∑r=0∞(r+1)×Nr+1
所以干脆令:
dr×Nr=(r+1)×Nr+1;r=0,1,2...
这样就能够求出
可是,当
直接的改进策略就是 “对出现次数超过某个阈值的n元组。不进行平滑,阈值一般取8~10”,其它方法请參见“Simple Good-Turing”。
4.3 组合预计平滑
不管是拉普拉斯平滑,还是古德图灵平滑技术,对于未出现的n元组都一视同仁。而这难免存在不合理。 由于哪怕是未发生的事件,相互之间真实的概率也会存在区别。
还有一方面,一个n元组可能未出现,可是其(n-1)元组或者(n-2)元组是出现过的,这些信息假设不利用就直接浪费掉了。
在没有足够的数据对高元n-gram模型进行概率预计时,低元n-gram模型通常能够提供有用的信息。 因此能够利用利用低元n-gram模型的信息对高元n-gram模型进行预计:
- 假设低元n-gram模型的概率本来就非常低,那么就给高元n-gram模型一个较低的预计值;
- 假设低元n-gram模型有一个中等的概率,那么就给高元n-gram模型一个较高的预计值。
经常使用的组合预计算法有线性差值法和Katz回退法。详细公式比較复杂,这里就不列了。
感兴趣的同学可參考 Christopher D. Manning 的《统计自然语言处理基础》
5. 从N-gram谈回贝叶斯方法
聊了这么多N-gram语言模型,我们再回到贝叶斯方法。从实际应用中看看他们的关联。
最原始的用贝叶斯方法进行分类的公式事实上非常简单:
P(Yi|X)∝P(X|Yi)P(Yi);i=1,2,3...
详细到不同应用中,它就能够演化出多种玩法:
- 对于拼写纠错(非词错误) 。
X 是错误的词语。Yi 是候选的改正词语,二者都是标量。
- 假设考虑先验概率
P(Yi) ,就是贝叶斯方法 - 假设不考虑先验概率
P(Yi) ,就是最大似然法
- 假设考虑先验概率
- 对于垃圾邮件识别,
X 是邮件中的句子。Yi 是备选的邮件类别。X 能够处理成向量,Yi 还是标量。
- 假设对向量
X 採用条件独立假设,就是朴素贝叶斯方法。 - 假设对向量
X 採用马尔科夫假设。就是N-gram语言模型。
- 假设对向量
- 对于中文分词,
X 是被分词的句子。Yi 是备选的分词方案(词串)。这里把X 看成是一个总体,所以能够理解成标量。而
Yi 则是向量。这里对向量Yi 採用马尔科夫假设。也是N-gram语言模型。
那么有没有一种模型处理的
敬请期待。