手把手教你实现命名实体识别

奎屹 14 2024-12-11 03:05:27

比赛链接: 互联网金融新实体发现.
本博客主要参考他的文章和代码: 阿力阿哩哩.感兴趣的话可以关注他的知乎、公众号以及B站账号。

(1)硬件环境:
操作系统:windows 10或者 linux(Ubuntu 16~18) (本人使用的windows 10)
硬件配置:主要是显卡要求:1660Ti 6G(最起码要保证有一个显卡)
(2)软件环境:
这里最好自己创建一个虚拟环境,然后在里面配置一下各种库的版本。

  • 创建虚拟环境:conda create –n ccf_ner python==3.6
  • 进入虚拟环境:conda activate ccf_ner
  • tensorflow-gpu==1.10
  • cudatoolkit==9.0
  • cudnn=7.0
  • tqdm = 4.60.0
  • pandas==0.25.3
  • numpy==1.14.5
    在这里插入图片描述

(1)实验流程
在这里插入图片描述

(2)代码结构

  • preprocess/preprocess.py: 对原始数据进行预处理,包含数据清洗、数据切割、数据格式转换

  • model.py:单模构建代码,包含BERT+BILISTM-CRF、BERT+IDCNN-CRF

  • utils.py:DataIterator数据迭代器, 用于生成batch数据喂入模型

  • train_fine_tune.py:模型的训练(即模型参数微调)

  • predict.py:模型预测(微调好的模型用于测试集的预测)

  • ensemble/ensemble.py:对predict.py模型生成的文件进行复原,生成单模的文字预测结果

  • bert/tokenization.py:BERT源码分词工具

  • tf_utils文件夹:BERT源码的修改以及CRF等的开源代码

  • config.py:超参数设置和预训练模型等的路径设置

  • optimization.py:参数优化器

  • post_process文件夹:

  • [1] get_ensemble_final_result.py: 对ensemble.py生成的单模文字结果进行拼接,因为在预处理的时候将测试集切成了多份。

  • [2] post_ensemble_final_result.py: 对get_ensemble_final_result.py 生成的文件进行后处理,得到最终的单模文字结果

(1)首先查看一下原始数据:
在这里插入图片描述
样本数据包含文本标识号(ID)、题目(title)、正文(text)、识别出的未知实体(unknownEntity)四列,这个阶段需要做的事情就是要将数据样本处理成BIEO或BIO等格式。预处理之后的数据格式如下:
在这里插入图片描述
(2)代码解析

  • 导入相关库
 
  • 找出所有的非数字、非中文、分英文的符号
 
  • 定义stop_word
 

-将数据中标题和文本合并,数据中的实体主要在title和text上

 
  • 使用停止词滤除数据中的噪声并对缺失值进行处理
 
  • 找出错误标签
 
  • 修复错误标签
 
  • 数据集的划分
 
  • 对长文本按照标点优先级进行切割
 
 
 
 
  • 测试数据集切分是否正确
 
  • 保存切分索引
 
  • 将切分的数据转成BIO数据格式
 

在机器学习中数据的质量直接决定了任务的天花板,而模型和算法只是无限的去接近这个天花板,本文对前期的数据处理进行了详细的介绍。最终在pycharm中运行结果如下图所示:
在这里插入图片描述
在本地data/process_data中生成了我们需要的文件:
在这里插入图片描述

在将数据处理成标准的BIO标注格式后,需要使用数据迭代器将数据喂给模型中,虽然所一般情况下可以将很多数据直接读入内存中,但是对于一些较大的神经网络或晕训练模型时,数据量往往较大,我们需要分批次将数据送入后去的神经网络中。

  • 加载数据
 
  • 读取语料和标记
 
  • 得到实例及标签
 
  • 数据迭代器
 
  • BERT源码分词器tokenizer.vovab:
    在这里插入图片描述
  • 迭代器结果:

    数据迭代次梅批次的结果:
 
 

NER一直是NLP领域中的研究热点,从早期基于词典和规则的方法,到传统机器学习的方法,到近年来基于深度学习的方法,NER研究进展的大概趋势大致如下图所示:
在这里插入图片描述
当时的源代码作者尝试了BERT+BILSTM+CRF、BERT+IDCNN+CRF、动态权重融合BERT+IDCNN/BILSTM+CRF。

