基于keras的BiLstm与CRF实现命名实体标注

众所周知,通过Bilstm已经可以实现分词或命名实体标注了,同样地单独的CRF也可以很好的实现。既然LSTM都已经可以预测了,为啥要搞一个LSTM+CRF的hybrid model? 因为单独LSTM预测出来的标注可能会出现(I-Organization->I-Person,B-Organization ->I-Person)这样的问题序列。

但这种错误在CRF中是不存在的,因为CRF的特征函数的存在就是为了对输入序列观察、学习各种特征,这些特征就是在限定窗口size下的各种词之间的关系。

将CRF接在LSTM网络的输出结果后,让LSTM负责在CRF的特征限定下,依照新的loss function,学习出新的模型。

基于字的模型标注:

假定我们使用Bakeoff-3评测中所采用的的BIO标注集,即B-PER、I-PER代表人名首字、人名非首字,B-ORG、I-ORG代表组织机构名首字、组织机构名非首字,O代表该字不属于命名实体的一部分

  • B-Person
  • I- Person
  • B-Organization
  • I-Organization
  • O

加入CRF layer对LSTM网络输出结果的影响

为直观的看到加入后的区别我们可以借用网络中的图来表示:其中\(x\)表示输入的句子,包含5个字分别用\(w_1\),\(w_2\),\(w_3\),\(w_4\),\(w_5\)表示

没有CRF layer的网络示意图

含有CRF layer的网络输出示意图

上图可以看到在没有CRF layer的情况下出现了 B-Person->I-Person 的序列,而在有CRF layer层的网络中,我们将 LSTM 的输出再次送入CRF layer中计算新的结果。而在CRF layer中会加入一些限制,以排除可能会出现上文所提及的不合法的情况

CRF loss function

CRF loss function 如下:
Loss Function = \(\frac{P_{RealPath}}{P_1 + P_2 + … + P_N}\)

主要包括两个部分Real path score 和 total path scroe

1、Real path score

\(P_{RealPath}\) =\(e^{S_i}\)

因此重点在于求出:

\(S_i\) = EmissionScore + TransitionScore

EmissionScore=\(x_{0,START}+x_{1,B-Person}+x_{2,I-Person}+x_{3,O}+x_{4,B-Organization}+x_{5,O}+x_{6,END}\)

因此根据转移概率和发射概率很容易求出\(P_{RealPath}\)

2、total score

total scroe的计算相对比较复杂,可参看https://createmomo.github.io/2017/11/11/CRF-Layer-on-the-Top-of-BiLSTM-5/

实现代码(keras版本)

1、搭建网络模型

使用2.1.4版本的keras,在keras版本里面已经包含bilstm模型,但crf的loss function还没有,不过可以从keras contribute中获得,具体可参看:https://github.com/keras-team/keras-contrib

