【命名实体识别】训练端到端的序列标注模型

导语

PaddlePaddle提供了丰富的运算单元,帮助大家以模块化的方式构建起千变万化的深度学习模型来解决不同的应用问题。这里,我们针对常见的机器学习任务,提供了不同的神经网络模型供大家学习和使用。本周推文目录如下:

3.12:【命名实体识别】

训练端到端的序列标注模型

3.13:【序列到序列学习】

无注意力机制的神经机器翻译

3.14:【序列到序列学习】

使用Scheduled Sampling改善翻译质量

3.15:【序列到序列学习】

带外部记忆机制的神经机器翻译

3.16:【序列到序列学习】

生成古诗词

给定输入序列,序列标注模型为序列中每一个元素贴上一个类别标签,是自然语言处理领域最基础的任务之一。随着深度学习方法的不断发展,利用循环神经网络学习输入序列的特征表示,条件随机场(Conditional Random Field, CRF)在特征基础上完成序列标注任务,逐渐成为解决序列标注问题的标配解决方案。

在序列标注任务中,我们以命名实体识别(Named Entity Recognition,NER)任务为例,介绍如何训练一个端到端的序列标注模型。

【命名实体识别】

训练端到端的序列标注模型

以下是本例的简要目录结构及说明:

.

├── data # 存储运行本例所依赖的数据

│ ├── download.sh

├── images # README 文档中的图片

├── index.html

├── infer.py # 测试脚本

├── network_conf.py # 模型定义

├── reader.py # 数据读取接口

├── README.md # 文档

├── train.py # 训练脚本

└── utils.py # 定义同样的函数

|1.简介

命名实体识别(Named Entity Recognition,NER)又称作“专名识别”,是指识别文本中具有特定意义的实体,主要包括人名、地名、机构名、专有名词等,是自然语言处理研究的一个基础问题。NER任务通常包括实体边界识别、确定实体类别两部分,可以将其作为序列标注问题解决。

序列标注可以分为Sequence Classification、Segment Classification和Temporal Classification三类[1],本例只考虑Segment Classification,即对输入序列中的每个元素在输出序列中给出对应的标签。对于NER任务,由于需要标识边界,一般采用BIO标注方法定义的标签集,如下是一个NER的标注结果示例:

图1. BIO标注方法示例

根据序列标注结果可以直接得到实体边界和实体类别。类似的,分词、词性标注、语块识别、语义角色标注等任务都可通过序列标注来解决。使用神经网络模型解决问题的思路通常是:前层网络学习输入的特征表示,网络的最后一层在特征基础上完成最终的任务;对于序列标注问题,通常:使用基于RNN的网络结构学习特征,将学习到的特征接入CRF完成序列标注。实际上是将传统CRF中的线性模型换成了非线性神经网络。沿用CRF的出发点是:CRF使用句子级别的似然概率,能够更好的解决标记偏置问题[2]。本例也将基于此思路建立模型。虽然,这里以NER任务作为示例,但所给出的模型可以应用到其他各种序列标注任务中。

