知识图谱3-LSTM+CRF for NER

Ref:LSTM+CRF for NER | 蘑菇先生学习记  摘抄到自己的博客上方便修改,添加备注。 比较深澳,后面的就看不懂了,之后再整理吧。

LSTM+CRF NER

本文将借鉴论文《End-to-end Sequence Labeling via Bi-directional LSTM-CNNs-CRF》中的思路和方法实现命名实体识别。

目标

NER英文命名实体识别的目标是识别句子中每个词语的实体类型,包括5大类:PER(人名)、LOC(地名)、ORG(组织名)、MISC(其它类型实体)、O(非实体)。由于实体可能是由多个词语构成的,因此使用标注B、I来区分该词语是该实体的起始词(Begin)还是中间词(Inside)。示例如下:

John  lives in New   York  and works for the European Union
B-PER O     O  B-LOC I-LOC O   O     O   O   B-ORG    I-ORG

命名实体识别最简单的实现方法就是查表法。也就是说,将所有的实体都标注好写进词典里,要识别句子中的实体时,直接查询词典,取出对应的词语的实体类型就可以了。但是问题在于,一方面实体数量太过于庞大,另一方面,会不断有新的实体出现,那么使用查表法就解决不了了。

通常,人类识别实体的方法是根据实体所处的上下文信息来判断的,因此为了模仿人类这种能力,此处主要使用神经网络的方法来进行实体识别。具体的方法是LSTM+CRF。LSTM用于建模、提取和利用上下文词语级别的信息,单个词内的字符级别的特征,CRF将利用提取到的特征以及标签信息,建模提取到的特征之间、标签之间、以及特征与标签之间的联系。二者结合起来实现命名实体任务。另外单个词内的字符级别的特征也可以采用论文中描述的CNN来提取,此处使用LSTM提取。

词语特征表示

神经网络的输入是句子,输出为句子中每个词的实体类型。为了使用神经网络建模,输入句子需要提取特征。特征包含两个方面,一方面是句子内词语级别的特征,另一方面是词语内字符级别的特征。前者是因为实体的识别依赖于上下文词语的特征;后者是因为实体的识别还依赖于自身的特征(如大小写等)。这两种特征都不需要手动设计,都使用神经网络来学习向量化表示。不过,对于词语的向量化表示,论文中会利用到预训练好的Glove词向量,不进行额外学习(最多Finetune一下)。对于字符的向量化表示,论文中使用CNN来提取特征,此处我们采用LSTM来提取特征。

下图是使用Bi-LSTM提取字符级别的特征。对于某个单词wi(例如CAT),w=[c1,…,cp],每个字符ci都有一个向量化表示。使用Bi-LSTM建模单词字符词向量序列,并将Bi-LSTM最后输出的隐藏层h1、h2向量(前向、后向各一个)连接起来,作为该词wi字符级别的特征,该特征能够捕获wi形态学特点。

char_representation

然后,再将提取到的字符级别的特征和Glove预训练好的词语级别的特征连接起来,作为该词最终的特征。

代码上,

下面针对的都是1个batch进行优化时,如何获取batch中的不同序列中的特征。

词向量:

将句子看成序列,序列由词语构成,词语看成序列不同时刻的观测输入

  • 为不同时刻的观测输入设置id,这里也就是为词语设置id。目的是查找观测的向量化表示。
# shape = (batch size, max length of sentence in batch)
word_ids = tf.placehold
  • 这里针对的是1个batch,batch由多个序列(句子)构成。要设置不同序列不同时刻的观测的id,也就是不同句子不同单词的id。因此word_ids的shape是二维的,Batch Size×Sentence LengthBatch Size×Sentence Length,Batch Size是这个Batch中序列的数量,Sentence Length是序列的最大长度,每个元素代表某个序列某个词语的id。

  • 不同序列设置有效长度,这里也就是句子的单词数目。目的是记录batch中不同序列的有效长度。

    1
    2
    
    # shape = (batch size)
    sequence_lengths = tf.placeholder(tf.int32, shape=[None])
    

    针对1个batch,记录batch中不同序列的有效长度。sequence_lengths一维数组记录了batch中不同句子的有效长度,即,每个元素记录了对应序列句子的单词真实数目。之所以称作有效长度,是因为word_ids中第二维是最大序列长度,而不同句子长度不一样,因此第二维不是全部填满的,末尾大部分为0,因此使用sequence_length记录一下每条序列的有效长度。

  • 根据上述的id查询观测词语的向量化表示

L = tf.Variable(embeddings, dtype=tf.float32, trainable=False)
# shape = (batch size, sentence, word_vector_size)
pretrained_embeddings = tf.nn.embedding_lookup(L, word_ids)

LL就是词向量矩阵,shape为Dictionary Size×Word Vector SizeDictionary Size×Word Vector Size, 即词语总数量乘以词的维数。注意trainable=False,我们不需要训练词向量,使用预训练好的Glove词向量,并借助Tensorflow自带的embedding_lookup来查找词向量。

这里直接查询到每个batch每个句子中不同单词的词向量。pretrained_embeddings的最后一维就是词向量的维数,因此pretrained_embeddings是3维的(Batch×Sequence×ObservationBatch×Sequence×Observation)。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值