美文网首页Python文集序列标注命名实体识别
序列标注与中文命名实体识别(NER)

序列标注与中文命名实体识别(NER)

作者: 415lab_MoMo | 来源:发表于2017-07-29 14:00 被阅读1284次

            最近一直再研究序列标注问题,对序列标注问题有了一点儿心得体会。然后就想写一篇博客介绍一下序列标注问题,序列标注问题中的中文命名实体识别问题,及常用的Bi-LSTM+CRF模型。


    1.序列标注

    序列标注简单的来说就是给定一个序列,对序列中的每一个元素做一个标记,或者说给每一个元素打一个标签,这是一个比较宽泛的概念。中文命名实体识别、中文分词和词性标注等这些基本的NLP任务都属于序列标注的范畴。

    我们拿中文命名实体识别来举例解释什么是序列标注,假设我们有如下句子:

    今年海钓比赛在厦门市与金门之间的海域举行。

    我们对这句话进行序列标注之后的结果:

    今(O)年(O)海(O)钓(O)比(O)赛(O)在(O)厦(B-LOC)门(I-LOC)市(E-LOC)与(O)金(B-LOC)门(E-LOC)之(O)间(O)的(O)海(O)域(O)举(O)行(O)。

    (O)

    这段标注采用的是BIEO标注方式,即Begin, Intermediate, End, Other,针对不同的标注任务标注方式也各不相同。

    通过标注之后的结果,我们可以识别出原来句子中的存在的两个地点实体“厦门市”和“金门”。

    在上面的中文命名实体识别的例子中,我们感兴趣的是文本序列中的实体。在其他任务中会针对任务的不同打上不同的标签。


    2.中文命名实体识别

    中文命名实体识别是NLP领域中的一个基本的问题,属于序列标注问题的范畴。简单来说中文命名实体识别问题就是将一段文本序列中包含的我们感兴趣的实体识别出来,例如人名,地名和机构名等。

    在这里我想说一点,中文命名实体识别相较于英文命名实体识别来说更加困难,这是因为英文中每个词很自然的被空格分隔开来,而中文中词与词之间是没有明显的边界的。

    一般来说进行命名实体识别的方法可以分成两大类:基于规则的方法和基于统计的方法。基于规则的方法是要人工建立实体识别规则,存在着成本高昂的缺点。基于统计的方法一般需要语料库来进行训练,常用的方法有HMM、CRF和神经网络等方法。我这采用的命名实体识别方法是一种将深度学习方法和机器学习方法相结合的模型:Bi-LSTM+CRF。


    3.Bi-LSTM+CRF

    我这次进行中文命名实体识别采用的是Bi-LSTM+CRF模型,关于Bi-LSTM和CRF这两种模型的原理介绍,文章博客一大堆,我就不详细介绍了。自己画了一个模型的结构图,一目了然:

    Bi-LSTM+CRF模型结构图

    如上图所示,模型结构十分简单。输入层是一个将文本序列中的每个汉字利用预先训练好的字向量进行向量化,作为Bi-LSTM层的输入。之后利用一个双向的LSTM(Bi-LSTM)对输入序列进行encode操作,也就是进行特征提取操纵。采用双向LSTM的效果要比单向的LSTM效果好,因为双向LSTM将序列正向和逆向均进行了遍历,相较于单向LSTM可以提取到更多的特征。在经过双向LSTM层之后,我们这里使用一个CRF层进行decode,将Bi-LSTM层提取到的特征作为输入,然后利用CRF从这些特征中计算出序列中每一个元素的标签。

    CRF是机器学习的方法,机器学习中困难的一点就是如何选择和构造特征。Bi-LSTM属于深度学习方法,深度学习的优势在于不需要人为的构造和选择特征,模型会根据训练语料自动的选择构造特征。因此采用Bi-LSTM进行特征的选择构造,然后采用CRF根据得到的特征进行decode(这个不知道用什么中文表达合适),得到最终的序列标注的结果。这样讲深度学习和机器学习相结合的,互相取长补短,最终模型的效果是不错的。


    4.基于TensorFlow的代码实现

    4.1数据预处理

    首先中文NER语料部分采用的是BIOES标注方式,格式如下:

    沙 B-ORG

    特 I-ORG

    队 E-ORG

    教 O

    练 O

    佩 B-PER

    雷 I-PER

    拉 E-PER

    : O

    两 O

    支 O

    队 O

    都 O

    想 O

    胜 O

    , O

    因 O

    此 O

    都 O

    作 O

    出 O

    了 O

    最 O

    大 O

    的 O

    努 O

    力 O

    。 O

    之后我们需要为每个字建立一个id,另外可以设置一个阈值把出现次数小于该阈值的字用<OOV>来统一表示。你可以把这个理解成为一个字典,id越小的字,其出现的频率越高,如下所示:

    氦 3338

    泵 3104

    绳 2077

    栩 4319

    祡 14837

    讳 3022

    㥄 11895

    賨 7565

    4.2模型部分代码

    这部分主要是Bi-LSTM层和CRF层的代码,基于TensorFlow写的,至于数据预处理和评测部分的代码,任务不同代码也会有很大的差别,所以这里就不给出来了。

    Bi-LSTM:

    Bi-LSTM层

    CRF:

    CRF层

    通过短短几十行的代码我们就实现了Bi-LSTM层和CRF层,足可见TensorFlow的强大!

    4.3结果

    我自己使用上述模型跑出来的模型在测试集上的三类实体(人名、地名和机构名)的总的F值可以达到0.85,其中人名的效果最好,其次是地名,最后是机构名。

    5.总结

    目前来看基本的模型效果还有待提高,毕竟F值0.85还是不能拿到工业界用的,但是Bi-LSTM+CRF的模型是目前很流行的序列的标注模型。接下来的任务就是对模型中各个参数的调优,以及对模型做一些改进。

    目前有下面几个改进点:

    1.+CNN,通过CNN的卷积操作去提取更多的字与字之间的特征。

    2.+word embedding,作用于第一条类似,增加序列输入的特征。

    3.考虑将特定的人工提取的规则融入到模型中去。

    相关文章

      网友评论

      • ciel:我想问一下,这种方式需要的数据集大概有多少?每个类别的数据分布不均衡可以吗?
      • bd4f01049e61:代码挂一下github呀!!我来学习学习

      本文标题:序列标注与中文命名实体识别(NER)

      本文链接:https://www.haomeiwen.com/subject/rzxhyttx.html