Coursera自然语言处理 Week1 笔记

来源:互联网 发布:手机怎么连接电脑网络 编辑:程序博客网 时间:2024/05/16 09:30

从今天开始,重新开始看Micheal Collins的NLP公开课。预计7天时间。

1. 概率模型- Markov Process

毕竟是机器学习嘛,所以第一步,先要把实际问题转化成数学模型。在NLP中,一般使用的都是概率模型,即把语言模型变成概率论范畴。

比如说,现在有一段语音,说的很含糊,没有听清楚,好像是“like your”,又好像是“lie cured”。那么到底是哪一种呢?我们就看在现有的语料库中,到底是“like your”出现的概率大,还是“lie cured”的概率大。

于是就把语音识别问题转变成了一个概率问题:输入一串字符,输出这串字符组合在一起的概率,如果概率大,就是正确的句子。下面构建这个模型:

假设有一个句子S={x1,x2,x3,...,xn},则这个句子出现的概率理所当然如下:

P(S)=P(x1,x2,...,xn)

根据贝叶斯公式(条件概率公式),可知:

P(S)=P(x1,x2,...,xn)=P(x1)P(x2|x1)P(x3|x1,x2)...P(xn|x1,..xn1)

为方便起见,补充x1=x0= (星号字符,无实际意义),则:

P(S)=i=1nP(xi|x1,...,xi1)

对于,其中的P(xi|x1,...,xi1)这一项,根据大数定律可以约等于:

P(xi|x1,...,xi1)#(x1,...,xi1,xi)#(x1,...,xi1)

然而大数定律满足的条件是,#(x1,...,xi1,xi)#(x1,...,xi1)要足够大,但是实际情况下,这样组合的数据并不会特别多,甚至会有很多等于0,所以无法这样去约等于。

正确的计算方式是用“Markov process”来假设:

第一种假设:

Unigram:

P(xi|x1,...,xi1)P(xi)

则我们的概率模型变成:

P(S)=i=1nP(xi|x1,...,xi1)i=1nP(xi)

第二种假设:

Bigram (First-order Markov):

P(xi|x1,...,xi1)P(xi|xi1)

则我们的概率模型变成:

P(S)=i=1nP(xi|x1,...,xi1)i=1nP(xi|xi1)

第三种假设:

Trigram (Second-order Markov):

P(xi|x1,...,xi1)P(xi|xi1,xi2)

则我们的概率模型变成:

P(S)=i=1nP(xi|x1,...,xi1)i=1nP(xi|xi1,xi2)

至此,我们模型框架已经搭建完毕,接下来只要把P(xi)或者P(xi|xi1)或者P(xi|xi1,xi2)计算出来即可,这些概率就是概率模型的参数,需要从训练集中学习出来。

2. 模型参数计算

假设训练集中共有V个单词,根据大数定律有:

  1. Unigram - P(xi)=#(xi)V

  2. Bigram - P(xi|xi1)=#(xi1,xi)#(xi1)

  3. Trigram - P(xi|xi1,xi2)=#(xi2,xi1,xi)#(xi1,xi)

这里大数定律基本可以成立,因为这样的小型组合还是不难找到的。

如此,就可以把模型中的每一个参数计算出来了。

3. 参数计算的问题

3.1 Unknown words pair

虽然可以找到比较大数据集,但是在训练集中依旧可能出现#(xi2,xi1,xi)=0,或者#(xi1,xi)=0的情况。但是训练集中不出现,并不代表这种情况不可能发生,所以需要模型具有泛化和推演能力。

3.1.1 Linear Interpolation

第一种解决方法称为 Linear Interpolation。

先再看一下三种参数计算方式:

  1. Unigram - q(xi)=#(xi)V

  2. Bigram - q(xi|xi1)=#(xi1,xi)#(xi1)

  3. Trigram - q(xi|xi1,xi2)=#(xi2,xi1,xi)#(xi1,xi)

单纯使用式子1是最有可能造成underfitting的,因为没有一点儿上下文关联信息在里面;使用式子3是最有可能造成overfitting的,因为对上下文的关联性太强,对于训练集中的context记忆太深。

因此,解决Unknown words pair问题,提升模型泛化能力的其中一个方法,就是结合上面式子1-3,不单纯地使用一个假设,令:

P(xi|xi1,xi2)=λ1q(xi)+λ2q(xi|xi1)+λ3q(xi|xi1,xi2)

其中,要求λ1+λ2+λ3=1,证明过程如下:

考虑到这是一个概率问题,即训练集中,所有的三元组P(xi|xi1,xi2)之和应等于1:

P(xi|xi1,xi2)=λ1q(xi)+λ2q(xi|xi1)+λ3q(xi|xi1,xi2)=λ1q(xi)+λ2q(xi|xi1)+λ3q(xi|xi1,xi2)

其中,因为概率计算,所以有q(xi)=1, q(xi|xi1)=1, q(xi|xi1,xi2)=1

因此,

P(xi|xi1,xi2)=λ1+λ2+λ3=1

这里的三个系数用下面的方法进行选择:

挑选λ1,λ2,λ3的过程类似于BP神经网络中的反向传播过程,即优化过程,定义一个优化目标函数,然后从训练集中,分出一部分作为验证集,在验证集上确定系数:

L(λ1,λ2,λ3)=x1,x2,x3#(x1,x2,x3)logq(x3|x1,x2)

L(λ1,λ2,λ3)越大的时候,模型越好,所以:

λ1,λ2,λ3=argminλ1,λ2,λ3L(λ1,λ2,λ3)

上面只是最简单的线性组合的形式,λ1,λ2,λ3之间是没有实质性关联的,还可以让它们有关系。

如,Bucketing方法:对出现不同次的词组,使用不同的系数:

又如,将三个系数写成同一个参数的线性组合:

λ1=c(xi1,xi2)c(xi1,xi2)+γ

λ2=(1λ1)×c(xi2)c(xi2)+γ

λ3=1λ1λ2

3.1.2 Discounting

就是从概率不为0的词组中预留一部分的概率给未出现过词组。

4. 模型评估

模型想要达到的目的是,generate出来的句子是正确的!而这个“正确性”是由概率来表示的,概率P(S)越大表示越正确。也就是说,我们的目标就是:要使P(S)尽可能地大!!!

下面假设从测试集中生成了句子S={,,x1,x2,...,xn},则这个句子的正确性(概率)是:(以Bigram为例)

P(S)=P(x1,x2,...,xn)=i=1nP(xi|xi1)

注意到一个问题,在实际编程中,使用容易造成underflow,因为如果句子很长,P很小但位数很多,可能会溢出。所以在实际编程中,会对这个概率取对数log,把乘法变成加法,可以一定程度缓解这种情况:

logP(S)=logP(x1,x2,...,xn)=logi=1nP(xi|xi1)=i=1nlogP(xi|xi1)

然后从测试集中,我们生成了好多的句子{S1,S2,...,SM},则整体平均正确性(概率)为:其中M为测试集中单词的总数

l=1Mj=1mlogP(Sj)

一般在机器学习中,评估标准是cost function,越小越好,在这里也是一样,为了满足越小越好,将上式变成下面的形式:

Perplexity=2lwherel=1Mj=1mlogP(Sj)

可以看到,Perplexity越小,正确性越高(概率越大)。