引言
今天我们要来学习另一个结构化学习问题——序列标记问题(Sequence Labeling Problem)。
序列标记
序列标记问题是,我们要找的函数它的输入和输出都是序列。我们先假设这两个序列的长度时一样的。
我们的输入和输出可写成向量的形式。这个可以用RNN来解,但是我们今天介绍一个和RNN不同的方法。
我们以词性标记(POS Tagging)作为例子讲解。词性标记任务就是要标记句子中每个词汇的词性。
词性有很多类别,光名词(Nouns)下面就可以分为专有名词(Proper)和一般名词(Common)。我们要做的是输入一个句子,系统自动标记每个单词的词性:
比如John是专有名词,第一个saw是动词,最后那个saw是名词等等。
词性标记其实是自然语言处理的基石。
那这个问题也许不是很难,我们可以找到一个词典,它可以告诉我们每个单词的词性是什么。但是问题是我们还要考虑上下文,也就是我们要知道整个句子的信息。
比如上面的saw可以是动词也可以是名词,虽然它在大多数情况下都是动词。
但是我们知道冠词the后面比较有可能接名词(这需要英文语法知识啊),这样the后面的saw应该是名词而不是动词。
今天要介绍的技术如下:
HMM
隐马尔可夫模型(Hidden Markov Model,HMM)假设我们人类生成一个句子的时候,有以下两个步骤:
我们要说一句话的时候,先在心里形成一个词性序列。它是根据你大脑内建的语法所产生的。
接下来就是根据词性去找一个符合这些词性词汇。相当于动词(V)的位置你就找个动词填上去;名词(N)的位置你就找个名词填上去。就把POS的序列变成单词序列。最后再把这个单词序列说出来。
步骤一
第一个步骤是根据我们脑中所有的语法建立一个POS序列,HMM假设你脑中的语法是一个马尔可夫链(Markov Chain)。
假设你要说一句话的时候,有50%的概率是一个冠词;有40%的概率是一个专有名词;有10%的概率是一个动词。
然后根据概率随机生成一个,假设随机到了专有名词,然后就看下个词汇的词性是什么。有10%的概率专有名词后面接冠词;有80%的概率后面是动词;还有10%的概率是整个句子就结束了。
再随机生成一个词性,假设下一个词性是动词,然后再继续下去。动词后面有可能就结束了;有可能再讲一个专有名词;也有可能是一个冠词;
以此类推,假设动词后面接一个冠词(Det);冠词后面接一个名词;名词后面就结束了。
这就是一个马尔可夫链。这样你可以可以算出产生下面词性句子的概率:
步骤二
产生了词性序列,接下来就进入了步骤二。步骤二要做的事情是根据某个词典,给定一个词性,我们看该词性应该要填入哪个词汇。
当我们要选专有名词的时候,就从专有名词的集合中去生成一个词汇出来。
因为这里有5个词汇,生成词汇John的概率就是20%。
从动词集合汇总生成saw的概率是17%,从冠词中取出the的概率是63%,从名词中取出saw的概率是17%。
所以给定一个POS序列,今天说出来的句子是"John saw the saw"的概率就是它们对应的概率之积。
根据HMM,它做的事情就是,它可以描述说一句话,刚好这句话是"John saw the saw"的概率。
的概率就是产生
这个词性序列的概率,这里是:PN放到句首的概率乘以PN后面接动词,乘以动词后面接冠词,再乘以冠词后面接名词的概率。
是给定词性序列 的情况下,产生句子 的概率,这里是PN产生John的概率,乘以V产生saw的概率,乘以D产生the的概率,乘以N产生saw的概率。
HMM就是描述我们怎么说出一句话来的。更加一般化的描述就是:
它是
放到句首的概率,乘上
后面接
的概率,最后乘上
放到句尾的概率。这个概率通常叫转移概率(Transition probability)。
那在第二步呢,我们会计算
:
是整个序列上,给定 产生 的概率,然后再连乘起来。这个概率通常叫输出概率(Emission probability)。
现在的问题是我们要怎么算出这些概率呢?
计算概率
我们要怎么算PN后面接动词的概率呢,以及怎么算给定一个动词,生成saw的概率呢,这个可以从训练数据中得到。
我们收集一大堆的句子。在这些句子中的每个词汇,我们都找语言专家帮我们标记了词性。完了之后这个问题就很容易解决了。
假如你要计算给定 的概率。
假设要算
,下一个词性是
的概率,只要计算在训练数据中
出现的次数,再算一下
这个词性后面接
的次数。然后相除就可以了。
如果你要算给定某个词性
,产生的词汇是
的概率的话,也是先计算整个训练数据中
出现的次数,以及统计一下词汇
它的词性标记为
的次数。然后也是相除就可以了。
要计算上面绿线标出的式子也很简单,只要计算
这个词性在句首出现的次数,和
在句尾出现的次数。它们都除掉句子的数量,就可以得到它们的概率。
我们统计出这些概率后,接下来要做什么呢。
如何做词性标记
我们回到原来的问题,给一个句子
,我们要寻找
。
这个
是已知的,而
是未知的。这就是为什么这个东西叫隐马尔科夫模型的原因。
怎么找出 呢,还是要靠我们算出 。
如果我们知道了
,那么使得
最大的
就是最有可能的
:
因为
是给定的,固定不变的。所以分母就可以去掉:
我们只要穷举所有的
,就可以知道哪个
的概率最大。
维特比算法(Veterbi Algorithm)
所以我们现在要做的事情就是只要穷举所有的
,算出它们的概率,找到最大概率的
。
是不是感觉穷举这件事情不好做。
假设现在有
个词性,而序列的长度(一个词汇代表一个长度)是
。那么
的数量是不是就是
这么多个呢
好在我们有维特比算法,可以把它想成一个函数,你告诉它
怎么算,它就会告诉你哪个
可以让
最大。
它的复杂度只有
。
HMM总结
HMM也是结构化学习的一种方法,我们说结构化学习方法要解决三个问题。
HMM如何回答这三个问题呢,第一个问题是,它的Evaluation就是
然后我们要解的Inference问题是哪个
可以让我们的
最大:
第三个问题的答案是
和
可以从训练数据中统计获得
缺点
我们在求解的时候是让
最大的
当做我们的输出。如果我们想让HMM得到一个正确结果的话,我们会希望正确结果的
要大于
。
但是HMM可能无法做到这件事情,在整个训练里面,它并没有保证让一个错误的
带进去使得
的概率一定是小的。
我们以一个例子来解释下,假设我们统计出来说,N后面接V的概率是90%,N后面接D的概率是10%。
然后给定V看到词汇a的概率是50%,给定D看到词汇a的概率是100%。
(下面这个图增加了V看到词汇c的概率也是50%)
今天假设我们有一个问题,我们已经知道在
这个时间点我们的词性是N,在
这个时间点看到的词汇是a,那么
的词性最有可能是什么呢?
我们可以用概率来计算一下。
如果是V的话,N产生V的概率是0.9,V产生a的概率是0.5。一起就是0.45;
如果是D的话,N产生D的概率是0.1,D产生a的概率是1。一起就是0.1;
显然V的概率更大。
但是如果我们观察一下训练数据,假设是这样的:
N后面接V,V产生c出现9次;P后面接V产生a出现9次;P后面接D产生a出现1次。
这样可以统计出N后可以接V或接D;并且接V的概率是0.9;接D的概率是0.1;
V产生a和c的概率都是0.5;
根据训练数据得到的概率会告诉我们说这里会得到V,有没有觉得不太对啊。
因为我们训练数据中有N后面接D,然后D产生a这份数据。
如果我们的测试数据里面说前面是N,产生的是a,中间你去填V。而训练数据中明明就有一笔一模一样的数据。
这样不是不对吗,这里你的训练数据告诉你应该是D了,但是对HMM来说,它会给一些在训练数据中从来没有出现过的序列很高的概率。
如果我们按照HMM的算法,它会觉得N后面接V,V产生a的概率很高。所以HMM有个特色是它会脑补它没有看过的东西。
这个就是HMM的一个问题。
但是其实这件事情也有好的一面,当你的训练数据很少的时候,也许实际上这笔数据的概率也很高,只是你没有观察到。所以HMM在训练数据少的时候,它的表现反而比其他方法还要好。
HMM为什么会产生这种脑补的现象,因为对它来说,输出概率和转移概率是分开建模的。它会假设这两个概率是独立的。
用更加复杂的模型能解决这个问题,但是容易做的很复杂。
其实CRF就可以用基于和HMM一样的模型来处理这个问题。
条件随机场
条件随机场(conditional random field,CRF)一样也要描述
,它描述的方法看起来有点奇怪。
它说
的概率正比于权重
与
点积,它们的点积结果作为
的幂。
- 是一个特征向量;
- 是从训练数据中学到的权重
- 一定是正的,并且可以大于1
所以不能说 这个东西是一个概率,只能说它是和概率成正相关的。
其实CRF不关心
是什么,它真正关心的是
。
可以写成
除掉所有可能的
的
之和。
我们知道
是和
这一项成正比的,我们可以说是这一项除以
。
把上面这个
的式子代入到
的式子,可以消掉
,就得到:
这里我们把下面这项用
表示:
它是对所有可能的
的一个求和,所以是和
是无关的。
可能感觉CRF和HMM是完全不一样的东西,其实它们的模型是一样的。
它们只是在训练上面是不一样的。
为什么说它们的模型是一样的呢?
在HMM里面,
是一大堆的概率相乘。
我们把它取
,原来的相乘就会变成了相加:
然后我们先来看看相加里面的红框框出来的这项:
这一项应该是
个
的和,我们把这一项做一下整理,写成:
这里的
表示词性,
表示词汇。如果你有10个词性,有10000个词汇的话,就是对
项进行求和。
是这个词汇 它被标记成 这件事情,在 里面总共出现的次数。 是给定词性 是词汇 的概率。
为什么可以做这个转换呢,我们来举一个例子。
现在有一个句子
,每个词汇都有标记它的词性。
我们接下来做一些计算:
比如the(不考虑大小写)这个词汇被标记成冠词的次数,在这个句子中出现了2次;
说的是其他的词汇被标记成其他的词性的次数是0次;
接下来来计算一下所有概率的相乘,取
就成了相加。D产生the的概率,加上N产生dog的概率,加上V产生ate的概率…
我们可以看到D产生the的概率出现过两次,我们就可以把它整理一下,后面乘以2:
最终整理后就可以写成:
就是所有词性产生词汇的概率(取
)乘以它们在句子里面出现的次数之和。
对其他项我们也可以做几乎一样的转换,比如下面框出来的:
把它们都写成两项相乘后,我们会发现
可以写成一大堆两项的相乘:
然后我们可以把它们描述从两个向量的内积:
所以我们可以用
来代表紫色的向量,用
来代表红色的向量,这个红色的向量是与
有关的,可以说是由
所形成的特征。
所以我们说
可以写成这样:
有个要注意的地方是,紫色向量中的元素
W_{s,t}对应到HMM中的
。
因为它们对应到HMM中的概率再取
,如果你想把它们转换成概率的话,就要取Exponential(e为底的指数函数)。
把这些权重取Exponential就可以转换为概率,但是有个问题是,我们在做训练的时候,这里的权重是可正可负的。如果取Exponential后得到的值大于1,就无法解释为概率了。
因此这里不用等于符号,而用正相关符号:
特征向量
特征向量 是怎样的呢
包含两个部分,第一个部分是有关词性和词汇的关系;第二个部分是词性之间的关系。
上面黑色箭头指的是第一个部分。
假设有
个词性,有
个可能的词汇,第一部分的特征向量的维度就是
。如果有10种可能的词性,有10000个词汇的话,那么它的维度就是100000维。
这个特征向量里面就是所有的词性与所有的词汇的配对。如果The被标记为D,出现2次的话,那么这个维度对应的值就是2。没有出现过的就标记为0。
这个向量是非常稀疏的,它的维度非常大,但是有值的不多。
第二个部分是关于词性之间的关系。怎么做呢,其实就是标记了词性
和
在
里面连续出现的次数。
所以
就是说
后面接
出现的次数,这个例子中是0。
后面接
出现过两次。
那这个向量的维度是多少呢,假设总共有
个可能的词性
那么这个向量的维度就是
因为对于所有的词性对都要有一个维度,然后每个词性与Start产生的对也是一个维度,跟End也会产生一个维度。因此最终就得到了上面的式子。
CRM和HMM想要建模的东西是一样的,但是因为CRF把它的概率描述成一个权重与特征向量的内积,所以CRF比HMM更厉害一点的在于,我们可以自定义这个特征向量。
训练准则
首先我们要收集训练数据。接下来要找一个向量
,它要去最大化目标函数
:
要找一个
,最大化给定
产生正确的序列
的概率。
这一项可以转换:
其实就是对下面的式子取
,然后除变成了减:
当我们最大化这个等式时
第一项告诉我们的是,当我们最大化这个等式时,我们会最大化我们在训练数据中看到的
对(pair)的概率。
同时我们要最小化没有看到的对的概率。如果做呢,这里要最大化一个目标函数,所以可以用梯度上升法。
梯度上升法
在梯度下降时,我们要最小化损失函数
,然后通过上面的式子来更新
。
而梯度上升做的事情也很像,我们有一个目标函数要最大化,我们在每个迭代计算下
的梯度,然后把这个梯度加给要优化的参数就好了。
训练
这是我们要优化的函数。我们要去计算
对权重的梯度。
我们的
有很多,有的
是对应到词汇和词性的对(pair),有的是对应词性和词性的对。
计算过程这里就不展示了,经过计算后,得出:
第一项是
的pair出现的次数,第二项是对所有可能的 单词
被标记成
的pair在
跟任意一个
中出现的次数 乘以 给定
产生这个
的概率。
我们来看下这个式子的含义,第一项说
和
这一对在
这个正确pair里面出现的次数。如果
在正确的
出现的次数越多,那么它对应的权重就会越大。
第二项告诉我们说,因为是减去任意一个
的里面
出现的次数。如果
在任意一个pair里面出现的次数很多的话,并且没有在训练数据中出现,那么我们就要把权重减少。
我们可以采用随机梯度上升的方法,每次随机选取一笔数据。
推断
我们现在要做的事情是,给定一个
,找一个
让
最大等同于是找个
让
最大。
在CRF里面,我们知道:
因为
是一个单调递增的函数,所以找
最大的
,等同于是找让
最大的
,就可以做一下替换:
这一项其实也可以用维特比算法来计算。
CRF与HMM
CRF不仅会增加
,它还会减少任意一个
与
所形成的
的概率,而HMM没有做这件事情。如果我们要得到正确的答案,我们会希望
的概率大于
,而CRF会减少其他
的概率。
所以与HMM比起来,CRF更有可能得到正确的结果。
举例来说。
我们前文说过,根据统计的结果,HMM给我们的答案是V。
如果是CRF的话,它会调这些概率,让正确的 对的分数比较大。
比如把
的概率由0.5调低为0.1。类似这样,最终CRF推断N后面接D。
CRF总结
CRF也是结构化方法,它也解决了三个问题。
结构化感知机/SVM
接下来看下我们上篇文章中学到的东西如何用到序列标记上面。
我们说过结构化感知机也是解决结构化问题的一个技术。它也解决了三个问题。
如果今天是序列的话,那么
应该要定义成什么样呢,很简单的方式是可以定义成CRF的方式。
第二个问题就是找到
让上面的式子最大,一样用维特比算法来解就好了。
在训练的时候,我们对所有不等于
的
,我们希望让
那怎么做呢,我们要找一个
,让下面这项
最大。接下来把
加上正常
所形成的的向量减去 KaTeX parse error: Expected group after '^' at position 18: …verset{\sim} y^̲所形成的的向量。
会不会觉得这个式子和在做CRF的梯度上升的式子很像。
如果我们忽略
这一样,把它当成1。那么
绿线标出的那项是一样的,紫线标出的那一项,虽然表面上看起来不一样,但是它们之间是很有关系的。
上面减去的由 组成的特征是可以让 最大的。其实就是概率最大的 。而CRF对所有可能的 都按照概率去做加权和。
如果在
里面只有一个是1,其他都是0的话,那么这两个东西就是等价的。
在结构化向量机训练的时候会考虑margin和误差的概念。
误差函数
是计算
和
的差异性。我们上次说过,结构化SVM的损失函数其实就是这个差异性的上界。如果你最小化结构化SVM的损失函数,那你就是在最小化错误的上界。
理论上说
可以是任何你喜欢的函数。
但是需要满足:
举个例子,如果把两个序列的差异定义成错误率的话:
就可以解决问题2.1。
我们看一下不同的方法在文献上的比较:
这是词性标记实验,纵轴是平均错误,你可以看到HMM的表现是最差的。最好的是结构化SVM。
为什么不用RNN
RNN(下篇文章就会介绍了)和LSTM会有个缺点,在做决定的时候,并没有看完整个序列。在单方向的RNN里面,要产生第t个时间点的输出时,只考虑时间1和时间t的输入,没有考虑时间t+1的输入。如果发现时间t+1的输入想要你改答案的话,那就已经来不及了。
而HMM、CRF等方法会考虑整个序列,并且可以明确考虑输出标签之间的关系。
RNN和LSTM还有个问题,它的损失和你要的错误不见得是有关系的。就是你最小化损失函数不见得会最小化错误。
而结构化的这些方法,损失就是错误的上界。
但是RNN和LSTM有个优点是结构化方法无法比拟的地方,就是可以有深层。
就是因为这点,最后导致还是RNN和LSTM比较强。
我们可以整合这些方法。
把模型比作萝卜的话,在比较深的地方,在底层用RNN和LSTM,在浅层的地方用结构化方法。结构化方法可以比较方便的描述依赖关系。
这样可能会得到比较好的结果。
以语音识别为例,一般是使用CNN/RNN或LSTM/DNN ,最后会接HMM。
我们把HMM的初始化概率 用DNN/RNN/LSTM得到的结果去代替。
但是有个问题是,蓝线标出的是
,而RNN产生的是
这种。
我们可以用条件概率公式来推导:
可以通过统计的方式得到。
出现的次数除以所有
出现的次数。
现在的问题是 怎么得到,方法很简单,就不不管它?!
我们在用HMM的时候,是给定 ,看哪个 可以让 最大,因此 是给定的。不管它的值是多少,都不会影响最后得到的 。
总结
我们今天讲了好几种不同的处理序列标记的方法,它们都解决了三个问题。
在问题1里面我们要定义一个评估函数,每个方法定义的都不一样。
在问题2都用维特比算法。
在问题3HMM就是统计;CRF要去最大化这个概率;而结构化感知机要让正确的分数大过错误的分数;结构化向量机让它们大过一个margin。
最后都可以通过让它们加上深度学习变得更加强大。
参考
1.李宏毅机器学习