由于序列标注问题的广泛性,产生了CRF等经典的序列模型,这些模型大多只能使用局部信息或需要人工设计特征。随着深度学习研究的发展,循环神经网络(Recurrent Neural Network,RNN等 序列模型能够处理序列元素之间前后关联问题,能够从原始输入文本中学习特征表示,而更加适合序列标注任务,更多相关知识可参考PaddleBook中语义角色标注一课(https://github.com/PaddlePaddle/book/blob/develop/07.label_semantic_roles/README.cn.md)。

|2. 模型详解

NER任务的输入是"一句话",目标是识别句子中的实体边界及类别,我们参照论文[2]仅对原始句子进行了一些简单的预处理工作:将每个词转换为小写,并将原词是否大写另作为一个特征,共同作为模型的输入。模型如图2所示,工作流程如下:

  1. 构造输入
  2. 输入1是句子序列,采用one-hot方式表示
  3. 输入2是大写标记序列,标记了句子中每一个词是否是大写,采用one-hot方式表示;
  4. one-hot方式的句子序列和大写标记序列通过词表,转换为实向量表示的词向量序列;
  5. 将步骤2中的2个词向量序列作为双向RNN的输入,学习输入序列的特征表示,得到新的特性表示序列;
  6. CRF以步骤3中模型学习到的特征为输入,以标记序列为监督信号,实现序列标注。

图2. NER 模型网络结构图

|3. 数据说明

在本例中,我们以 CoNLL 2003 NER(https://www.clips.uantwerpen.be/conll2003/ner/)任务为例,原始Reuters数据由于版权原因需另外申请免费下载,请大家按照原网站说明获取。

我们仅在data目录下的train和test文件中放置少数样本用以示例输入数据格式。

本例依赖数据还包括:

  • 输入文本的词典
  • 为词典中的词语提供预训练好的词向量
  • 标记标签的词典 标记标签词典已附在data目录中,对应于data/target.txt文件。输入文本的词典以及词典中词语的预训练的词向量来自:Stanford CS224d(http://cs224d.stanford.edu/)课程作业。为运行本例,请首先在data目录下运行download.sh脚本下载输入文本的词典和预训练的词向量。 完成后会将这两个文件一并放入data目录下,输入文本的词典和预训练的词向量分别对应:data/vocab.txt和data/wordVectors.txt这两个文件。

CoNLL 2003原始数据格式如下:

U.N. NNP I-NP I-ORG

official NN I-NP O

Ekeus NNP I-NP I-PER

heads VBZ I-VP O

for IN I-PP O

Baghdad NNP I-NP I-LOC

. . O O

  • 第一列为原始句子序列
  • 第二、三列分别为词性标签和句法分析中的语块标签,本例不使用
  • 第四列为采用了 I-TYPE 方式表示的NER标签。I-TYPE 和 BIO 方式的主要区别在于语块开始标记的使用上,I-TYPE只有在出现相邻的同类别实体时对后者使用B标记,其他均使用I标记),句子之间以空行分隔。

我们在reader.py脚本中完成对原始数据的处理以及读取,主要包括下面几个步骤:

  • 从原始数据文件中抽取出句子和标签,构造句子序列和标签序列;
  • 将 I-TYPE 表示的标签转换为 BIO 方式表示的标签;
  • 将句子序列中的单词转换为小写,并构造大写标记序列;
  • 依据词典获取词对应的整数索引。

预处理完成后,一条训练样本包含3个部分作为神经网络的输入信息用于训练:(1)句子序列;(2)首字母大写标记序列;(3)标注序列,下表是一条训练样本的示例:

|4.运行

A.编写数据读取接口

自定义数据读取接口只需编写一个 Python 生成器实现从原始输入文本中解析一条训练样本的逻辑。reader.py 中的data_reader函数实现了读取原始数据返回类型为: paddle.data_type.integer_value_sequence的 3 个输入(分别对应:词语在字典的序号、是否为大写、标注结果在字典中的序号)给network_conf.ner_net中定义的 3 个 data_layer 的功能。

B.训练

运行 sh data/download.sh

修改 train.py 的 main 函数,指定数据路径

main(

train_data_file="data/train",

test_data_file="data/test",

vocab_file="data/vocab.txt",

target_file="data/target.txt",

emb_file="data/wordVectors.txt",

model_save_dir="models/")

运行命令 python train.py,需要注意:直接运行使用的是示例数据,请替换真实的标记数据。

commandline: --use_gpu=False --trainer_count=1

Initing parameters..

Init parameters done.

Pass 0, Batch 0, Cost 41.430110, {'ner_chunk.precision': 0.01587301678955555, 'ner_chunk.F1-score': 0.028368793427944183, 'ner_chunk.recall': 0.13333334028720856, 'error': 0.939393937587738}

Test with Pass 0, Batch 0, {'ner_chunk.precision': 0.0, 'ner_chunk.F1-score': 0.0, 'ner_chunk.recall': 0.0, 'error': 0.16260161995887756}

C.预测

修改 infer.py 的 main 函数,指定:需要测试的模型的路径、测试数据、字典文件,预测标记文件的路径,默认参数如下:

infer(

model_path="models/params_pass_0.tar.gz",

batch_size=2,

test_data_file="data/test",

vocab_file="data/vocab.txt",

target_file="data/target.txt")

在终端运行 python infer.py,开始测试,会看到如下预测结果(以下为训练500个pass所得模型的部分预测结果):

cricket O

- O

leicestershire B-ORG

take O

over O

at O

top O

after O

innings O

victory O

. O

london B-LOC

1996-08-30 O

west B-MISC

indian I-MISC

all-rounder O

phil B-PER

simmons I-PER

took O

four O

输出分为两列,以“t” 分隔,第一列是输入的词语,第二列是标记结果。多条输入序列之间以空行分隔。

【参考文献】

  1. Graves A. Supervised Sequence Labelling with Recurrent Neural Networks[J]. Studies in Computational Intelligence, 2013, 385.
  2. Collobert R, Weston J, Bottou L, et al. Natural Language Processing (Almost) from Scratch[J]. Journal of Machine Learning Research, 2011, 12(1):2493-2537.

原文发布于微信公众号 - PaddlePaddle(PaddleOpenSource)

原文发表时间:2018-03-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大数据挖掘DT机器学习

【Keras】完整实现‘交通标志’分类、‘票据’分类两个项目,让你掌握深度学习图像分类

我们一般用深度学习做图片分类的入门教材都是MNIST或者CIFAR-10,因为数据都是别人准备好的,有的甚至是一个函数就把所有数据都load进来了,所以跑起来...

5205
来自专栏大数据挖掘DT机器学习

用python实现支持向量机对婚介数据的用户配对预测

网上有人用libsvm2.89在Python2.6成功。(一定要libsvm2.89搭配python2.6,其他版本都不能成功,我就是浪费了大量时间在这里!) ...

3725
来自专栏机器之心

前端慌不慌?用深度学习自动生成HTML代码

53611
来自专栏PaddlePaddle

【排序学习】基于Pairwise和Listwise的排序学习

导语 PaddlePaddle提供了丰富的运算单元,帮助大家以模块化的方式构建起千变万化的深度学习模型来解决不同的应用问题。这里,我们针对常见的机器学习任务,提...

2.2K8
来自专栏Python中文社区

用Python从零开始构造决策树

專 欄 ❈ 作者:weapon,不会写程序的浴室麦霸不是好的神经科医生 ❈ 起步 本章介绍如何不利用第三方库,仅用python自带的标准库来构造一个决策树。 ...

2127
来自专栏决胜机器学习

从机器学习学python(四) ——numpy矩阵广播及一些技巧

从机器学习学python(四)——numpy矩阵广播及一些技巧 (原创内容,转载请注明来源,谢谢) 在学ng的深度学习微专业时,其中有几节课讲到numpy的一...

4224
来自专栏机器之心

教程 | 从头开始在Python中开发深度学习字幕生成模型

3974
来自专栏Python数据科学

一款非常棒的特征选择工具:feature-selector

本篇主要介绍一个基础的特征选择工具feature-selector,feature-selector是由Feature Labs的一名数据科学家williamk...

1914
来自专栏超智能体

YJango:TensorFlow高层API Custom Estimator建立CNN+RNN的演示

该文是YJango:TensorFlow中层API Datasets+TFRecord的数据导入的后续。

1.2K7
来自专栏编程软文

前端慌不慌?用深度学习自动生成HTML代码

5086

扫码关注云+社区