HMM、MaxEnt、CRF 模型介绍
随着近年来互联网等新兴媒体的快速发展,人类已经进入了信息爆炸的时代。同时也越来越希望计算机能够理解人类的语言,以更好地帮助人类完成各种日常工作。因此自然语言处理成为了近年来的研究热点。
而在自然语言处理中,序列标注模型是最常见的模型,也有着广泛地应用。与一般分类问题不同的是,序列标注模型输出的是一个标签序列。通常而言,标签之间是相互联系的,构成标签之间的结构信息。利用这些结构信息,序列标注模型在序列标注问题上往往可以达到比传统分类方法更高的性能。本文将主要介绍了目前在序列标注问题中常见的三种模型,隐马尔可夫模型(Hidden Markov Model,HMM),最大熵模型(The Maximum Entropy Principle)、和条件随机场(Conditional Random Field,CRF)。并对三种模型的原理结合序列标注问题进行具体阐述,最后会总结四种模型在序列标注上的优缺点,并提供了实现基本的 HMM 模型和最大熵模型的 python 代码。
首先在介绍该模型时先来介绍马尔可夫链,马尔可夫链是指的每一个状态的转移只依赖于之前的 n 个状态,而最为简单的模型就是每一个状态只依赖于前一个状态,也可以成为马尔可夫的一阶过程。
以一个简单的例子为例,假如天气服从马尔可夫的一阶过程,也就是说今天的天气状态只与昨天的天气状态有关,我们可以建立一个如下的状态。
马尔可夫的状态转移图
这样的话,我们就可以构建一个晴阴的状态转换矩阵p= ( 0.9 0.1 0.5 0.5 ) \begin{pmatrix} 0.9 & 0.1 \\ 0.5 & 0.5 \end{pmatrix} (0.90.50.10.5),那么从今天(状态为晴或者阴)开始,在未来的某一天,晴阴的概率分布是什么是可以利用马尔可夫链计算出来的。
lim n → ∞ ( 1 0 ) p n = ( 0.8333 0.167 ) \lim_{n\to \infty \begin{pmatrix} 1 & 0 \end{pmatrix} p^n= \begin{pmatrix} 0.8333& 0.167 \end{pmatrix}} limn→∞(10)pn=(0.83330.167) ,
这里1代表今天的状态是晴天,之后很久的未来某一天的晴阴概率将达到稳态分布,即晴的概率为 0.8333。
总结上面的一阶马尔可夫链,我们可以总结出一个一阶马尔可夫过程包含三个部分。
状态变量:例如晴天、阴天
初始向量:定义序列在时间为 0 的时候状态的概率,如上面的(1 0)
状态转移矩阵:定义的是每一种状态转移到另一种状态的概率(可以根据大量的已有信息统计经验得出)
所有能被描述成这样的系统被称之为马尔可夫过程。
那么,在我们处理序列标注问题时,我们需要解决的问题是对一个句子序列进行词性或实体的预测,实际上我们需要预测的词性或实体序列 ( s 1 , s 2 , s 3 , s 4 ) ( s_1, s_2, s_3, s_4) (s1,s2,s3,s4)和句子序列 ( o 1 , o 2 , o 3 , o 4 ) ( o_1, o_2, o_3, o_4) (o1,o2,o3,o4)的对应关系可以和通信过程中的解码问题对应。
原始信息 ----编码---- ( s 1 , s 2 , s 3 , s 4 ) ( s_1, s_2, s_3, s_4) (s1,s2,s3,s4) ----解码---- ( o 1 , o 2 , o 3 , o 4 ) ( o_1, o_2, o_3, o_4) (o1,o2,o3,o4)
那么如何去推测预测词性或者实体序列呢,其实想法就是从已有的信息,即大量的标注信息中找到最有可能的一条序列来表示要预测的句子的序列。
用概率论的语言描述就是在已知 ( o 1 , o 2 , o 3 , o 4 ) ( o_1, o_2, o_3, o_4) (o1,o2,o3,o4)的情况下,求得令条件概率 P ( s 1 , s 2 , s 3 ⋯ ∣ o 1 , o 2 , o 3 ⋯ ) P( s_1, s_2, s_3 ⋯ | o_1, o_2, o_3 ⋯ ) P(s1,s2,s3⋯∣o1,o2,o3⋯)达到最大值的那个信息串 ( s 1 , s 2 , s 3 , s 4 . . . . ) ( s_1, s_2, s_3, s_4....) (s1,s2,s3,s4....)
隐含马尔可夫模型就是可以帮我们解决这么一个问题的模型,隐含马尔可夫模型是马尔可夫链的一个扩展:任何一个时刻的状态 ( s 1 , s 2 , s 3 , s 4 ) ( s_1, s_2, s_3, s_4) (s1,s2,s3,s4)是不可见的,所以观察者没法观察到。但是隐含马尔可夫模型会在每一个时刻 t 输出一个符号 o t o_t ot, 而且 o t o_t ot跟 s t s_t st相关且仅跟 s t s_t st 相关,隐含马尔可夫模型示意图如下:
序列标注在 HMM 模型上的示意图
由于我们预先可以获得大量地标注过的训练语料,而这些语料可以通过统计的方式去计算出相关的状态转移概率,观测量概率等等。结合隐马尔可夫模型,我们就可以对隐含的序列状态进行预测了,那么在开始进行预测之前,我们定义隐马尔可夫模型的参数 λ = ( A , B , π ) λ = (A, B, π) λ=(A,B,π)。含义如下:A 表示的是隐藏状态转移概率,B 表示的是观测量的概率分布,即某一个观测量与隐藏状态的同时出现的概率分布,π即是指的隐藏状态序列的初始时刻也就是时间为0时各个隐藏状态的概率分布。下图结合词性标注问题对上述参数做了进一步说明。
序列标注问题在 HMM 中各参数的解释用例图
隐含马尔可夫模型通常可以解决三个问题。
这里来解决本次报告中重点要来解决的预测问题。解决预测问题,需要用到维特比算法(Viterbi Algorithm)。我们可以通过列出所有可能的隐藏状态序列并且计算对于每个组合相应的观察序列的概率来找到最可能的隐藏状态序列。最可能的隐藏状态序列是使下面这个概率最大的组合
a r g m a x s P ( s 1 , s 2 , s 3 ⋯ , o 1 , o 2 , o 3 ⋯ ∣ λ ) = ∏ P ( s t ∣ s t − 1 ) ∗ P ( o t ∣ s t ) argmax_s P( s_1, s_2, s_3 ⋯ , o_1, o_2, o_3 ⋯ |λ) = ∏ P(s_t|s_{t-1})*P(o_t|s_t) argmaxsP(s1,s2,s3⋯,o1,o2,o3⋯∣λ)=∏P(st∣st−1)∗P(ot∣st)
即找到一个在某一个隐藏状态序列S生成观测序列O的概率最大的情况。如果利用穷举算法去找出所有的可能的组合,时间代价太大,如果一个观测序列里值有 M 个,总的状态数是 N,那么需要遍历的是 N M N^M NM。显然代价太大。为此我们需要递归地考虑最有可能的隐藏状态序列,类似于动态规划,这么做有两个重要的原因:
接下来我们来介绍维比特算法。
Init:
δ j ( t ) = M A X s 1 , s 2 , s 3 . . . s t − 1 P ( s 1 , s 2 , . . . , s t = j , o 1 , o 2 , o 3 ⋯ ∣ λ ) = ∏ P ( s t ∣ s t − 1 ) ∗ P ( o t ∣ s t ) \delta_j(t)=MAX_{s_1,s_2,s_3...s_{t-1}} P( s_1, s_2, ..., s_t=j , o_1, o_2, o_3 ⋯ |λ) = ∏ P(s_t|s_{t-1})*P(o_t|s_t) δj(t)=MAXs1,s2,s3...st−1P(s1,s2,...,st=j,o1,o2,o3⋯∣λ)=∏P(st∣st−1)∗P(ot∣st)
称 δ j ( t ) \delta_j(t) δj(t)为这些路径局部最佳路径。其中每个局部最佳路径都有一个相关联的概率。该表达式是指 t 时刻到达状态 j 的所有序列概率中最大的概率。
Induction:
δ j ( 1 ) = π j b j o 1 \delta_j(1)=π_jb_{jo1} δj(1)=πjbjo1 1 ≤ j ≤ N 1\leq j \leq N 1≤j≤N
δ j ( t + 1 ) = ( M A X δ i ( t ) a i j ) b j o t + 1 \delta_j(t+1)=(MAX\delta_i(t)a_{ij})b_{jo_{t+1}} δj(t+1)=(MAXδi(t)aij)bjot+1 1 ≤ t ≤ T − 1 1\leq t \leq T-1 1≤t≤T−1
B a c k T r a c k ( t + 1 , j ) = i BackTrack(t+1,j)=i BackTrack(t+1,j)=i 1 ≤ t ≤ T − 1 1\leq t \leq T-1 1≤t≤T−1
N 代表共有多少个状态,T 代表序列的总时刻或者是总长。初始时刻的隐藏状态概率计算需要使用初始概率分布,之后的时刻利用之前一个时刻算出的到达各状态的概率进行计算。BackTrack 记录每一个时刻 j 状态最优路径的前一个状态是什么。
END:
result = M A X j δ j ( T ) MAX_j\delta_j(T) MAXjδj(T), t T = M A X j t = T t_T=MAX_j t =T tT=MAXjt=T
for i=T–>2 do
t i − 1 = B a c k T r a c k ( i , t i ) t_{i-1}=BackTrack(i,t_i) ti−1=BackTrack(i,ti)
end for
在时刻 T 结束时,找出概率最大的路径,并通过 BackTrack 记录的状态回溯过去,将最优的隐藏状态输出
通过这样的方式便可以找到一条最优的序列标注路径,同时这里有必要对词性标注这块的HMM算法做一个简单的说明。我们是要求的在某一个标签序列下生成该句子序列的概率,可以表示为 P ( w 1 , w 2 , w 3 ⋯ , t 1 , t 2 , t 3 ⋯ ) P( w_1,w_ 2, w_3 ⋯ , t_1, t_2, t_3 ⋯ ) P(w1,w2,w3⋯,t1,t2,t3⋯),这里的 w i w_i wi代表序列中的词, t i t_i ti代表的句子序列对应的标签序列中的标签。
我们知道 P ( w 1 , w 2 , w 3 ⋯ w N , t 1 , t 2 , t 3 ⋯ , t N ) P( w_1,w_ 2, w_3 ⋯w_N , t_1, t_2, t_3 ⋯,t_N ) P(w1,w2,w3⋯wN,t1,t2,t3⋯,tN)= P ( t 1 , t 2 , t 3 , . . . t N ) ∗ P ( w 1 , w 2 , . . . w N ∣ t 1 , t 2 , . . . t N ) P(t_1,t_2,t_3,...t_N)*P(w_1,w_2,...w_N|t_1,t_2,...t_N) P(t1,t2,t3,...tN)∗P(w1,w2,...wN∣t1,t2,...tN)
HMM这里有两个假设:
熵是随机变量不确定性的度量,不确定性越大,熵值就越大。假设离散随机变量 X 的概率分布为 P(x),则其熵为:
H ( P ) = − ∑ x P ( x ) l o g P ( x ) H(P)=-\sum_xP(x)logP(x) H(P)=−∑xP(x)logP(x)
熵可以理解为对随机事件的信息量求期望,不确定性度量的本质即为信息量的期望,同时我们可以看到假如一个事件是确定事件,即概率为 1,熵为 0 也就是最小。
两个随机变量的 X,Y 的联合分布,可以形成联合熵,用 H(X,Y)表示。条件熵 H(X|Y) = H(X,Y) - H(Y)。
我们的目的是使得条件概率分布 P ( Y ∣ X ) P(Y|X) P(Y∣X)的条件熵最大:
H ( P ) = − ∑ x , y p ( x , y ) l o g P ( y ∣ x ) H(P)=-\sum_{x,y}p(x,y)logP(y|x) H(P)=−∑x,yp(x,y)logP(y∣x)
最大熵原理是统计学的一般原理,也是概率模型学习的一个准则。最大熵原理认为,学习概率模型时,在所有可能的概率模型中,熵最大的模型是最好的模型。如果总结起来就是如下两个原则:第一是承认已知事物(知识)。第二是对未知事物不做任何假设,没有任何偏见,也是要求保证熵最大,在未知事物不偏袒任何一方,再说白一点是保证在这一块是均匀的概率分布。
以一个词性标注的任务为例,举一个简单地例子,比如说“学习”这个词既可以被标注为 y 1 y_1 y1名词, 也可以被标注为 y 2 y_2 y2动词。同时我们提供了这个词之前一个词的词性为 x 1 x_1 x1名词, x 2 x_2 x2形容词, x 3 x_3 x3动词, x 4 x_4 x4副词。
在没有任何限制的条件下,最大熵原理认为任何一种解释都是等概率的。也就是说:
P ( y 1 ∣ x 1 ) = P ( y 1 ∣ x 2 ) = P ( y 1 ∣ x 3 ) = P ( y 1 ∣ x 4 ) = P ( y 2 ∣ x 1 ) = P ( y 2 ∣ x 2 ) = P ( y 2 ∣ x 3 ) = P ( y 2 ∣ x 4 ) = 1 8 P( y_1|x_1) = P( y_1| x_2) = P( y_1| x_3) = P(y_1|x_4) = P( y_2|x_1) = P(y_2|x_2) = P(y_2|x_3) = P(y_2|x_4) =\frac{1}{8} P(y1∣x1)=P(y1∣x2)=P(y1∣x3)=P(y1∣x4)=P(y2∣x1)=P(y2∣x2)=P(y2∣x3)=P(y2∣x4)=81
实际中总有或多的限制条件,比如说副词在开头时,学习作为动词的概率变得非常大。为此我们设计用特征函数 f(x,y)描述输入 x,输出 y 之间的某一个事实,只有 0 和 1 两种值, 称为二值函数。
f ( x , y ) = { 1 , i f y = " 名 词 " a n d x = “ 副 词 ” 且 是 开 头 0 , f(x,y) = \begin{cases} 1, & if y="名词" and x=“副词”且是开头\\ 0, \end{cases} f(x,y)={1,0,ify="名词"andx=“副词”且是开头
最大熵模型根据最大熵原理在类似上面的特征限制下选择最优的概率分布。
该条件约束优化问题的 拉格朗日函数即可以建立起来,求解推导(参考李航P85)最大熵模型的后验概率:
这里 Z(x)表示的归一化因子,而这里的参数集合 λ 1 , λ 2 , … { \lambda_1,\lambda_ 2, … } λ1,λ2,…对应着 n 个限制,它们需要通过观测数据训练出来。
这里我们介绍通用迭代算法 GIS,它的算法流程如下:
最大熵模型的训练步骤
应用最大熵模型的统计方法可以把模型与语言学知识分为两个模块进行处理,它也具备几个优势:
条件随机场模型简单来讲也是一种分类器,尤其是以解决序列问题为主,因为它在分类是不仅仅考虑考虑当前的信息特征,同时也会将与其相邻的标签信息考虑进去(当然 CRF 不仅仅可以联系前后信息,序列中任何位置的信息均可以考虑其中),进行序列标注、风险预测时,时间顺序相当重要,这样的信息在预测分类具有重要的信息依据,不能将其忽视掉。
随机场可以看成是一组随机变量的集合(这组随机变量对应同一个样本空间)。当给每一个位置按照某种分布随机赋予一个值之后,其全体就叫做随机场。当然,这些随机变量之间可能有依赖关系,一般来说,也只有当这些变量之间有依赖关系的时候,我们将其单独拿出来看成一个随机场才有实际意义,这就是所谓的条件随机场的定义。
接下来,以一个具体的词性标注的例子来介绍最为基本的线性 CRF。例如我需要对一句话进行词性的标注。
平安科技 / 位于 / 上海市/ , / 该公司 / 是 / 在 / 2008年 / 建立。
【名词】【介词】【名词】【标点】【名词】 【谓语】【介词】【时间】【动词】
以上面的话为例,有 9 个单词,我们将:(名词,介词,名词,标点,名词,谓语,介词,时间,动词)作为一个标注序列,称为 l l l, 可选的标注序列有很多种,比如还可以是这样:(名词,动词,动词,标点,名词,谓语,介词,时间,动词),我们要在这么多的可选标注序列中,挑选出一个最靠谱的作为我们对这句话的标注。怎么判断一个标注序列靠谱不靠谱呢?就我们上面展示的两个标注序列来说,第二个显然不如第一个靠谱,因为它把第二、第三个单词都标注成了动词,动词后面接动词,这在一个句子中通常是说不通的。假如我们给每一个标注序列打分,打分越高代表这个标注序列越靠谱。上面所说的动词后面还是动词就是一个特征函数,我们可以定义一个特征函数集合,用这个特征函数集合来为一个标注序列打分,并据此选出最靠谱的标注序列。也就是说,每一个特征函数都可以用来为一个标注序列评分,把集合中所有特征函数对同一个标注序列的评分综合起来,就是这个标注序列最终的评分值。
首先为其设定一组特征方程(特征函数) 。以上述的词性标注为例,它接收四个参数:
它的输出值是 0 或者 1,0 表示要评分的标注序列不符合这个特征,1 表示要评分的标注序列符合这个特征。
定义好一组特征函数后,我们要给每个特征函数 f f f赋予一个权重 λ \lambda λ 。关于权重的获得会在下面一节中提到。现在,只要有一个句子 s,有一个标注序列 l l l,我们就可以利用前面定义的特征函数集来对 l l l 评分。
上式中有两个相加,外面的相加用来相加每一个特征函数 ,里面的相加用来相加句子中每个位置的单词的的特征值。
最终,我们通过指数与归一的方式将转换这些得分为 0,1 之间的概率。
公式的分母表示的是所有的预测序列的打分加和的结果,分子是某一个预测序列的打分,这样的比值越大的序列,可靠性越高。
显然在完成例如词性标注的过程中,仅仅依靠刚才的一种词性标签与词性标签联系当然是不够的,接下来可以看到几个特征函数。
当 是“副词”并且第 i 个词以“地”结尾时,我们就让 f 1 f_1 f1 = 1,其他情况 f 1 f_1 f1为 0。不难想到, f 1 f_1 f1特征函数的 λ 1 \lambda_1 λ1权重应当是正的。而且 λ 1 \lambda_1 λ1越大,表示我们越倾向于采用那些把以“地”结尾的单词标注为“副词”的标注序列。
如果 i=1, 是“动词”,并且句子 s 是以“?”结尾时, f 2 f_2 f2 = 1,其他情况 f 2 f_2 f2 = 0。同样, λ 2 \lambda_2 λ2应当是正的,并且 λ 2 \lambda_2 λ2越大,表示我们越倾向于采用那些把问句的第一个单词标注为“动词”的标注序列。
如果 l i l_i li和 l i − 1 l_{i-1} li−1都是介词,那么 f 3 f_3 f3 = 1,其他情况 f 3 f_3 f3 = 0。这里,我们应当可以经过训练之后想到 λ 3 \lambda_3 λ3是负的,并且 λ 3 \lambda_3 λ3的绝对值越大,表示我们越不认可介词后面还是介词的标注序列。
接下来回到如何学习 CRF 权重这个问题上去。一种方式是使用梯度上升,假设我们有一组训练样本(包含了句子以及相关的词性标注标签结果)。一开始,为 CRF 模型随机初始化权重值,为了使这些随机初始的权重值调整为正确的值,遍历每一个训练样本,执行如下的算法流程。
表 4 权重学习算法的步骤
有了 CRF 模型,这时如果来了一个句子,我们该如何标注它呢?最直接的方式就是为每一个可能的标注 l l l计算 p ( l ∣ s ) p(l|s) p(l∣s),选取一种概率值最大的打标。然而打标的方式又是幂指数级别的,计算量极大。为此我们可以在线性链式的 CRF 继续采用类似 HMM 的维特比的算法进行序列的预测。
最大熵模型可以使用任意的复杂相关特征,这一点与 CRF 类似。但是,作为一种分类器模型它的缺点是:每个词都是单独进行分类的,标记之间的关系无法得到充分利用,具有马尔可夫链的 HMM 模型可以建立标记之间的马尔可夫关联性,这是最大熵模型所没有的。
CRF 与最大熵模型(包括最大熵马尔可夫模型)的本质区别是:最大熵模型在每个状态都有一个概率模型,在每个状态转移时都要进行归一化。如果某个状态只有一个后续状态,那么该状态到后续状态的跳转概率即 1。这样,不管输入为任何内容,它都向该后续状态跳转。而 CRF 是在所有的状态上建立一个统一的概率模型,这样在进行归一化时,即使某个状态只有一个后续状态,它到该后续状态的跳转概率也不会为 1,从而解决了标记偏置问题。
因此作为传统序列标注任务中,传统模型里(非 deep learning 方法)CRF 模型能取得非常好的效果。CRF 模型的优点:
相关代码
https://github.com/fancybian/HMM-POS-Tagger
该代码简单实现了基于 nltk 的 brown 语料对句子进行词性分析。主要是基于维比特算法的实现。
https://github.com/fancybian/MaxEnt-predict
该代码实现了最为基本的最大熵模型,训练过程采用最为简单的 GIS 算法,去对一个序列进行结果预测。
参考文献
[1]吴军 《数学之美》 人民邮电出版社,2012
[2]常宝宝 自然语言处理的最大熵模型
[3]李航 《统计学习方法》 清华大学出版社,2012
[4]Edwin Chen. Introduction to Conditional Random Fields http://blog.echen.me/2012/01/03/introduction-to-conditional-random-fields/
[5] Charles Sutton. An Introduction to Conditional Random Fields,2010
[6] Hanna M. Wallach, Conditional Random Fields: An Introduction∗,2004
[7]最大熵模型学习 http://blog.csdn.net/itplus/article/details/26549871
[8]HMM 模型学习 http://blog.csdn.net/baimafujinji/article/details/51285082