精华内容
下载资源
问答
  • 基于BERT预训练的中文命名实体识别TensorFlow实现

    万次阅读 多人点赞 2019-01-03 11:58:25
    BERT-BiLSMT-CRF-NER Tensorflow solution of ...使用谷歌的BERT模型在BLSTM-CRF模型上进行预训练用于中文命名实体识别的Tensorflow代码’ 代码已经托管到GitHub 代码传送门 大家可以去clone 下来亲自体验一下! g...

    BERT-BiLSMT-CRF-NER

    Tensorflow solution of NER task Using BiLSTM-CRF model with Google BERT Fine-tuning
    GitHub: https://github.com/macanv/BERT-BiLSTM-CRF-NER
    本文目录机构:

    1. 自己训练模型
    2. 说明
    3. 结果
    4. 使用自己的数据

    2019.1.31更新,支持pip install package


    现在可以使用下面的命令下载软件包了:

    pip install bert-base==0.0.7 -i https://pypi.python.org/simple
    

    或者使用基于源代码的安装:

    git clone https://github.com/macanv/BERT-BiLSTM-CRF-NER
    cd BERT-BiLSTM-CRF-NER/
    python3 setup.py install
    

    如果没啥问题,你将会看到这个:
    安装成功
    笔者在windows10/ Linux/ Mac OSX上都测试过,安装没有问题。

    软件包现在支持的功能

    1. 命名实体识别的训练
    2. 命名实体识别的服务C/S
    3. 继承优秀开源软件:bert_as_service(hanxiao)的BERT所有服务
      4. 文本分类服务 (2019.2.19)

    内容还会继续补充,同时欢迎大神们分享训练的模型或者新的方法或者数据(弱鸡的我并不会用在商业上,毕竟还是一个毕业即失业的渣渣~~)。

    基于命名行训练命名实体识别模型:

    安装完bert-base后,会生成两个基于命名行的工具,其中bert-base-ner-train支持命名实体识别模型的训练,你只需要指定训练数据的目录,BERT相关参数的目录即可。可以使用下面的命令查看帮助

    bert-base-ner-train -help
    

    在这里插入图片描述
    训练的事例命名如下:

    bert-base-ner-train \
        -data_dir {your dataset dir}\
        -output_dir {training output dir}\
        -init_checkpoint {Google BERT model dir}\
        -bert_config_file {bert_config.json under the Google BERT model dir} \
        -vocab_file {vocab.txt under the Google BERT model dir}
    

    参数说明

    1. 其中data_dir是你的数据所在的目录,训练数据,验证数据和测试数据命名格式为:train.txt, dev.txt,test.txt,请按照这个格式命名文件,否则会报错。
      训练数据的格式如下:
      海 O
      钓 O
      比 O
      赛 O
      地 O
      点 O
      在 O
      厦 B-LOC
      门 I-LOC
      与 O
      金 B-LOC
      门 I-LOC
      之 O
      间 O
      的 O
      海 O
      域 O
      。 O
      

    每行得第一个是字,第二个是它的标签,使用空格’ '分隔,请一定要使用空格。句与句之间使用空行划分。程序会自动读取你的数据。

    1. output_dir: 训练模型输出的文件路径,模型的checkpoint以及一些标签映射表都会存储在这里,这个路径在作为服务的时候,可以指定为-ner_model_dir
    2. init_checkpoint: 下载的谷歌BERT模型
    3. bert_config_file : 谷歌BERT模型下面的bert_config.json
    4. vocab_file: 谷歌BERT模型下面的vocab.txt

    训练完成后,你可以在你指定的output_dir中查看训练结果。

    将命名实体识别任务进行服务部署

    作为服务的很多代码都来自优秀的开源项目: bert as service of hanxiao 但是我不知道这样改动是不是违反了某些许可规定,如果有违反,请马上告诉我,我将第一时间进行修改.而且服务端的代码很解耦,修改为另外一种任务的服务也是很简单的,例如文本分类,我将会不就提供这一功能,也欢迎愿意分享的童鞋分享模型或者代码。

    作为服务的命名是:bert-base-serving-start,同样的,你可以先使用-help查看相关帮助

    bert-base-serving-start -help
    

    在这里插入图片描述
    作为命名实体识别任务的服务,这两个目录是你必须指定的:ner_model_dir, bert_model_dir
    然后你就可以使用下面的命令启动了:

    bert-base-serving-start \
        -model_dir C:\workspace\python\BERT_Base\output\ner2 \
        -bert_model_dir F:\chinese_L-12_H-768_A-12
        -mode NER
    

    参数解释

    bert_model_dir: 谷歌BERT模型的解压路径,可以在这里下载 https://github.com/google-research/bert
    model_dir: 训练好的NER模型或者文本分类模型的路径,对于上面的output_dir
    model_pd_dir: 运行模型优化代码后, 经过模型压缩后的存储路径,例如运行上面的命令后改路径下会产生 ner_model.pb 这个二进制文件
    mode:NER 或者是BERT这两个模式,类型是字符串,如果是NER,那么就会启动NER的服务,如果是BERT,那么具体参数将和[bert as service] 项目中得一样。

    我提供了命名实体识别pb模型下载:https://pan.baidu.com/s/1m9VcueQ5gF-TJc00sFD88w, 提取码: guqq
    文本分类模型:https://pan.baidu.com/s/1oFPsOUh1n5AM2HjDIo2XCw, 提取码: bbu8
    文本分类使用的是bert中的demo:run_classxxx.py,在运行的时候使用Pickle序列化了label_list和id2label折两个变量。
    将 ner_mode.pb/classification_model.pb 文件放到 model_pd_dir目录下,将命名识别的label_list.pkl和id2map.pkl不同的模型不同的文件夹,因为他们同名,但是内容不一样,需要区分开来
    命名实体识别模型只支持人名,地名,住址机构名的识别,在我的测试数据上有95.6%的F1值(实体级别的得分)
    文本分类模型数据来自清华大学的文本分类数据:http://thuctc.thunlp.org/ , 在测试数据上准确率为98%~99%的准确率
    肥肠欢迎大家分享你们训练的更好的模型。

    如果使用的下载的模型,你可以使用下面的命令启动,替换你自己的路径即可:

    bert-base-serving-start -model_pd_dir /home/macan/ml/workspace/BERT_Base/output/predict_optimizer  \ 
    	-bert_model_dir /home/macan/ml/data/chinese_L-12_H-768_A-12/ \
    	-ner_model_dir /home/macan/ml/data/bert_ner \
    	-num_worker 8 
    	-mode NER
    

    你将会看到下面的启动信息(启动log有点多,分两张图截):
    在这里插入图片描述
    在这里插入图片描述

    在本地连接服务端进行命名实体识别的测试

    你可以使用下面的代码进行服务的连接,在本地进行NER测试,客户端代码如下:

    import time
    from bert_base.client import BertClient
    # 指定服务器的IP
    with BertClient(ip='XXX,XXX,XXX,XXX', ner_model_dir=ner_model_dir, show_server_config=False, check_version=False, check_length=False, mode='NER') as bc:
        start_t = time.perf_counter()
        str = '1月24日,新华社对外发布了中央对雄安新区的指导意见,洋洋洒洒1.2万多字,17次提到北京,4次提到天津,信息量很大,其实也回答了人们关心的很多问题。'
        rst = bc.encode([str, str])  #测试同时输入两个句子,多个输入同理
        print('rst:', rst) 
        print(time.perf_counter() - start_t)
    

    运行后,会输出下面的信息:
    在这里插入图片描述

    结果说明:

    返回的结果就是序列标注的结果,再往后的工作就不准备再写了,因为后面的操作会涉及到一些策略问题,写的太多,影响代码的灵活,例如有童鞋在terminal_predict.py的代码上提了issue,无法应用到自己的数据中。这样看起来,也比较直观吧~~

    到此,基于命令行的用法已经讲完,不明白的地方请评论或者在GitHub上提交issue,觉得有用,麻烦在GitHub上点个star吧~~

    ###########################################################################################

    以下是基于源代码的训练和启动服务的教程

    ###########################################################################################

    自己训练命名实体识别模型

    使用谷歌的BERT模型在BLSTM-CRF模型上进行预训练用于中文命名实体识别的Tensorflow代码’

    代码已经托管到GitHub 代码传送门 大家可以去clone 下来亲自体验一下!

    git clone https://github.com/macanv/BERT-BiLSTM-CRF-NER
    

    关于BERT的相关理论文章不是本文的主要目的,而且网上简介该部分的文章多如牛毛,大家自行去查看吧,本文着重讲解基于BERT用于中文命名实体的fine-tuning 过程。

    1. 下载Google BERT 预训练模型:

    下载
    wget https://storage.googleapis.com/bert_models/2018_11_03/chinese_L-12_H-768_A-12.zip  
    解压
    unzip chinese_L-12_H-768_A-12.zip
    

    2. 训练模型

    下载了Google的BERT模型和我的GitHub代码后,就可以开始训练啦
    训练之前先在项目目录中新建一个output文件夹,模型的输出,和结构都会保存在这个目录中

    mkdir output
    

    训练的时候需要一些参数,你可以使用命名行的形式进行模型参数指定,例如下面的方法:

      python3 bert_lstm_ner.py   \
                      --task_name="NER"  \ 
                      --do_train=True   \
                      --do_eval=True   \
                      --do_predict=True
                      --data_dir=NERdata   \
                      --vocab_file=checkpoint/vocab.txt  \ 
                      --bert_config_file=checkpoint/bert_config.json \  
                      --init_checkpoint=checkpoint/bert_model.ckpt   \
                      --max_seq_length=128   \
                      --train_batch_size=32   \
                      --learning_rate=2e-5   \
                      --num_train_epochs=3.0   \
                      --output_dir=./output/result_dir/ 
    

    笔者比较菜,选择的是将默认参数写在代码中,开始训练的之前,只需要修改下面的代码即可,代码在bert_lstm_ner.py文件中

    if os.name == 'nt': #windows path config
       bert_path = '{your BERT model path}'
       root_path = '{project path}'
    else: # linux path config
       bert_path = '{your BERT model path}'
       root_path = '{project path}'
    

    os.name=='nt’是表示识别到的系统是windows,其余的是Linux,这里只需要修改一个,如果你是windows训练修改os.name='nt’下面的路径就好了,Linux或者Mac修改else下面的两个路径。
    两个路径说明:
    bert_path: 就是在步骤1中下载解压的BERT模型的路径,复制绝对路径替换即可,例如我项目中所写的路径
    root_path: 这个是项目的路径,也是一个绝对路径,即BERT-BiLSTM-CRF-NER的路径

    修改好两个路径后,就可以开始训练了:

    python3 bert_lstm_ner.py
    

    说明:

    模型代码主要在bert_lstm_ner.py中的create_model函数中
    下面对该函数逻辑进行讲解:

    • 1使用bert模型对我们的输入进行represent
    	#使我们的input_ids数据通过bert 网络结构
        model = modeling.BertModel(
            config=bert_config,
            is_training=is_training,
            input_ids=input_ids,
            input_mask=input_mask,
            token_type_ids=segment_ids,
            use_one_hot_embeddings=use_one_hot_embeddings
        )
        # 获取bert 模型最后一层
        embedding = model.get_sequence_output()
    

    bert 的最后一层是所有transformer结果的最后一维,其是一个三维向量维度是:[batch_size, seq_length, embedding_size],可以类比的理解为我们使用tf.nn.embedding_lookup获取的结果。

    • 2 将embedding 作为LSTM结构的输入:
    	# 加载BLSTM-CRF模型对象
        blstm_crf = BLSTM_CRF(embedded_chars=embedding, hidden_unit=FLAGS.lstm_size, cell_type=FLAGS.cell, num_layers=FLAGS.num_layers,
                              dropout_rate=FLAGS.droupout_rate, initializers=initializers, num_labels=num_labels,
                              seq_length=max_seq_length, labels=labels, lengths=lengths, is_training=is_training)
        # 获取添加我们自己网络结构后的结果,这些结果包括loss, logits, trans, pred_ids
        rst = blstm_crf.add_blstm_crf_layer(crf_only=True)
    

    这里有几点需要说明:

    1. 因为BERT里面已经存在双向编码,所以LSTM并不是必须的,可以将BERT最后一层的结构直接扔给CRF进行解码。所以在代码中通过在add_blstm_crf_layer函数中的crf_only参数进行控制我们训练的时候使用的是那种网络结构用于最后的fine-tuning.通过两种结构的训练结果对比,其实他们的最后结果相差不大,可以说基本是一样的,足见transformer的强大。
    2. crf_only=True 是我们fine-tuning 只使用CRF进行解码,不再使用传统经典的BLSTM-CRF,False表示使用blstm-crf这样的网络结构。
    3. 但是我在试验中发现,只使用CRF的训练时间要比BLSTM-CRF结构的时间要长,这一点我百思不得其解,按理加了BLSTM网络的参数会更多,如果有大佬发现这是个错的观察或者有合理的解释,麻烦不吝赐教。

    实验结果

    • 1 基于label计算出来的指标:

    In dev data set:

    在这里插入图片描述

    In test data set

    在这里插入图片描述

    • 2 在很多地方命名实体的结果使用基于实体级别的评测更为合理,下面是实体级别的评测结果。
      在这里插入图片描述

    评测脚本使用的是conlleval.plconlleval.py

    提供我训练的模型下载:

    my model can download from baidu cloud:
    链接:https://pan.baidu.com/s/1GfDFleCcTv5393ufBYdgqQ 提取码:4cus

    • 3 在线预测
      当你的模型训练完后,可以使用下面的脚本加载模型,进行在线预测
    python3 terminal_predict.py
    

    在这里插入图片描述

    使用自己的数据:

    BERT的大腿简直太粗了,效果很好有木有,看到这样的效果,是不是很想再自己的数据上进行测试一番呢? 其实改的地方很少,只需要修改bert_lstm_ner.py文件中的几行代码就好啦:

      1. get_labels 函数
        def get_labels(self):
            return ["O", "B-PER", "I-PER", "B-ORG", "I-ORG", "B-LOC", "I-LOC", "X", "[CLS]", "[SEP]"]
    

    这里是我数据中所有的标签,其中"X", “[CLS]”, “[SEP]” 是附加的, “[CLS]”, "[SEP]"是句子的开始和结束标志,X是wordpice产生的东西,中文中目前还没有遇到过,可以不用管,大家要改的话,就改前面的标签就好啦。
    例如你想加一个时间类型的实体,就加 “B-TIME”, “I-TIME”
    如果你想应用于分词中,那就没有-XXX了。就是B,I这些,简而言之,就是你的序列标注数据中的第二列的标签的set集合。
    你也可以把get_labels函数写成这样一劳永逸,但是要注意在测试集或者验证机中出现的OOLabel哦:

        def get_labels(self):
            # 通过读取train文件获取标签的方法会出现一定的风险。
            if os.path.exists(os.path.join(FLAGS.output_dir, 'label_list.pkl')):
                with codecs.open(os.path.join(FLAGS.output_dir, 'label_list.pkl'), 'rb') as rf:
                    self.labels = pickle.load(rf)
            else:
                if len(self.labels) > 0:
                    self.labels = self.labels.union(set(["X", "[CLS]", "[SEP]"]))
                    with codecs.open(os.path.join(FLAGS.output_dir, 'label_list.pkl'), 'wb') as rf:
                        pickle.dump(self.labels, rf)
                else:
                    self.labels = ["O", 'B-TIM', 'I-TIM', "B-PER", "I-PER", "B-ORG", "I-ORG", "B-LOC", "I-LOC", "X", "[CLS]", "[SEP]"]
            return self.labels
    

    参考:

    展开全文
  • 具有双向LSTM-CNN的命名实体识别 命名实体识别的双向LSTM_CNN的keras实现。 原始论文可以在找到 该实现与原始论文的不同之处在于: 不考虑词典 使用存储桶可加快培训速度 使用nadam优化程序代替SGD 结果 该模型在约...
  • 一文了解命名实体识别

    千次阅读 2020-09-04 20:25:53
    导读:从1991年开始,命名实体识别逐渐开始走进人们的视野,在各评测会议的推动下,命名实体识别技术得到了极大地发展,从最初的基于规则和字典的方法,到现在热门的注意力机制、图神经网络等方法,命名实体识别已经...

    导读:从1991年开始,命名实体识别逐渐开始走进人们的视野,在各评测会议的推动下,命名实体识别技术得到了极大地发展,从最初的基于规则和字典的方法,到现在热门的注意力机制、图神经网络等方法,命名实体识别已经在各开放数据集上取得了很高的准确率,但从自然语言处理实际应用的角度来看,命名实体识别技术依旧面临着很大的挑战。

     

    什么是命名实体

        1991年Rau等学者首次提出了命名实体识别任务,但命名实体(named entity,NE)作为一个明确的概念和研究对象,是在1995年11月的第六届MUC会议(MUC-6,the Sixth Message Understanding Conferences)上被提出的。当时的MUC-6和后来的MUC-7并未对什么是命名实体进行深入的讨论和定义,只是说明了需要标注的实体是“实体的唯一标识符(unique identifiers of entities)”,规定了NER评测需要识别的三大类(命名实体、时间表达式、数量表达式)、七小类实体,其中命名实体分为:人名、机构名和地名 。MUC 之后的ACE将命名实体中的机构名和地名进行了细分,增加了地理-政治实体和设施两种实体,之后又增加了交通工具和武器。CoNLL-2002、CoNLL-2003 会议上将命名实体定义为包含名称的短语,包括人名、地名、机构名、时间和数量,基本沿用了 MUC 的定义和分类,但实际的任务主要是识别人名、地名、机构名和其他命名实体 。SIGHAN Bakeoff-2006、Bakeoff-2007 评测也大多采用了这种分类。

        除了主流的 NER 评测会议之外,也有学者专门就命名实体的含义和类型进行讨论,Petasis等认为命名实体就是专有名词(proper noun,PN),作为某人或某事的名称。Alfonseca 等从构建本体的角度,提出命名实体就是能用来解决特定问题的我们感兴趣的对象(objects)。Sekine 等认为通用的 7 小类命名实体并不能满足自动问答和信息检索应用的需求,提出了包含 150 种实体类别的扩展命名实体层级(extended named entity hierarchy),并在后来将类别种数增加到200个。

        Borrega等从语言学角度对命名实体进行了详细的定义,规定只有名词和名词短语可以作为命名实体,同时命名实体必须是唯一且没有歧义的。比较特别的是,该研究将命名实体分为强命名实体(strong named entities,SNE)和弱命名实体(weak named entities,WNE),其中 SNE 对应词汇,而WNE对应短语,SNE 和 WNE 又可以细分为若干个小类。虽然该研究将每种类别都进行了详细的定义和阐释,但可能由于过于复杂而不利于计算机自动识别,因此该研究并未得到太多关注。

        Nadeau等指出,“命名实体”中的“命名(named)”表示:只关心那些表示所指对象(referent)的严格指示词(rigid designators)。严格指示词的概念源于Kripke的观点,“对于一个对象 x,如果在所有存在 x 的世界中,指示词 d 都表示 x,而不表示别的对象,那么 x 的指示词 d 是严格的”。

        Marrero等总结了前人对命名实体的定义,并将之归纳为语法类别、严格指示、唯一标识和应用目的四种类别。作者先假设每种类别都能作为定义命名实体的标准,再通过分析和举例等方式否定其作为标准的可行性。最后得出的结论是,应用方面的需求目的,是定义命名实体唯一可行的标准。

        命名实体是命名实体识别的研究主体,而命名实体识别通常认为是从原始文本中识别有意义的实体或实体指代项的过程,即在文本中标识命名实体并划分到相应的实体类型中,通常实体类型包括人名、地名、组织机构名、日期等。举例说明,“当地时间 14 日下午,叙利亚一架军用直升机在阿勒坡西部乡村被一枚恶意飞弹击中。”这句话中包含的实体有:日期实体“14 日下午”、组织机构实体“叙利亚”、地名实体“阿勒坡西部乡村”、装备实体“军用直升机”和“飞弹”,如图1所示。

    图1

     

    命名实体识别的特点、难点、热点

    1

    特点 

        评判一个命名实体是否被正确识别包括两个方面:实体的边界是否正确;实体的类型是否标注正确。

        对比中文和英文本身的语言特点,英语中的命名实体具有比较明显的形态标志,如人名、地名等实体中的每个词的第一个字母要大写等,而且,英文句子中的每个词都是通过空格自然分开,所以英文的实体边界识别相对中文来说比较容易,故而其任务的重点是确定实体的类型。相比于英文,中文里的汉字排列紧密,中文的句子由多个字符组成且单词之间没有空格,这一自身独特的语言特征增大了命名实体识别的难度。

    2

    难点 

        (1)领域命名实体识别局限性。目前命令实体识别只是在有限的领域和有限的实体类型中取得了较好的成绩,如针对新闻语料中的人名、地名、组织机构名的识别。但这些技术无法很好地迁移到其他特定领域中,如军事、医疗、生物、小语种语言等。一方面,由于不同领域的数据往往具有领域独特特征,如医疗领域中实体包括疾病、症状、药品等,而新闻领域的模型并不适合;另一方面,由于领域资源匮乏造成标注数据集缺失,导致模型训练很难直接开展。

        (2)命名实体表述多样性和歧义性。自然语言的多样性和歧义性给自然语言理解带来了很大挑战,在不同的文化、领域、背景下,命名实体的外延有差异,是命名实体识别技术需要解决的根本问题。获取大量文本数据后,由于知识表示粒度不同、置信度相异、缺乏规范性约束等问题,出现命名实体表述多样、指代不明确等现象。

        (3)命名实体的复杂性和开放性。传统的实体类型只关注一小部分类型,例如“人名”“地名”“组织机构名”,而命名实体的复杂性体现在实际数据中实体的类型复杂多样,需要识别细粒度的实体类型,将命名实体分配到更具体的实体类型中。目前业界还没有形成可遵循的严格的命名规范。命名实体的开放性是指命名实体内容和类型并非永久不变,会随着时间变化发生各种演变,甚至最终失效。命名实体的开放性和复杂性给实体分析带来了巨大的挑战,也是亟待解决的核心关键问题。

    3

    热点 

        通 过 调 研 近 三 年 来 ACL,AAAI,EMNLP,COLING,NAACL 等自然语言处理顶级会议中命名实体识别相关的论文,总结并选择了若干具有代表性的研究热点进行展开介绍,分别是匮乏资源命名实体识别、细粒度命名实体识别、嵌套命名实体识别、命名实体链接。

        (1) 匮乏资源命名实体识别

        命名实体识别通常需要大规模的标注数据集,例如标记句子中的每个单词,这样才能很好地训练模型。然而这种方法很难应用到标注数据少的领域,如生物、医学等领域。这是因为资源不足的情况下,模型无法充分学习隐藏的特征表示,传统的监督学习方法的性能会大大降低。

        近来,越来越多的方法被提出用于解决低资源命名实体识别。一些学者采用迁移学习的方法,桥接富足资源和匮乏资源,命名实体识别的迁移学习方法可以分为两种:基于并行语料库的迁移学习和基于共享表示的迁移学习。利用并行语料库在高资源和低资源语言之间映射信息,Chen 和 Feng 等提出同时识别和链接双语命名实体。Ni 和 Mayhew 等创建了一个跨语言的命名实体识别系统,该系统通过将带注释的富足资源数据转换到匮乏资源上,很好地解决了匮乏资源问题。Zhou等采用双对抗网络探索高资源和低资源之间有效的特征融合,将对抗判别器和对抗训练集成在一个统一的框架中进行,实现了端到端的训练。

        还有学者采用正样本-未标注样本学习方法(Positive-Unlabeled,PU),仅使用未标注数据和部分不完善的命名实体字典来实现命名实体识别任务。Yang 等学者采用 AdaSampling 方法,它最初将所有未标记的实例视为负实例,不断地迭代训练模型,最终将所有未标注的实例划分到相应的正负实例集中。Peng 等学者实现了 PU 学习方法在命名实体识别中的应用,仅使用未标记的数据集和不完备的命名实体字典来执行命名实体识别任务,该方法无偏且一致地估算任务损失,并大大减少对字典大小的要求。

        因此,针对资源匮乏领域标注数据的缺乏问题,基于迁移学习、对抗学习、远监督学习等方法被充分利用,解决资源匮乏领域的命名实体识别难题,降低人工标注工作量,也是最近研究的重点。

        (2)细粒度命名实体识别

        为了智能地理解文本并提取大量信息,更精确地确定非结构化文本中提到的实体类型很有意义。通常这些实体类型在知识库的类型层次结构中可以形成类型路径 ,例如,牛顿可以按照如下类型的路径归类:物理学家 /科学家/人。知识库中的类型通常为层次结构的组织形式,即类型层次。

        大多数命名实体识别研究都集中在有限的实体类型上,MUC-7只考虑了 3 类:人名、地名和组织机构名,CoNLL-03增加了其他类,ACE引入了地缘 政治、武器、车辆和设施 4 类 实 体,Ontonotes类型增加到 18 类,BBN有 29 种实体类型。Ling 和 Daniel 定义了一个细粒度的112 个标签集。

         学者们在该领域已经进行了许多研究,通常学习每个实体的分布式表示,并应用多标签分类模型进行类型推断。Neelakantan 和 Chang利用各种信息构造实体的特征表示,如实体的文字描述、属性和类型,之后,学习预测函数来推断实体是否为某类型的实例。Yaghoobzadeh 等重点关注实体的名称和文本中的实体指代项,并为实体和类型对设计了两个评分模型。这些工作淡化了实体之间的内部关系,并单独为每个实体分配类型。Jin 等以实体之间的内部关系为结构信息,构造实体图,进一步提出了一种网络嵌入框架学习实体之间的相关性。最近的研究表明以卷积方式同时包含节点特征和图结构信息,将实体特征丰富到图结构将获益颇多。此外,还有学者考虑到由于大多数知识库都不完整,缺乏实体类型信息,例如在 DBpedia 数据库中 36.53%的实体没有类型信息。因此对于每个未标记的实体,Jin 等充分利用其文本描述、类型和属性来预测缺失的类型,将推断实体的细粒度类型问题转化成基于图的半监督分类问题,提出了使用分层多图卷积网络构造 3 种连通性矩阵,以捕获实体之间不同类型的语义相关性。

        此外,实现知识库中命名实体的细粒度划分也是完善知识库的重要任务之一。细粒度命名实体识别现有方法大多是通过利用实体的固有特征(文本描述、属性和类型)或在文本中实体指代项来进行类型推断,最近有学者研究将知识库中的实体转换为实体图,并应用到基于图神经网络的算法模型中。

        (3)嵌套命名实体识别

        通常要处理的命名实体是非嵌套实体,但是在实际应用中,嵌套实体非常多。大多数命名实体识别会忽略嵌套实体,无法在深层次文本理解中捕获更细粒度的语义信息。如图2 所示,在“3 月 3 日,中国驻爱尔兰使馆提醒旅爱中国公民重视防控,稳妥合理加强防范。”句子中提到的中国驻爱尔兰使馆是一个嵌套实体,中国和爱尔兰均为地名,而中国驻爱尔兰使馆为组织机构名。普通的命名实体识别任务只会识别出其中的地名“中国”和“爱尔兰”,而忽略了整体的组织机构名。

    图2

        学者们提出了多种用于嵌套命名实体识别的方法。Finkel 和 Manning基于 CRF 构建解析器,将每个命名实体作为解析树中的组成部分。Ju 等动态堆叠多个扁平命名实体识别层,并基于内部命名实体识别提取外部实体。如果较短的实体被错误地识别,这类方法可能会遭受错误传播问题的困扰。嵌套命名实体识别的另一系列方法是基于超图的方法。Lu和Roth 首次引入了超图,允许将边缘连接到不同类型的节点以表示嵌套实体。Muis 和Lu使用多图表示法,并引入分隔符的概念用于嵌套实体检测。但是这样需要依靠手工提取的特征来识别嵌套实体,同时遭受结构歧义问题的困扰。Wang 和 Lu提出了一种使用神经网络获取分布式特征表示的神经分段超图模型。Katiyar 和Cardie提出了一种基于超图的计算公式,并以贪婪学习的方式使用 LSTM 神经网络学习嵌套结构。这些方法都存在超图的虚假结构问题,因为它们枚举了代表实体的节点、类型和边界的组合。Xia等提出了 MGNER 架构,不仅可以识别句子中非重叠的命名实体,也可以识别嵌套实体,此外不同于传统的序列标注任务,它将命名实体识别任务分成两部分开展,首先识别实体,然后进行实体分类。

        嵌套实体识别充分利用内部和外部实体的嵌套信息,从底层文本中捕获更细粒度的语义,实现更深层次的文本理解,研究意义重大。

        (4)命名实体链接

        命名实体链接主要目标是进行实体消歧,从实体指代项对应的多个候选实体中选择意思最相近的一个实体。这些候选实体可能选自通用知识库,例如维基百科、百度百科,也可能来自领域知识库,例如军事知识库、装备知识库。图3给出了一个实体链接的示例。短文本“美海军陆战队 F/A-18C战斗机安装了生产型 AN/APG-83 雷达”,其中实体指代项是“生产型 AN/APG-83 雷达”,该实体指代项在知识库中可能存在多种表示和含义,而在此处短文本,其正确的含义为“AN/APG-83 可扩展敏捷波束雷达”。

    图3

        实体链接的关键在于获取语句中更多的语义,通常使用两种方法。一种是通过外部语料库获取更多的辅助信息,另一种是对本地信息的深入了解以获取更多与实体指代项相关的信息。Tan 等提出了一种候选实体选择方法,使用整个包含实体指代项的句子而不是单独的实体指代项来搜索知识库,以获得候选实体集,通过句子检索可以获取更多的语义信息,并获得更准确的结果。Lin 等寻找更多线索来选择候选实体,这些线索被视为种子实体指代项,用作实体指代项与候选实体的桥梁。Dai 等使用社交平台 Yelp 的特征信息,包括用户名、用户评论和网站评论,丰富了实体指代项相关的辅助信息,实现了实体指代项的歧义消除。因此,与实体指代项相关的辅助信息将通过实体指代项和候选实体的链接实现更精确的歧义消除。

        另一些学者使用深度学习研究文本语义。Francis-Landau 等使用卷积神经网络学习文本的表示形式,然后获得候选实体向量和文本向量的余弦相似度得分。Ganea 和 Hofmann专注于文档级别的歧义消除,使用神经网络和注意力机制来深度表示实体指代项和候选实体之间的关系。Mueller和 Durrett将句子左右分开,然后分别使用门控循环单元和注意力机制,获得关于实体指代项和候选实体的分数。Ouyang 等提出一种基于深度序列匹配网络的实体链接算法,综合考虑实体之间的内容相似度和结构相似性,从而帮助机器理解底层数据。目前,在实体链接中使用深度学习方法是一个热门的研究课题。

     

    命名实体识别的研究方法

        命名实体识别从早期基于词典和规则的方法,到传统机器学习的方法,后来采用基于深度学习的方法,一直到当下热门的注意力机制、图神经网络等研究方法,命名实体识别技术路线随着时间在不断发展,技术发展趋势如图4所示。

    图4

    1

    基于规则和字典的方法

        基于规则和字典的方法是最初代的命名实体识别使用的方法,这些方法多采用由语言学家通过人工方式,依据数据集特征构建的特定规则模板或者特殊词典。规则包括关键词、位置词、方位词、中心词、指示词、统计信息、标点符号等。词典是由特征词构成的词典和外部词典共同组成,外部词典指已有的常识词典。制定好规则和词典后,通常使用匹配的方式对文本进行处理以实现命名实体识别。

        Rau等学者首次提出将人工编写的规则与启发式想法相结合的方法,实现了从文本中自动抽取公司名称类型的命名实体。这种基于规则的方法局限性非常明显,不仅需要消耗巨大的人力劳动,且不容易在其他实体类型或数据集扩展,无法适应数据的变化情况。

    2

    基于传统机器学习的方法

        在基于机器学习的方法中,命名实体识别被当作是序列标注问题。与分类问题相比,序列标注问题中当前的预测标签不仅与当前的输入特征相关,还与之前的预测标签相关,即预测标签序列之间是有强相互依赖关系的。采用的传统机器学习方法主要包括:隐马尔可夫模型(Hidden Markov Model,HMM)、最大熵(Maximum Entropy,ME)、最大熵马尔可夫模型( Maximum Entropy Markov Model,MEMM)、支持向量机(Support Vector Machine,SVM)、条件随机场 ( Conditional Random Fields,CRF)  等。

        在这 5 种学习方法中,ME 结构紧凑,具有较好的通用性,其主要缺点是训练时间复杂性非常高,甚至导致训练代价难以承受,另外由于需要明确的归一化计算,导致开销比较大。HMM 对转移概率和表现概率直接建模,统计共现概率。ME 和 SVM 在正确率上要 HMM 高一些,但是 HMM 在训练和识别时的速度要快一些。MEMM 对转移概率和表现概率建立联合概率,统计条件概率,但由于只在局部做归一化容易陷入局部最优。CRF 模型统计全局概率,在归一化时考虑数据在全局的分布,而不是仅仅在局部进行归一化,因此解决了 MEMM 中标记偏置的问题。在传统机器学习中,CRF 被看作是命名实体识别的主流模型,优点在于在对一个位置进行标注的过程中 CRF 可以利用内部及上下文特征信息。

        还有学者通过调整方法的精确率和召回率对传统机器学习进行改进。Culotta 和 McCallum计算从 CRF 模型提取的短语的置信度得分,将这些得分用于对实体识别进行排序和过滤。Carpenter 从HMM 计算短语级别的条件概率,并尝试通过降低这些概率的阈值来增加对命名实体识别的召回率。对给定训练好的 CRF 模型,Minkov 等学者通过微调特征的权重来判断是否是命名实体,更改权重可能会奖励或惩罚 CRF 解码过程中的实体识别。

    3

    基于深度学习的方法

        随着深度学习的不断发展,命名实体识别的研究重点已转向深层神经网络(Deep Neural Network,DNN),该技术几乎不需要特征工程和领域知识 。Collobert 等学者首次提出基于神经网络的命名实体识别方法,该方法中每个单词具有固定大小的窗口,但未能考虑长距离单词之间的有效信息。为了克服这一限制,Chiu 和 Nichols提出了一种双向 LSTM-CNNs 架构,该架构可自动检测单词和字符级别的特征。Ma 和 Hovy进一步将其扩展到 BiLSTM-CNNs-CRF 体系结构,其中添加了 CRF 模块以优化输出标签序列。Liu 等提出了一种称为 LM-LSTM-CRF 的任务感知型神经语言模型,将字符感知型神经语言模型合并到一个多任务框架下,以提取字符级向量化表示。这些端到端模型具备从数据中自动学习的功能,可以很好地识别新实体。

        部分学者将辅助信息和深度学习方法混合使用进行命名实体识别。Liu 等在混合半马尔可夫条件随机场(Hybrid Semi-Markov Conditional Random Fields,HSCRFs) 的体系结构的基础上加入了Gazetteers 地名词典,利用实体在地名词典的匹配结果作为命名实体识别的特征之一。一些研究尝试在标签级别跨数据集共享信息,Greenberg等提出了一个单一的 CRF 模型,使用异构标签集进行命名实体识别,此方法对平衡标签分布的领域数据集有实用性。Augenstein 等使用标签向量化表示在任务之间进一步播信息。Beryozkin 等建议使用给定的标签层次结构共同学习一个在所有标签集中共享其标签层的神经网络,取得了非常优异的性能。

        近年来,在基于神经网络的结构上加入注意力机制、图神经网络、迁移学习、远监督学习等热门研究技术也是目前的主流研究方向。

     

    公开的数据集和评价指标

    1

    公开的数据集 

        常用的命名实体识别数据集有 CoNLL 2003,CoNLL 2002,ACE 2004,ACE 2005 等。数据集的具体介绍如下:

        ① CoNLL 2003 数据集包括1393 篇英语新闻文章和 909 篇德语新闻文章,英语语料库是免费的,德国语料库需要收费。英语语料取自路透社收集的共享任务数据集。数据集中标注了 4 种实体类型:PER,LOC,ORG,MISC。

         ② CoNLL 2002 数据集是从西班牙 EFE 新闻机构收集的西班牙共享任务数据集。数据集标注了 4 种实体类型:PER,LOC,ORG,MISC。

        ③ ACE 2004 多语种训练语料库版权属于语言数据联盟(Linguistic Data Consortium,LDC),ACE2004多语言培训语料库包含用于2004年自动内容提取(ACE)技术评估的全套英语、阿拉伯语和中文培训数据。语言集由为实体和关系标注的各种类型的数据组成。

        ④ ACE2005多语种训练语料库版权属于LDC,包含完整的英语、阿拉伯语和汉语训练数据,数据来源包括:微博、广播新闻、新闻组、广播对话等,可以用来做实体、关系、事件抽取等任务。

        ⑤ OntoNotes5.0数据集版权属于LDC,由1745K英语、900K中文和300 K阿拉伯语文本数据组成,OntoNotes5.0的数据来源也多种多样,来自电话对话、新闻通讯社、广播新闻、广播对话和博客等。实体被标注为PERSON,ORGANIZATION,LOCATION 等18个类型。

        ⑥ MUC 7 数据集是发布的可以用于命名实体识别任务,版权属于LDC,下载需要支付一定费用。数据取自北美新闻文本语料库的新闻标题,其中包含190K训练集、64K测试集。

        ⑦ Twitter 数据集是由 Zhang 等提供,数据收集于 Twitter,训练集包含了 4 000 推特文章,3 257 条推特用户测试。该数据集不仅包含文本信息还包含了图片信息。

        大部分数据集的发布官方都直接给出了训练集、验证集和测试集的划分。同时不同的数据集可能采用不同的标注方法,最常见的标注方法有 IOB,BIOES,Markup,IO,BMEWO 等,下面详细介绍几种常用的标注方法(如图5所示):

        (1)IOB 标注法,是 CoNLL 2003 采用的标注法,I 表示内部,O 表示外部,B 表示开始。如若语料中某个词标注 B/I-XXX,B/I 表示这个词属于命名实体的开始或内部,即该词是命名实体的一部分,XXX表示命名实体的类型。当词标注 O 则表示属于命名实体的外部,即它不是一个命名实体。

        (2)BIOES 标注法,是在 IOB 方法上的扩展,具有更完备的标注规则。其中 B 表示这个词处于一个命名实体的开始,I 表示内部,O 表示外部,E 表示这个词处于一个实体的结束,S 表示这个词是单独形成一个命名实体。BIOES 是目前最通用的命名实体标注方法。

    图5

    2

    评价指标

        对命名实体识别系统的发展来说,对系统的全面评估是必不可少的,许多系统被要求根据它们标注文本的能力来对系统进行排序。目前,通常采用的评估指标主要有查准率(Precision,亦称准确率)、查全率(Recall,亦称召回率)和 F1值,它们的定义如下:

    表1

       查准率P和查全率R分别定义为

        查准率和查全率是一对矛盾的度量,一般来说,查准率高时,查全率往往偏低;而查全率高时,查准率往往偏低。通常只有在一些简单的任务中,才可能使查全率和查准率都很高。为了综合考虑查全率和查准率,引入它们的调和平均F1值,F1值的定义如下:

     

    注:本文旨在学习和分享,如内容上有不到之处,欢迎后台批评指正。

    参考文献:

    [1]陈曙东,欧阳小叶.命名实体识别技术综述[J].无线电通信技术,2020,46(03):251-260.

    [2]刘浏,王东波.命名实体识别研究综述[J].情报学报,2018,37(03):329-340.

    [3]孙镇,王惠临.命名实体识别研究进展综述[J].现代图书情报技术,2010(06):42-47.

    [4]周志华.机器学习[M].北京:清华大学出版社,2016:30-32.

     

    本文来源微信公众号:python遇见NLP

     

    展开全文
  • 命名实体识别

    千次阅读 2017-11-10 16:16:49
    诸如中文分词、词性标注、命名实体等问题均属于序列标签标注问题。经典的模型有HMM,MEMM,CRF模型,这些都是比较传统的方法,三种模型各有优劣,HMM模型假设观测独立,不依赖观测之间的序列特征,MEMM虽然加入了观测...

    诸如中文分词、词性标注、命名实体等问题均属于序列标签标注问题。经典的模型有HMM,MEMM,CRF模型,这些都是比较传统的方法,三种模型各有优劣,HMM模型假设观测独立,不依赖观测之间的序列特征,MEMM虽然加入了观测序列之间的跳转特征,但由于采用了局部归一化引入了标记偏置的问题,最后CRF采用全局归一化从而弥补了HMM和MEMM的缺点,但是计算量却比较大。
    随着深度学习的兴起,将DNN模型应用到标签标注问题上,取得了不俗的结果。比较各模型的结果,一般来说, DNN之前,CRF的结果最好,应用中也最为广泛, DNN这把神器出来后,state-of-the-art的结果均已被DNN的各种模型占领。DNN重在特征的学习和表示,通过DNN学习特征,取代传统CRF中的特征工程,集合DNN和CRF各自的优点,是这一系列方法的主要思路。
    下面介绍几种常见的DNN+CRF模型在命名实体识别问题上的具体应用。


    1 文献调查

    文献年份方法conll2003 ,English, F1值
    [1]Neural Architectures for Named Entity Recognition 2016.4 BiLSTM+CRF+character 90.94
    [2]End-to-end Sequence Labeling via Bi-directional LSTM-CNNs-CRF 2016.5 BiLSTM+CNN+CRF+character 91.21
    [3]LSTM-Based NeuroCRFs for Named Entity Recognition 2016.9 LSTM/BiLSTM+CRF 89.30/89.23
    [4]Attending to Characters in Neural Sequence Labeling Models 2016.11 LSTM/BiLSTM+CRF 84.09
    [5]Fast and Accurate Entity Recognition with Iterated Dilated Convolutions 2017.7 IDCNN+CRF 90.54±0.18
    [6]Named Entity Recognition with Gated Convolutional Neural Networks 2017 GCNN+CRF 91.24

    以上模型结果存在差异一方面是因为模型结构和输入数据不同,另一方面是模型参数的设置不同,比如embedding的维度,lstm的隐藏状态ht 的维度等。以上数据仅作为参考,不作为绝对标准。

    2 命名实体识别模型

    以上各模型可以概括为如下的结构,不同之处主要在于使用的是CNN还是RNN(LSTM,Bi-LSTM),以及输入数据(word-embeddding, character-representation)。

    2.1 模型基本结构

    给定观测序列

    X=(x1,x2,,xn),

    假设矩阵 Pn×k 是有DNN输出的得分矩阵(matrix of scores output).其中k是需要标注的标签个数;Pi,j表示序列中的第i 个word对应的第j 标签的分数.假设上述序列预测标签为
    y=(y1,y2,,yn)
    ,定义该序列的得分为
    s(X,y)=i=0nAyi,yi+1+i=1nPi,yi,

    其中A为转移矩阵,Ai,j 为从标签i 跳转到标签 j 的概率值.y0yn 表示添加到输入序列上的startend对应的标签。因此XR(k+2)×(k+2).
    通过softmax函数对所有可能的标签序列的得分进行变换,得到各个序列对应的概率值:
    p(y|X)=es(X,y)y~YXes(X,y~)

    概率maxy,Xp(y|X) 对应的标签序列为最终的标签预测结果。在训练的时候则采用最大化对数概率:
    log(p(y|X))=s(X,y)logy~YXes(X,y~)

    其中YX 为序列X 对应的所有可能的标签序列。最后,
    y=argmaxy~YXs(X,y~)

    2.2 几种具体的网络

    2.2.1 RNN 网络(Bi-LSTM)

    • 文献[1]的输入数据为word-embedding dt以及 character-embedding ht。对于wt(对应的字符序列为(c1,c2,,cR),采用Bi-LSTM生成character-embedding,即
      hi=LSTM(ct,hi1),hi=LSTM(ci,hi+1),h=[hR,h1]

      将生成的character-embedding 级联到 word-embedding, 作为每个word的featrure,送入到 Bi-LSTM, 最后将Bi-LSTM的输出送入到CRF层。其中character-embedding 采用forward-LSTM和 backword-LSTM的输出的最终状态(final state)拼接而成,即
      xt=concat{dt,h}

      究其原因,LSTM在生成wt representations时,更多的是包含距离 wt 最近的信息(they have a representation biased towards their most recent inputs.)。因此,在用Bi-LSTM提取character-level的representation时,forward LSTM的最终状态能够更好的对wt 的后缀进行表示,backward LSTM的最终状态能够更好的对 wt 的前缀进行表示。
    • 文献[3]的输入数据为word-embedding以及pos-embedding(5-dim), capitalization-embedding(5-dim)(也就是大小写标识)。
    • 文献[4]的输入数据为word-embedding 以及character-embedding,但是word-embedding和character-embedding组合的方式不用于文献[1].首先对h 做了一层非线性变换,即

      h^=tanh(Wth),
      原因是通过非线性变换(相当于增加了一层隐藏层)可以提取更高层的特征(An additional hidden layer allows the model to detect higher-level feature combinations, while constraining it to be small forces it to focus on more generalisable patterns).(不是很理解)其次,将word-embedding dt 和 character-embedding h^进行加权组合
      z=σ(W(3)ztanh(W(1)zdt+W(2)zh^)),x~=zd+(1z)h^

      这种方式的有点是网络可以动态决定word-embedding 和character-embedding 分别取多少。for example,words with regular suffixes can share some character-level features, whereas irregular words can store exceptions into word embeddings.(有规则后缀的单词可以共享一些字符级特性,而不规则的单词可以将异常存储为单词嵌入。–有道翻译 :) ) .
      为了让dh^ 进行对齐,作者又设计了一种目标函数:
      E~=E+t=1Tgt(1cos(h^),dt)gt={01ifwt==OOVotherwise

      最后,贴上一段文献中比较有启发意义的表述:

      While the character component learns general regularities that are shared between all the words, individual word embeddings provide a way for the model to store word-specific information and any exceptions. Therefore, while we want the character-based model to shift towards predicting high-quality word embeddings, it is not desireable to optimise the word embeddings towards the character-level representations. This can be achieved by making sure that the optimisation is performed only in one direction。
      简言之,期望 character-embedding 能够预测出高质量的word-embedding,但反之不亦然。

      2.2.2 CNN 网络

      考虑RNN不能并行计算,并且虽然RNN能够解决长时以来的问题,但是当序列较长时,序列尾部对序列头部的依赖依然会损失很多信息。于是有学者考虑用CNN进行建模。

    • 文献[5]采用CNN对序列建模,并且采用的是迭代扩张卷积Iterated Dilated Convoltuons(IDCNNs).输入数据有word-embdding、character-embdding,shape-embdding, 通过concat 串起来。具体来说:1, 采用滑动窗口,在窗口内做卷积,然而卷积层后面并没有接池化层,而是采用扩张卷积的思路,继续卷积,进行了L次迭代扩张卷积,将这一过程称为一个Block。由于采用了扩张的方式,没增加一层网络,就会使得新增层的神经元的”感受区域”以2的指数倍增加(rl1,窗口宽度为w=2r+1);2,采用Multi-Scale Context Aggregation 机制,将上一个Block的输出作为下一个Block的输入。这样,由于上一个Block已经涵盖了真个输入的所有信息,具备了全局信息,那么这种方式实际上为当前计算的word添加非局部信息。

      By feeding the outputs of each dilated convolution as the input to the next, increasingly non-local information is incorporated into each pixel’s representation<<


    3,改进的损失函数。对于DNN+CRF的结构来说,损失函数一般是将网络的输出送入到CRF层计算整个序列的标签的最大概率。由于文章提出的模型具有多个Block,每个Block后都可以直接接入CRF层并计算序列的标签概率。这样,假如使用了Lb个Block,每个Block的输出都送入到CRF层计算概率,将这Lb个标签作为整体进行优化。这种除了提高精度外,还能降低梯度弥散问题。
    Instead of explicit reasoning over output labels during inference, we train the network such that each block is predictive of output labels. Subsequent blocks learn to correct dependency violations of their predecessors, refining the final sequence prediction.
    采用扩张卷积而不是池化有两个原因:一,凡是池化就有信息损失,不管是有用的还是无用的;二,扩张卷积可以以网络层数的指数级增加每个节点的覆盖范围(也就是感受野);
    文章分别对sentence-level和document-level分别做了实验,待补充
    文章采用dropout with expectationlinear regularization。具体还没有看,听着还是很fancy的.
    The version of dropout typically used in practice has the undesirable property that the randomized predictor used at train time differs from the fixed one used at test time.Ma et al. (2017) present dropout with expectation linear regularization, which explicitly regularizes these two predictors to behave similarly.

    2.2.3 RNN(Bi-LSTM)+CNN网络

    文献[2]的输入数据也是word-embedding 和 character-embedding, 与上述文献不同的地方时,本文采用CNN提取 character-embedding, 其网络结构如下图
    图1 RNN+CNN+CRF网络结构图
    作者认为,CNN是一种提取形态信息的有效方法。比如一个词的前缀或者后缀。

    CNN is an effective approach to extract morphological information (like the prefix or suffix of a word) from characters of words and encode it into neural representations。

    2.3 一些trick

    2.3.1 Embedding

    • 对于输入数据的embedding,要么随机初始化,要么采用预训练好的embedding,比如w2v,glove. 由于embedding可以在更大的数据集上训练(无监督的),因此采用pre-train的embedding进行初始化,使得网络能够收敛到更好的结果。试验结果也表明pre-train的embedding相比随机初始化的embedding 有较大的提升[1]。
    • character-embedding 通常是随机初始化,在训练中进行更新优化;当然也可以用w2v or glove 在大语料上预训练,然后在训练中进行微调;

    2.3.2 Initialization

    • 随机初始化embedding, 从均分分布[3dim,3dim] 中采样,其中dim 为embedding的维度。 实际上就是He-initializer. 这一步的初始化,如果采用CNN提取character-embedding时初始化建议采用He-initializer(激活函数为ReLU),如果才能用LSTM提取embedding是初始化建议采用Xavier-initialize(激活函数为σ,tanh).
    • Weight Matrix and Bias Vectors. Weight Matrix 从均匀分布[6r+c,6r+c] 中采样,其中 rc分布是Weight Matrix的行数和列数。Bias Vectors初始化为零,但LSTM中的遗忘门对应的偏置bf 初始化为1.0。
      Most applications of LSTMs simply initialize the LSTMs with small random weights which works well on many problems. But this initialization effectively sets the forget gate to 0.5. This introduces a vanishing gradient with a factor of 0.5 per timestep, which can cause problems whenever the long term dependencies are particularly severe.This problem is addressed by simply initializing the forget gates bfto a large value such as 1 or 2. By doing so, the forget gate will be initialized to a value that is close to 1, enabling gradient flow.

    2.3.3 OOV

    [1]:words that do not have an embedding in the lookup table are mapped to a UNK embedding. To train the UNK embedding, we replace singletons with the UNK embedding with a probability 0.5.

    2.3.4 dropout

    通常在hidden layers 将dropout 设为0.5, 在 input layers 将 dropout 设为0.8。一般来讲,对于隐藏层的神经元,其 dropout率等于 0.5时效果最好,因为此时通过 dropout 方法,随机生成的网络结构最具多样性。

    2.4 总结

    • 加入CRF层是为了利用标签之间的局部依赖关系;
    • 加入 character-level 是为了缓解 OOV问题; unseen words and rare words 的 embedding由于缺少数据,通常不能够有效的表示该word,引入character-level embedding可以有效缓解这个问题,比如对于“cabinets”,虽然没有数据集中没有”cabinets”,但是有”cabinet”以 “-s”,那么就可以在character-level 推导出 “cabinets”.同时频繁词项又可以获得更高质量的word-embedding(The main benefits of character-level modeling are expected to come from improved handling of rare and unseen words, whereas frequent words are likely able to learn high-quality word-level embeddings directly. We would like to take advantage of this, and train the character component to predict these word embeddings.[4])
    • 在文本分类中有学者采用多通道输入,一个静态的word-embedding,一个动态的embedding,静态的embedding在学习中保持不变(维护了全局特征),动态的embedding在学习中进行微调,也就是task-specific。应用到NER中不知效果如何。

    3 中文命名实体识别

    在模型结构上中文命名实体识别与英文的命名实体识别并没有的区别,主要的一点是,character-embedding的使用,在中文语料下,单个汉字并没有形态上的区别。待我整理完数据后做个试验。

    Ref

    展开全文
  • 中文电子病例命名实体识别项目

    万次阅读 多人点赞 2018-11-28 12:10:18
    Medical Named Entity Recognition implement using bi-directional lstm and crf model with char embedding.CCKS2018中文电子病例命名实体识别项目,主要实现使用了基于字向量的四层双向LSTM与CRF模型的网络....

    MedicalNamedEntityRecognition

    Medical Named Entity Recognition implement using bi-directional lstm and crf model with char embedding.CCKS2018中文电子病例命名实体识别项目,主要实现使用了基于字向量的四层双向LSTM与CRF模型的网络.该项目提供了原始训练数据样本(一般项目,出院情况,病史情况,病史特点,诊疗经过)与转换版本,训练脚本,预训练模型,可用于序列标注研究.把玩和PK使用.
    项目地址:https://github.com/liuhuanyong/MedicalNamedEntityRecognition

    项目介绍

    电子病历结构化是让计算机理解病历、应用病历的基础。基于对病历的结构化,可以计算出症状、疾病、药品、检查检验等多个知识点之间的关系及其概率,构建医疗领域的知识图谱,进一步优化医生的工作.
    CCKS2018的电子病历命名实体识别的评测任务,是对于给定的一组电子病历纯文本文档,识别并抽取出其中与医学临床相关的实体,并将它们归类到预先定义好的类别中。组委会针对这个评测任务,提供了600份标注好的电子病历文本,共需识别含解剖部位、独立症状、症状描述、手术和药物五类实体。
    领域命名实体识别问题自然语言处理中经典的序列标注问题, 本项目是运用深度学习方法进行命名实体识别的一个尝试.

    实验数据

    一, 目标序列标记集合
    O非实体部分,TREATMENT治疗方式, BODY身体部位, SIGN疾病症状, CHECK医学检查, DISEASE疾病实体,
    二, 序列标记方法
    采用BIO三元标记

    self.class_dict ={
                     'O':0,
                     'TREATMENT-I': 1,
                     'TREATMENT-B': 2,
                     'BODY-B': 3,
                     'BODY-I': 4,
                     'SIGNS-I': 5,
                     'SIGNS-B': 6,
                     'CHECK-B': 7,
                     'CHECK-I': 8,
                     'DISEASE-I': 9,
                     'DISEASE-B': 10
                    }
    

    三, 数据转换
    评测方提供了四个目录(一般项目, 出院项目, 病史特点, 诊疗经过),四个目录下有txtoriginal文件和txt标注文件,内容样式如下:

    一般项目-1.txtoriginal.txt

    女性,88岁,农民,双滦区应营子村人,主因右髋部摔伤后疼痛肿胀,活动受限5小时于2016-10-29;11:12入院。
    

    一般项目-1.txt:

    右髋部	21	23	身体部位
    疼痛	27	28	症状和体征
    肿胀	29	30	症状和体征
    

    转换脚本函数:

      def transfer(self):
        f = open(self.train_filepath, 'w+')
        count = 0
        for root,dirs,files in os.walk(self.origin_path):
            for file in files:
                filepath = os.path.join(root, file)
                if 'original' not in filepath:
                    continue
                label_filepath = filepath.replace('.txtoriginal','')
                print(filepath, '\t\t', label_filepath)
                content = open(filepath).read().strip()
                res_dict = {}
                for line in open(label_filepath):
                    res = line.strip().split('	')
                    start = int(res[1])
                    end = int(res[2])
                    label = res[3]
                    label_id = self.label_dict.get(label)
                    for i in range(start, end+1):
                        if i == start:
                            label_cate = label_id + '-B'
                        else:
                            label_cate = label_id + '-I'
                        res_dict[i] = label_cate
    
                for indx, char in enumerate(content):
                    char_label = res_dict.get(indx, 'O')
                    print(char, char_label)
                    f.write(char + '\t' + char_label + '\n')
        f.close()
        return
    

    模型输出样式:

    ,	O
    男	O
    ,	O
    双	O
    塔	O
    山	O
    人	O
    ,	O
    主	O
    因	O
    咳	SIGNS-B
    嗽	SIGNS-I
    、	O
    少	SIGNS-B
    痰	SIGNS-I
    1	O
    个	O
    月	O
    ,	O
    加	O
    重	O
    3	O
    天	O
    ,	O
    抽	SIGNS-B
    搐	SIGNS-I
    

    模型搭建

    本模型使用预训练字向量,作为embedding层输入,然后经过两个双向LSTM层进行编码,编码后加入dense层,最后送入CRF层进行序列标注.

       '''使用预训练向量进行模型训练'''
    def tokenvec_bilstm2_crf_model(self):
        model = Sequential()
        embedding_layer = Embedding(self.VOCAB_SIZE + 1,
                                    self.EMBEDDING_DIM,
                                    weights=[self.embedding_matrix],
                                    input_length=self.TIME_STAMPS,
                                    trainable=False,
                                    mask_zero=True)
        model.add(embedding_layer)
        model.add(Bidirectional(LSTM(128, return_sequences=True)))
        model.add(Dropout(0.5))
        model.add(Bidirectional(LSTM(64, return_sequences=True)))
        model.add(Dropout(0.5))
        model.add(TimeDistributed(Dense(self.NUM_CLASSES)))
        crf_layer = CRF(self.NUM_CLASSES, sparse_target=True)
        model.add(crf_layer)
        model.compile('adam', loss=crf_layer.loss_function, metrics=[crf_layer.accuracy])
        model.summary()
        return model
    

    模型效果

    1, 模型的训练:

    模型 训练集 测试集 训练集准确率 测试集准确率 备注
    医疗实体识别 6268 1571 0.9649 0.8451 5个epcho

    2, 模型的测试:
    python lstm_predict.py, 对训练好的实体识别模型进行测试,测试效果如下:

        enter an sent:他最近头痛,流鼻涕,估计是发烧了
        [('他', 'O'), ('最', 'O'), ('近', 'O'), ('头', 'SIGNS-B'), ('痛', 'SIGNS-I'), (',', 'O'), ('流', 'O'), ('鼻', 'O'), ('涕', 'O'), (',', 'O'), ('估', 'O'), ('计', 'O'), ('是', 'O'), ('发', 'SIGNS-B'), ('烧', 'SIGNS-I'), ('了', 'SIGNS-I')]
        enter an sent:口腔溃疡可能需要多吃维生素
        [('口', 'BODY-B'), ('腔', 'BODY-I'), ('溃', 'O'), ('疡', 'O'), ('可', 'O'), ('能', 'O'), ('需', 'O'), ('要', 'O'), ('多', 'O'), ('吃', 'O'), ('维', 'CHECK-B'), ('生', 'CHECK-B'), ('素', 'TREATMENT-I')]
        enter an sent:他骨折了,可能需要拍片
        [('他', 'O'), ('骨', 'SIGNS-B'), ('折', 'SIGNS-I'), ('了', 'O'), (',', 'O'), ('可', 'O'), ('能', 'O'), ('需', 'O'), ('要', 'O'), ('拍', 'O'), ('片', 'CHECK-I')]
    

    总结

    1,本项目针对中文电子病例命名实体任务,实现了一个基于Bilstm+CRF的命名实体识别模型
    2,本项目使用charembedding作为原始特征,训练集准确率为0.9649,测试集准确达到0.8451
    3,命名实体识别可以加入更多的特征进行训练,后期将逐步实验其他方式.

    any question? 请联系我:
    邮箱:lhy_in_blcu@126.com
    csdn:https://blog.csdn.net/lhy2014
    我的自然语言处理项目: https://liuhuanyong.github.io/

    展开全文
  • BiLSTM+CRF(二)命名实体识别

    千次阅读 2018-12-03 21:15:11
    前言 前一篇博客里面,我们已经提到了如何构建一个双向的LSTM网络,并在原来单层的RNN的基础上,修改少数几行代码即可实现。...这篇博客,我们就来看看如何通过BiLSTM+CRF来进行命名实体识别的任务...
  • 知识图谱之命名实体识别

    千次阅读 2020-01-05 17:49:24
    本片博文我将讲解两个部分,第一部分讲命名实体识别的发展史,这中间会涉及到整个技术的成熟历程,第二部分讲主流的命名实体识别技术的实现细节。 ...
  • 最近比赛多得令人窒息,所以笔者也从中学到了不少的东西。为此,笔者想基于之前更新的命名实体识别的文章,再写一写最近看到的一些NER算法。笔者在这里就不对命名实体识别等基础知识进行赘述了,我...
  • 中文电子病例命名实体识别

    千次阅读 2019-03-31 17:50:30
    中文电子病例命名实体识别 CCKS2017中文电子病例命名实体识别项目,主要实现使用了基于字向量的四层双向LSTM与CRF模型的网络.该项目提供了原始训练数据样本(一般醒目,出院情况,病史情况,病史特点,诊疗经过)与转换...
  • 本文结构: 什么是命名实体识别(NER) ...命名实体识别是信息提取、问答系统、句法分析、机器翻译等应用领域的重要基础工具,作为结构化信息提取的重要步骤。摘自BosonNLP怎么识别?先把解决问题的逻辑说一
  • 命名实体识别

    2020-03-28 21:35:45
      大家好,今天跟大家介绍一下基于pyltp做中文文本中命名实体的识别。基于词典来介绍一下整个流程,首先...  命名实体识别(Named Entity Recognition,简称NER),又称作“专名识别”,是自然语言处理中的一项...
  • pytorch实现BiLSTM+CRF用于NER(命名实体识别) 在写这篇博客之前,我看了网上关于pytorch,BiLstm+CRF的实现,都是一个版本(对pytorch教程的翻译), 翻译得一点质量都没有,还有一些竟然说做得是词性标注,B,I,O是...
  • 【NLP】一文了解命名实体识别

    千次阅读 2020-09-06 11:00:00
    导读:从1991年开始,命名实体识别逐渐开始走进人们的视野,在各评测会议的推动下,命名实体识别技术得到了极大地发展,从最初的基于规则和字典的方法,到现在热门的注意力机制、图神经网络等方法...
  • 目录 1、NER 简介 2. 深度学习方法在NER中的应用 2.2 IDCNN-CRF 3. 实战应用 3.1 语料准备 ...近几年来,基于神经网络的深度学习方法在...在NLP的关键性基础任务—命名实体识别(Named Entity Recognition,NER...
  • 命名实体识别发展历程 早期使用基于规则和字典的方法进行命名实体识别,后来使用机器学习方法(如:HMM、CRF等),后来使用深度学习的方法(如BILSTM-CRF、Lattice-LSTM-CRF、CNN-CRF等),近期流行使用注意力学习机制...
  • 本文是对 《命名实体识别技术综述》的摘录和笔记。 论文链接 文章目录1. 简介2. 研究难点3. 主要方法4. 研究热点5. 数据集和评价指标6. 参考文献 1. 简介 命名实体识别(NER)的目的是识别文本中的命名实体(边界)并...
  • 6.1 命名实体识别介绍 学习目标: 了解什么是命名实体识别 了解命名实体识别的作用 了解命名实体识别常用方法 了解医学文本特征 什么是命名实体识别: 命名实体识别(Named Entity Recognition,NER)就是从一...
  • 序列标注-命名实体识别

    千次阅读 2018-08-17 15:08:58
    三个月之前 NLP 课程结课,我们做的是命名实体识别的实验。在MSRA的简体中文NER语料(我是从这里下载的,非官方出品,可能不是SIGHAN 2006 Bakeoff-3评测所使用的原版语料)上训练NER模型,识别人名、地名和组织机构...
  • 基于CRF的命名实体识别模型 条件随机场 CRF ​ 条件随机场 CRF 是在已知一组输入随机变量条件的情况下,输出另一组随机变量的条件概率分布模型;其前提是假设输出随机变量构成马尔可夫随机场;条件随机场可以应用于...
  • 基于深度学习的命名实体识别与关系抽取 【备注:此博文初次编辑为2019年12月19日,最新编辑为2019年12月19日】 摘要:构建知识图谱包含四个主要的步骤:数据获取、知识抽取、知识融合和知识加工。其中最主要的步骤是...
  •     今天主要和大家分享一篇关于中文命名实体识别的文章,本文分析Lattice-LSTM模型,并针对该方法的弊端提出将字符符号信息合并到字符向量表示中,提高了模型的性能(计算量、效果)。 First Blood TILE: ...
  • 文献阅读:利用深度学习模型在生物医学文本的上下文关系中进行命名实体识别题目1 背景2 材料和方法2.1 GRAM-CNN方法2.1.1 嵌入方法2.1.2 GRAM-CNN2.1.3 CRF2.2 实施细节 题目 GRAM-CNN: a deep learning approach ...
  • 命名实体识别 1. 问题定义 广义的命名实体识别是指识别出待处理文本中三大类(实体类、时间类和数字类)、七小类(人名、机构名、地名、日期、货币和百分比)命名实体。但实际应用中不只是识别上述所说的实体类,还...
  • 传统的序列标记的方法已经不适合用来识别嵌套实体。在这篇文章中,作者使用了partially-observed TreeCRFs(PO-TreeCRFs),将标记的实体跨度看作树中的可见节点,将其他的看作潜在节点,与其他实体部分重叠的就reject...
  • 【论文笔记】命名实体识别论文

    千次阅读 2019-04-10 11:27:12
    其实实体识别这块看了挺久了的,今天就来好好聊一聊它。实体识别(Name Entity Recognition)是属于NLP任务中的序列标注问题:给定一个输入句子,要求为句子中的每一个token做实体标注(如人名、组织/机构、地名、日期...
  • 本文主要通过不同的数据集来进行 NER 模型验证验证,以及指定一些通过训练 NER 任务的... 序列标准任务优化和拓展 作者:走在前方 博客:https://wenjie.blog.csdn.net/ 专注于文本分类、关键词抽取、文本摘要、FQA .
  • 本文较全面的介绍了命名实体识别(NER),包括NER定义、BiLSTM-CRF模型、Pytorch代码实现,未来将继续完善本文,以求涵盖NER众多方面。 文章目录命名实体识别任务(NER)定义BiLSTM-CRF模型模型输入LSTMCRF真实路径...
  • 文本分词、词性标注和命名实体识别都是自然语言处理领域里面很基础的任务,他们的精度决定了下游任务的精度,其实在这之前我并没有真正意义上接触过命名实体识别这项工作,虽然说读研期间断断续续也参与了这样的项目...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 14,295
精华内容 5,718
关键字:

命名实体识别结构优化