NLP入门(五)用深度学习实现命名实体识别(NER)
文章目录
在本文中,我们将会学习到如何使用深度学习工具来自己一步步地实现NER,只要你坚持看完,就一定会很有收获的。 几乎所有的NLP都依赖一个强大的语料库,本项目实现NER的语料库如下(文件名为train.txt,一共42000行,这里只展示前15行,可以在文章最后的Github地址下载该语料库):
|
|
简单介绍下该语料库的结构:该语料库一共42000行,每三行为一组,其中,第一行为英语句子,第二行为每个句子的词性(关于英语单词的词性,可参考文章:NLP入门(三)词形还原(Lemmatization)),第三行为NER系统的标注,具体的含义会在之后介绍。 我们的NER项目的名称为DL_4_NER,结构如下:
项目中每个文件的功能如下:
utils.py: 项目配置及数据导入 data_processing.py: 数据探索 Bi_LSTM_Model_training.py: 模型创建及训练 Bi_LSTM_Model_predict.py: 对新句子进行NER预测 接下来,笔者将结合代码文件,分部介绍该项目的步骤,当所有步骤介绍完毕后,我们的项目就结束了,而你,也就知道了如何用深度学习实现命名实体识别(NER)。 Let’s begin!
项目配置
第一步,是项目的配置及数据导入,在utils.py文件中实现,完整的代码如下:
|
|
在该代码中,先是设置了语料库文件的路径CORPUS_PATH,KERAS模型保存路径KERAS_MODEL_SAVE_PATH,以及在项目过程中会用到的三个字典的保存路径(以pickle文件形式保存)WORD_DICTIONARY_PATH,LABEL_DICTIONARY_PATH, OUTPUT_DICTIONARY_PATH。然后是load_data()函数,它将语料库中的文本以Pandas中的DataFrame结构展示出来,该数据框的前30行如下:
|
|
在该数据框中,word这一列表示文本语料库中的单词,pos这一列表示该单词的词性,tag这一列表示NER的标注,sent_no这一列表示该单词在第几个句子中。
数据探索 接着,第二步是数据探索,即对输入的数据(input_data)进行一些数据review,完整的代码(data_processing.py)如下:
|
|
调用data_review()函数,输出的结果如下:
|
|
在该语料库中,一共有13998个句子,比预期的42000/3=14000个句子少两个。一个有24339个单词,单词量还是蛮大的,当然,这里对单词没有做任何处理,直接保留了语料库中的形式(后期可以继续优化)。单词的词性可以参考文章:NLP入门(三)词形还原(Lemmatization)。我们需要注意的是,NER的标注列表为[‘O’ ,‘B-MISC’, ‘I-MISC’, ‘B-ORG’ ,‘I-ORG’, ‘B-PER’ ,‘B-LOC’ ,‘I-PER’, ‘I-LOC’,‘sO’],因此,本项目的NER一共分为四类:PER(人名),LOC(位置),ORG(组织)以及MISC,其中B表示开始,I表示中间,O表示单字词,不计入NER,sO表示特殊单字词。
接下来,让我们考虑下句子的长度,这对后面的建模时填充的句子长度有有参考作用。句子长度及出现频数的统计图如下:
可以看到,句子长度基本在60以下,当然,这也可以在输出的句子长度及出现频数字典中看到。那么,我们是否可以选在一个标准作为后面模型的句子填充的长度呢?答案是,利用出现频数的累计分布函数的分位点,在这里,我们选择分位点为0.9992,对应的句子长度为60,如下图:
接着是数据处理函数data_processing(),它的功能主要是实现单词、标签字典,并保存为pickle文件形式,便于后续直接调用。
建模
在第三步中,我们建立Bi-LSTM模型来训练训练,完整的Python代码(Bi_LSTM_Model_training.py)如下:
|
|
在上面的代码中,先是通过input_data_for_model()函数来处理好进入模型的数据,其参数为input_shape,即填充句子时的长度。然后是创建Bi-LSTM模型create_Bi_LSTM(),模型的示意图如下:
最后,是在输入的数据上进行模型训练,将原始的数据分为训练集和测试集,占比为9:1,训练的周期为10次。
模型训练
运行上述模型训练代码,一共训练10个周期,训练时间大概为500s,在训练集上的准确率达99%以上,在测试集上的平均准确率为95%以上。以下是最后几个测试集上的预测结果:
|
|
该模型在原始数据上的识别效果还是可以的。
训练完模型后,BASE_DIR中的所有文件如下:
模型预测
最后,也许是整个项目最为激动人心的时刻,因为,我们要在新数据集上测试模型的识别效果。预测新数据的识别结果的完整Python代码(Bi_LSTM_Model_predict.py)如下:
|
|
输出结果为:
|
|
接下来,再测试三个笔者自己想的句子:
输入为:
|
|
输出结果为:
|
|
输入为: sent = ‘Oxford is in England, Jack is from here.’
输出为:
|
|
输入为:
|
|
输出为:
|
|
在上面的例子中,只有Oxford的识别效果不理想,模型将它识别为PERSON,其实应该是ORGANIZATION。
接下来是三个来自CNN和wikipedia的句子:
输入为:
|
|
输出为:
|
|
输入为:
|
|
输出为:
|
|
输入为:
|
|
输出为:
|
|
这三个例子识别全部正确。
总结 到这儿,笔者的这个项目就差不多了。我们有必要对这个项目做个总结。 首先是这个项目的优点。它的优点在于能够让你一步步地实现NER,而且除了语料库,你基本熟悉了如何创建一个识别NER系统的步骤,同时,对深度学习模型及其应用也有了深刻理解。因此,好处是显而易见的。当然,在实际工作中,语料库的整理才是最耗费时间的,能够占到90%或者更多的时间,因此,有一个好的语料库你才能展开工作。 接着讲讲这个项目的缺点。第一个,是语料库不够大,当然,约14000条句子也够了,但本项目没有对句子进行文本预处理,所以,有些单词的变形可能无法进入词汇表。第二个,缺少对新词的处理,一旦句子中出现一个新的单词,这个模型便无法处理,这是后期需要完善的地方。第三个,句子的填充长度为60,如果输入的句子长度大于60,则后面的部分将无法有效识别。 因此,后续还有更多的工作需要去做,当然,做一个中文NER也是可以考虑的。 本项目已上传Github,地址为 https://github.com/percent4/DL_4_NER
##参考文献 BOOK: Applied Natural Language Processing with Python, Taweh Beysolow II WEBSITE:https://github.com/Apress/applied-natural-language-processing-w-python WEBSITE: NLP入门(四)命名实体识别(NER): https://www.jianshu.com/p/16e1f6a7aaef
文章作者 glin
上次更新 2020-09-08 01:37