构建网络模型代码如下:

    model = Sequential()
    model.add(Embedding(len(vocab), EMBED_DIM, mask_zero=True))  # Random embedding
    model.add(Bidirectional(LSTM(BiRNN_UNITS // 2, return_sequences=True)))
    crf = CRF(len(chunk_tags), sparse_target=True)
    model.add(crf)
    model.summary()
    model.compile('adam', loss=crf.loss_function, metrics=[crf.accuracy])

2、清洗数据

清晰数据是最麻烦的一步,首先我们采用网上开源的语料库作为训练和测试数据。语料库中已经做好了标记,其格式如下:

月 O
油 O
印 O
的 O
《 O
北 B-LOC
京 I-LOC
文 O
物 O
保 O
存 O
保 O
管 O

语料库中对每一个字分别进行标记,比较包括如下几种:

'O', 'B-PER', 'I-PER', 'B-LOC', 'I-LOC', "B-ORG", "I-ORG"

分别表示,其他,人名第一个,人名非第一个,位置第一个,位置非第一个,组织第一个,非组织第一个

    train = _parse_data(open('data/train_data.data', 'rb'))
    test = _parse_data(open('data/test_data.data', 'rb'))

    word_counts = Counter(row[0].lower() for sample in train for row in sample)
    vocab = [w for w, f in iter(word_counts.items()) if f >= 2]
    chunk_tags = ['O', 'B-PER', 'I-PER', 'B-LOC', 'I-LOC', "B-ORG", "I-ORG"]

    # save initial config data
    with open('model/config.pkl', 'wb') as outp:
        pickle.dump((vocab, chunk_tags), outp)

    train = _process_data(train, vocab, chunk_tags)
    test = _process_data(test, vocab, chunk_tags)
    return train, test, (vocab, chunk_tags)

3、训练数据

在处理好数据后可以训练数据,本文中将batch-size=16获得较为高的accuracy(99%左右),进行了10个epoch的训练。

import bilsm_crf_model

EPOCHS = 10
model, (train_x, train_y), (test_x, test_y) = bilsm_crf_model.create_model()
# train model
model.fit(train_x, train_y,batch_size=16,epochs=EPOCHS, validation_data=[test_x, test_y])
model.save('model/crf.h5')

4、验证数据

import bilsm_crf_model
import process_data
import numpy as np

model, (vocab, chunk_tags) = bilsm_crf_model.create_model(train=False)
predict_text = '中华人民共和国国务院总理周恩来在外交部长陈毅的陪同下,连续访问了埃塞俄比亚等非洲10国以及阿尔巴尼亚'
str, length = process_data.process_data(predict_text, vocab)
model.load_weights('model/crf.h5')
raw = model.predict(str)[0][-length:]
result = [np.argmax(row) for row in raw]
result_tags = [chunk_tags[i] for i in result]

per, loc, org = '', '', ''

for s, t in zip(predict_text, result_tags):
    if t in ('B-PER', 'I-PER'):
        per += ' ' + s if (t == 'B-PER') else s
    if t in ('B-ORG', 'I-ORG'):
        org += ' ' + s if (t == 'B-ORG') else s
    if t in ('B-LOC', 'I-LOC'):
        loc += ' ' + s if (t == 'B-LOC') else s

print(['person:' + per, 'location:' + loc, 'organzation:' + org])

输出结果如下:

['person: 周恩来 陈毅, 王东', 'location: 埃塞俄比亚 非洲 阿尔巴尼亚', 'organzation: 中华人民共和国国务院 外交部']

源码地址:https://github.com/stephen-v/zh-NER-keras

原文地址:https://www.cnblogs.com/vipyoumay/p/ner-chinese-keras.html

时间: 2024-10-08 18:05:46

基于keras的BiLstm与CRF实现命名实体标注的相关文章

NLP入门(八)使用CRF++实现命名实体识别(NER)

CRF与NER简介 ??CRF,英文全称为conditional random field, 中文名为条件随机场,是给定一组输入随机变量条件下另一组输出随机变量的条件概率分布模型,其特点是假设输出随机变量构成马尔可夫(Markov)随机场. ??较为简单的条件随机场是定义在线性链上的条件随机场,称为线性链条件随机场(linear chain conditional random field). 线性链条件随机场可以用于序列标注等问题,而本文需要解决的命名实体识别(NER)任务正好可通过序列标注方

用CRF做命名实体识别

摘要 本文主要讲述了关于人民日报标注语料的预处理,利用CRF++工具包对模型进行训练以及测试 目录 明确我们的标注任务 语料和工具 数据预处理 1.数据说明 2.数据预处理 模型训练及测试 1.流程 2.标注集 3.特征模板 4.CRF++包的使用说明 总结与展望 正文 1.明确我们的标注任务 这篇文章主要是介绍用CRF模型去提取人民日报语料的时间.人物.地点及组织机构名,也就是提取TIME.PERSON.LOCATION.ORGANIZATION四种实体.训练我们直接使用CRF++工具包. 2

基于深度学习做命名实体识别

基于CRF做命名实体识别系列 用CRF做命名实体识别(一) 用CRF做命名实体识别(二) 用CRF做命名实体识别(三) 摘要 1. 之前用CRF做了命名实体识别,效果还可以,最高达到0.9293,当然这是自己用sklearn写的计算F1值, 后来用**conlleval.pl**对CRF测试结果进行评价,得到的F1值是**0.9362**. 2. 接下来基于BILSTM-CRF做命名实体识别,代码不是自己写的,用的github上的一个大佬写的,换了自己的数据集,得到最终的结果是0.92. 3.

基于维基百科的中文命名实体关联度计算

基于维基百科的中文命名实体关联度计算(出自北方工业大学报) 基本的假设是wiki页面中每个链接都指向一个命名实体.通过链接来计算关联度. 每个维基百科页面都有唯一的标识符,命名实体关联度是指命名实体的相关性.关联度是一个数值,取值范围为(0,1).一个命名实体与本身的关联度为1,如果两个命名实体的相关性为0,则它们的关联度为0. 论文中两个机制:重定向机制.消岐机制. 命名实体关联度计算公式 其中,EN1.EN2表示2个命名实体: a表示命名实体EN1页面所含链接数: b表示命名实体EN2页面所

基于 Keras 用 LSTM 网络做时间序列预测

基于 Keras 用 LSTM 网络做时间序列预测 本文主要参考了 Jason Brownlee 的博文 Time Series Prediction with LSTM Recurrent Neural Networks in Python with Keras 原文使用 python 实现模型,这里是用 R 时间序列预测是一类比较困难的预测问题. 与常见的回归预测模型不同,输入变量之间的"序列依赖性"为时间序列问题增加了复杂度. 一种能够专门用来处理序列依赖性的神经网络被称为 递归

[AI开发]centOS7.5上基于keras/tensorflow深度学习环境搭建

这篇文章详细介绍在centOS7.5上搭建基于keras/tensorflow的深度学习环境,该环境可用于实际生产.本人现在非常熟练linux(Ubuntu/centOS/openSUSE).windows上该环境的搭建 :) 前面三篇博客代码实现均基于该环境(开发或者测试过): [AI开发]Python+Tensorflow打造自己的计算机视觉API服务 [AI开发]基于深度学习的视频多目标跟踪实现 [AI开发]视频多目标跟踪高级版 运行环境 1) centOS 7.5 ,不要安装GUI桌面:

学习参考+《深度学习基于Keras的Python实践》PDF+ 源代码+魏贞原

深度学习学习框架有tensorflow.pytorch.keras.学习keras时,推荐<深度学习:基于Keras的Python实践>,适合深度学习入门和实践. 尤其是第三部分,利用卷积神经网络解决情感分析问题比较好. <深度学习:基于Keras的Python实践>系统讲解了深度学习的基本知识,以及使用深度学习解决实际问题,详细介绍了如何构建及优化模型,并针对不同的问题给出不同的解决方案,通过不同的例子展示了在具体项目中的应用和实践经验. 推荐参考:<深度学习:基于Kera

用深度学习做命名实体识别(七)-CRF介绍

还记得之前介绍过的命名实体识别系列文章吗,可以从句子中提取出人名.地址.公司等实体字段,当时只是简单提到了BERT+CRF模型,BERT已经在上一篇文章中介绍过了,本文将对CRF做一个基本的介绍.本文尽可能不涉及复杂晦涩的数学公式,目的只是快速了解CRF的基本概念以及其在命名实体识别等自然语言处理领域的作用. 什么是CRF? CRF,全称 Conditional Random Fields,中文名:条件随机场.是给定一组输入序列的条件下,另一组输出序列的条件概率分布模型. 什么时候可以用CRF?

神经网络结构在命名实体识别(NER)中的应用

近年来,基于神经网络的深度学习方法在自然语言处理领域已经取得了不少进展.作为NLP领域的基础任务-命名实体识别(Named Entity Recognition,NER)也不例外,神经网络结构在NER中也取得了不错的效果.最近,我也阅读学习了一系列使用神经网络结构进行NER的相关论文,在此进行一下总结,和大家一起分享学习. 1 引言 命名实体识别(Named Entity Recognition,NER)就是从一段自然语言文本中找出相关实体,并标注出其位置以及类型,如下图.它是NLP领域中一些复