自然语言处理NLP(5)——序列标注b:条件随机场(CRF)、RNN+CRF

在上一部分中,我们了解了序列标注问题以及解决该种问题的一种方法——隐马尔科夫模型HMM:自然语言处理NLP(4)——序列标注a:隐马尔科夫模型(HMM)
在这一部分中,我们将要介绍解决序列标注问题的另外两种方法:条件随机场(CRF),以及RNN+CRF。

了解了HMM之后,我们可以发现HMM有两个很明显的缺点:
1.HMM定义的是联合概率,必须列举出所有可能出现的情况,这在很多领域是很困难的。在NLP领域,常知道各种各样但又不完全确定的信息,需要一个统一的模型将这些信息综合起来。
2.HMM遵循一个假设:输出独立性假设。这要求序列数据严格相互独立才能保证推导的正确性,导致不能考虑上下文特征。而在NLP领域,上下文信息是很重要的。

因此,引入条件随机场(CRF)。

【一】最大熵模型

在介绍条件随机场(CRF)之前,首先了解一下什么是最大熵模型。

简而言之,最大熵模型就是这个式子:
pλ(yx)=1Zλ(x)exp(iλifi(x,y))p_λ(y|x)=\frac{1}{Z_λ(x)}exp(\sum_iλ_if_i(x,y))
其中,
Zλ(x)=yexp(λifi(x,y))Z_λ(x)=\sum_yexp(\sumλ_if_i(x,y))
称为归一化因子。

现在我们举个例子:
假设我们有一个健康评估的系统,每个人的健康水平分为“优、良、中、差”四个等级,与健康关联的信息包括“血压、血糖、运动、抽烟状况……”。

很明显,健康水平(四种)是我们系统的输出(所求目标)yy
我们将“血压、血糖”等信息称为特征,这些特征是需要我们人工进行挑选的,以保证特征与所求目标之间的关联性。
在这个例子中,如果选取了类似“头发弯曲程度”这样的特征,可能就与“健康水平”这个目标关联性较小,我们要尽量避免这样的特征。

假设我们现在挑选出了这样四种特征:
{(血压)、(血糖)、(血压 吸烟情况(支/天))、(运动情况(次/天))}
值得注意的是,这个特征集合中的第三项是由两个属性组合而成的。如果你想的话,可以利用更多属性组合成一个特征。

在这里,我们只是用上述四个特征举个例子,如果你喜欢,完全可以用其他的特征或者更多的特征进行描述。

现在,有一个人张三,利用上述特征集合描述之后的情况是这样的,我们称其为特征信息集合 xx
自然语言处理NLP(5)——序列标注b:条件随机场(CRF)、RNN+CRF
通过这个例子,我们回忆最大熵模型:
pλ(yx)=1Zλ(x)exp(iλifi(x,y))p_λ(y|x)=\frac{1}{Z_λ(x)}exp(\sum_iλ_if_i(x,y))
pλ(yx)p_λ(y|x)是给定 xx 之后,输出 yy 的分布,这里的 xx 就是上述特征信息集合(各个特征值组成的集合)。
我们将 λifi(x,y)λ_if_i(x,y) 称为特征函数,这里面的 xx 是特征信息集合中的某一个元素(例如,“血糖=7.0” 或者 “血压=150 烟=5”)。特征函数的参数 λiλ_i 是系统参数,对每个不同的 x,yx,y 有不同的值。
值得注意的是,组合特征以组合的形式存在:有一个 xx 是“血压=150”,也有另一个 xx 是“血压=150 且 烟=5”,其所对应的 λiλ_i 也未必相同。

用一张图直观表示:
自然语言处理NLP(5)——序列标注b:条件随机场(CRF)、RNN+CRF
归一化因子的作用是将最后的输出值转化为概率的形式(不同输出的和为1),很好理解,在这里不进行详细阐述。

看到这里,大家一定有这样一个问题:特征函数是什么?
特征函数 fi(x,y)f_i(x,y) 表示了某个特征信息对某个输出是否有影响的事实:
如果满足条件,fi(x,y)=1f_i(x,y) = 1;否则,fi(x,y)=0f_i(x,y) = 0
以“血压=150”为例:
自然语言处理NLP(5)——序列标注b:条件随机场(CRF)、RNN+CRF
对于“中、差”的健康状况也是相同的。

这些信息都是从数据库中得到的:有张三的血压为150,且张三的健康状况为“优”,则对应特征函数值记为1;有李四的血压为150,且李四的健康状况为“差”,则对应特征函数值记为1。λiλ_i 控制其所占权重。

我们可以看出,最大熵模型有这样的特点:
1.可以综合多个不完全的信息。
2.这些信息可以以某种方式灵活表示(特征函数可以自行定义)。

好了,现在我们的最大熵模型已经形成了,我们看看它在序列问题中的效果:
自然语言处理NLP(5)——序列标注b:条件随机场(CRF)、RNN+CRF
把图中的两个特征信息(x1,x2x_1,x_2)看作句子中的每个词(字)的特征信息,把输出(y1,y2y_1,y_2)看作序列标注结果。

好像没什么问题?
不,问题大了。

