1. 引言
在自然语言处理中,很多任务都涉及到序列标注,比如词性标注、分词、命名实体识别等,这些任务都有一个特点是输入序列和标签序列是等长的,因此,常用的解决方法有HMM、MEMM、CRF等,本文将介绍一个2015年提出来的非常经典模型,即BILSTM-CRF模型,该模型现在已经成为命名实体识别、词性标注、分词等任务的主流模型。
2. BILSTM-CRF原理介绍
2.1 BILSTM-CRF模型介绍
BILSTM-CRF模型主要包括两部分,即BILSTM层和CRF损失层。BILSTM层如下图所示,对于一个输入句子
x
x
x,首先经过embedding层将每个词汇或者字符映射为一个词向量或者字符向量,然后传入BILSTM层,获得句子的前向和后向向量,接着将前向和后向向量进行拼接作为当前词汇或字符的隐藏状态向量。
在BILSTM每个时间步,虽然可以采用一个sorfmax层直接预测该时间步的标签,但是作者发现直接采用LSTM或者BILSTM进行预测效果一般,因为此时预测出来的标签并没有考虑前后标签的信息,在一些序列标注任务,比如命名实体识别,我们知道有些标签之前的转移是不合法的,比如人名我们一般是类似于“B-PER,I-PER,I-PER”的标注格式,如果采用LSTM或者BILSTM直接预测的话,可能预测出来的标签是“B-PER,B-PER,I-PER”,这时明显是不合法的。因此,为了考虑相邻标签的信息,作者在BILSTM层后接了一层CRF层,因为CRF不仅可以考虑当前输入的信息,还可以考虑前后标签的信息,具体的原理介绍可以参考我之前的另一篇文章《条件随机场原理介绍》。CRF的结构如下图所示:
对于一个输入句子
[
x
]
1
T
[x]_{1}^{T}
[x]1T,记
[
f
θ
]
i
,
t
\left[f_{\theta}\right]_{i, t}
[fθ]i,t表示在第
t
t
t个时刻、第
i
i
i个标签的score,记
[
A
]
i
,
j
[A] _{i, j}
[A]i,j为CRF的转移概率矩阵中的第
i
j
ij
ij个位置的概率,表示由状态
i
i
i转移到状态
j
j
j的概率,则对于一个输入句子及其标签序列
[
i
]
1
T
[i]_{1}^{T}
[i]1T,其最终的分数为:
s
(
[
x
]
1
T
,
[
i
]
1
T
,
θ
~
)
=
∑
t
=
1
T
(
[
A
]
[
i
]
t
−
1
,
[
i
]
t
+
[
f
θ
]
[
i
]
t
,
t
)
s\left([x]_{1}^{T},[i]_{1}^{T}, \tilde{\theta}\right)=\sum_{t=1}^{T}\left([A]_{[i]_{t-1},[i]_{t}}+\left[f_{\theta}\right]_{[i]_{t}, t}\right)
s([x]1T,[i]1T,θ~)=t=1∑T([A][i]t−1,[i]t+[fθ][i]t,t)
最终BILSTM-CRF模型的结构如下:
3. NCRF++原理介绍
我们知道,BILSTM-CRF作者是基于词向量的形式,但是在一些场合下,比如命名实体识别中的人名、地名,往往会有很多新的词汇出现,这时进行预测时,可能会出现OOV的情况,导致准确率不高。因此,在2018年时,Jie Yang等人在BILSTM-CRF的基础上,做了一点微改,不仅考虑词向量,还结合字符向量,作者在实验中发现,加入字符向量可以显著地提高模型的准确率,因此,这里顺便介绍一下这个模型。
3.1 NCRF++原理介绍
NCRF++模型的结构如下图所示,其结构跟BILSTM-CRF非常像,只是在词向量的基础上,采用CNN或者LSTM对这个词汇的字符向量进行编码,将其转化为一个字符向量,然后将字符向量与词向量进行拼接,再进去BILSTM层。对于字符向量部分,作者采用的CNN是TextCNN的结构,LSTM采用的是BILSTM的结构,具体如下图所示,并且在实验中发现,采用CNN或LSTM效果都差不多,这里不再赘述。
3. BILSTM-CRF的tensorflow实现
对于BILSTM-CRF模型的tensorflow实现,可以参考JHWen的代码:
对于NCRF++,作者自己用pytorch搭建了一个第三方库,可以方便地切换各种结构的组合:
4.总结
最后,总结一下对模型的评价:
- BILSTM-CRF模型更加稳健,不仅可以考虑到输入的前后信息,还可以考虑到标签的前后信息。
- BILSTM-CRF对embedding的初始化依赖性不强,不需要采用预训练的词向量也可以达到一个比较好的结果。
- NCRF++由于引入字符级向量,因此,可以有效提升OOV的准确率,效果要比BILSTM-CRF更好一点。