(1)BERT+BILSTM+CRF
在预训练模型BERT未出现之前,BILSTM-CRF就是一种比较流行的命名实体识别框架,这里将BERT的token向量(即含有上下文信息的词向量)喂到BILSTM中,BILSTM可以进一步提取特征,CRF可以更好的学习到标签之间的约束关系。网络模型一般输出的是一个句子的每个字的分类,不能够较好的考虑该字左右两边的结果,比如小明,小(B-PER)明(I-PER),可能会预测成小(B-PER)明(B-PER),而CRF可以避免这种情况,比如B-PER后面只能是I-PER或者O类标签。感兴趣的话可以参考这篇文章 博客.
BERT+BILSTM+CRF的结构如下图所示:
在这里插入图片描述
(2)BERT+IDCNN+CRF
IDCNN(Iterated Dilated Convolutional Neural Networks)迭代空洞卷积神经网络,和传统的CNN相比,IDCNN可以较好的捕捉更长的上下文信息,和时序模型LSTM相比,IDCNN可以实行并行化运算,大大提高了模型的运算速度,这里不再对 IDCNN模型进行赘述,感兴趣的话可以参考以下几篇文章:
【1】IDCNN for NER论文阅读笔记: 链接.
【2】如何理解空洞卷积(dilated convolution): 链接1.
【3】如何理解空洞卷积(dilated convolution): 链接2.
BERT+IDCNN+CRF的结果如下图所示:
在这里插入图片描述
本文采用的是当时IDCNN作者默认的模型参数,各层的dilation为[1,1,2],卷积核参数为3x3
(3)动态融合的BERT+IDCNN+CRF
BERT的每一层编码对文本都有着不同的理解,本文将BERT的12层编码赋予了不同的权重,初始化公式按照如下公式进行初始化:

然后通过训练来确定权重,并将每一层的表示进行加权平均,在后接一层全连接层降维至512维(BERT可以接收的最大序列长度),公式如下:

式中represent i 为BERT每一层输出的表示,ai 为权重BERT每一层表示的权重值。
动态融合的BERT结构图如下图所示:
在这里插入图片描述
后续将512维的向量输入BILSTM/IDCNN-CRF模型即可。
(4)代码实现

-动态融合BERT和原生BERT代码:
【注意】这里的BERT代码直接调用bert_modeling库(该库来源于官方库)

 
  • IDCNN代码:
 
  • BILSTM代码
 
  • CRF层代码(tensorflow.contrib.crf库中的crf_log_likelihood):
 
 

模型的训练模型参数微调和模型保存。

  • 模型的训练
 
  • 使用验证集,验证每个epoch的效果,并保存模型
 

训练过程的结果如下图所示:在这里插入图片描述
本次实验使用的是6G的显卡,batch_size设置为2,训练完一个epoch大概花费了两个小时左右,最终会在model/runs_0路径下生成训练好的模型:
在这里插入图片描述

先通过运行check_F1.py查看最优的预测模型,而后读取模型,再通过之前在model.py给每一个变量设置的变量名得到我们需要的变量,这样做的好处是无需重新构建模型图,只要抽取我们预测所需要的变量即可完成任务,一定程度上对我们的模型代码进行了加密。最后我们对测试集进行预测,并保存所需的预测概率。预测的代码结构和训练的代码相差不大

 

预测的结果如下图所示,后续需要对该文件进行后处理:
在这里插入图片描述
会在该路径下生成测试文件:
在这里插入图片描述

  • ensemble/ensemble.py
    将predict.py生成的概率文件复原成文字结果。其中,remove_list存放的是predict.py生成的概率文件名。如果我们想要还原某个模型的文字结果,直接注释该模型的概率文件即可。当然,vote_ensemble函数也可以对多个模型的概率文件进行还原,相当于是对多个模型的出来的标签进行数字投票,并还原成文字结果。不过笔者在竞赛时统计错误发现数字投票会截断实体,如下图所示。为此,笔者将数字投票改成了对所有单模的文字结果进行投票,我们通过设定阈值,统计每一条数据的预测实体在所有模型的出现次数,当实体出现次数大于阈值时,则认为该实体是未知实体,将其保留。笔者通过这个方法提高了两个百分点的成绩。
 
 
 

对多个异构单模的文字结果投票进行多模融合。具体的融合思路如下图所示。我们通过模型构建部分获得了多个异构模型,我们选择高召回率的模型进行单模预测,并将得到的单模结果进行文字投票融合得到最终结果
在这里插入图片描述

(1)自建库或者别人写的非官方库(这里的官方库指的是可以pip/conda install的那种)在pycharm环境中一定要设置成Resource root这样在调用该库时不会报错。
在这里插入图片描述
设置成功后,该文件夹为蓝色,设置过程如下:
在这里插入图片描述

(2)注意初始化文件config.py中一些模型的路径问题:

 

这里建议最好使用“/”而不是windows 文件路径的“”,因为“”容易被理解成转义字符
(3)原作者没有给出BERT官方的预训练模型,官方给出了多种不同的BERT模型,这里可以选择合适的模型,放在相应路径即可。下载速度慢的可以参考:https://gitee.com/cheng_jinpei/bert
(4)由于笔者水平和经验有限,该解析文件肯定存在一些漏洞,欢迎大家进行批评与指正

上一篇:民生银行再现亿元“飞单案”追讨无果,买理财要擦亮眼……(民生银行北京假理财案涉及金额16.5亿 部分客户不接受赔偿方案)
下一篇:《教育周报数学二年级北师大版》
相关文章
返回顶部小火箭