我们可以看出,每个输入对应的输出是独立的(和HMM一样)。假设我们进行的是命名实体识别,完全有可能输出两个相邻的B(实体开始符),而从逻辑上来讲,这种情况是完全不可能发生的。
(这部分看不太懂的朋友们可以参看上一部分中有关命名实体识别的内容:自然语言处理NLP(4)——序列标注a:隐马尔科夫模型(HMM)

所以,最大熵模型还不够,我们还需要条件随机场(CRF)。

【二】条件随机场(CRF)

先来描述几个(没什么用)的概念:
随机场:随机场可以看作一组随机变量的集合,这些随机变量间可能有依赖关系,给每一个位置中随机变量按照某种分布随机赋予相空间的一个值之后,其全体就叫做随机场。
马尔可夫性质:指的是一个随机变量序列按时间先后关系依次排开的时候,第 n+1n+1 时刻的分布特性,与 nn 时刻以前的随机变量的取值无关。
马尔科夫随机场(MRF):具有马尔科夫性质的随机场。
条件随机场(CRF):如果给定的MRF中每个随机变量下面还有观察值,要确定的是给定观察集合下,这个MRF的分布,也就是条件分布,那么这个MRF就称为CRF(Conditional Random Field)。

这几个概念大家了解一下就好~

在上面的介绍中,最大熵模型是这样的:
自然语言处理NLP(5)——序列标注b:条件随机场(CRF)、RNN+CRF
在此基础上,条件随机场是这样的:
自然语言处理NLP(5)——序列标注b:条件随机场(CRF)、RNN+CRF
条件随机场将最大熵模型中“特征函数”的概念分为两个类别:
1.结点特征函数:类似于最大熵模型中的特征函数,描述特征信息对当前输出的影响;
2.边特征函数:描述特征信息对输出转换的影响。

图中各个部分的解释已经很清晰了,在这里就不再赘述。

相比于最大熵模型,条件随机场多了“边特征函数”,用以解决不合理标注问题。很明显,在条件随机场边特征函数的约束下,输出两个相邻B的情况是不可能发生的。

由此定义的线性条件随机场基本形式如下:
p(yx,λ)=1Z(x)exp(jiλjtj(yi1,yi,x,i)+kiμksk(yi,x,i))p(y|x,λ)=\frac{1}{Z(x)}exp(\sum_{ji}λ_jt_j(y_{i-1},y_i,x,i)+\sum_{ki}μ_ks_k(y_i,x,i))
其中,
Z(x)=yexp(jiλjtj(yi1,yi,x,i)+kiμksk(yi,x,i))Z(x)=\sum_yexp(\sum_{ji}λ_jt_j(y_{i-1},y_i,x,i)+\sum_{ki}μ_ks_k(y_i,x,i))
同样为归一化项。

式子中各部分与最大熵模型类似,在这里不再一一进行解释。

该模型中,
输入为:x={x1,x2,...,xn}x=\{x_1,x_2,...,x_n\}(观测序列)
输出为:y={y1,y2,...,yn}y=\{y_1,y_2,...,y_n\}(标记序列)
参数为:λj,μkλ_j,μ_k
注意,特征函数是预先定义的。

条件随机场由特征函数 tj,skt_j,s_k 以及对应权重 λj,μkλ_j,μ_k 所确定。

在应用方面,有很多实现条件随机场的开源工具包,例如CRF++。这些工具包的使用我们不在这里进行详细描述,有兴趣的朋友们可以自行查阅相关资料。但是有一点是在使用任何工具包时都要注意的:
特征函数是CRF最重要的部分,CRF的效果与特征函数的定义密不可分。

【三】RNN+CRF

在结合CRF之前,我们先想象一下只用RNN解决序列标注问题的方法。
回想一下,无论是单向RNN还是双向RNN,都没有在输出层建立前后文联系。因此,与HMM类似,仅用RNN解决序列标注问题同样存在不合理标注(例如两个相邻的B)的问题。
所以,在此基础上,提出了RNN+CRF的方法。

RNN+CRF的结构是这个样子的:
自然语言处理NLP(5)——序列标注b:条件随机场(CRF)、RNN+CRF
模型结构看起来很复杂是不是?
拆开来看,其实它只是在双向RNN上堆了一层CRF。
双向RNN的部分在这里不再赘述,不理解的朋友们可以参考博客:神经网络基础:DNN、CNN、RNN、梯度下降、反向传播

很容易理解,双向RNN的输出是一个 nkn*k 矩阵,表示了每个位置对每个标注标签的打分(序列长度为 nn,每个位置有 kk 种标签,对于B E I O标签,k=4k=4),但正如我们刚刚所分析的,这可能导致不合理标注问题的出现。
于是,在RNN输出的基础上,又堆叠了一层CRF,利用边特征函数规避不合理标注问题。很明显,每个RNN输出之间的边特征函数可以用一个kkk*k矩阵描述,表示了由每个标注标签到其他标注标签的转移打分(类似马尔可夫模型中的转移概率矩阵)。

在这里,我们可以看出,RNN的输出矩阵(nkn*k)描述了结点特征函数,而输出之间的连接矩阵(kkk*k)描述了边特征函数。

模型的学习过程与预测过程与RNN类似,在这里就不再赘述。

在这里,值得注意的是,在模型的学习过程中,RNN自动提取了特征函数(每当想到这里,都会感叹道“神经网络真是个神奇的东西”),这也避免了人工挑选特征函数的工作。

这一部分中,我们介绍了解决序列标注问题的另外两种方法:CRF、RNN+CRF。目前,RNN+CRF的方法是处理序列标注问题的方法中相对较好的一种方法。
在下一部分的内容中,我们将会介绍NLP中最基本的问题之一:词法分析。

如果本文中某些表述或理解有误,欢迎各位大神批评指正。

谢谢!