实践课堂:使用keras和tensorflow进行命名实体识别(NER)
点击上方关注,All in AI中国
通过应用最先进的深度学习方法满足行业需求---
几年前,当我在一家创业公司担任软件工程实习生时,我看到了一个发布网络应用程序的新功能。该应用程序能够识别和解析重要信息,如电子邮件地址、电话号码、学位标题等。我开始与我们的团队讨论可能的方法,我们决定在python中构建一个基于规则的解析器来解析不同的部分简历。花了一些时间开发解析器之后,我们意识到答案可能不是基于规则的工具。我们开始在谷歌上搜索它是如何实现的,我们遇到了自然语言处理(NLP)这个术语以及与机器学习相关的更具体的命名实体识别(NER)。
NER是一种信息提取技术,用于识别和分类文本中的命名实体。这些实体可以是预定义的,也可以是通用的,如位置名称、组织、时间等,或者它们可以非常具体,就像简历中的示例一样。 NER在业务中有各种各样的用例。我认为gmail是在您撰写电子邮件时应用NER并且您在电子邮件中提及时间或附加文件,gmail提供设置日历通知或提醒您附加文件以防您在没有附件的情况下发送电子邮件。 NER的其他应用包括:从法律、财务和医疗文档中提取重要的命名实体,为新闻提供者分类内容,改进搜索算法等。对于本文的其余部分,我们将简要介绍不同的解决NER问题的方法然后开始编写最先进的方法。以下是Suvro对NER的更详细的介绍。
NER的方法
- 经典方法:主要是基于规则的。以下是由Sentdex的一个简短精彩视频的链接,它使用python中的NLTK包来表示NER。
- 机器学习方法:此类别中有两种主要方法:A-将问题视为多类别分类,其中命名实体是我们的标签,因此我们可以应用不同的分类算法。这里的问题是识别和标记命名实体需要彻底了解句子的上下文和单词标签的序列,而这种方法忽略了这一点。 B-此类别中的另一种方法是条件随机场(CRF)模型。它是一种概率图形模型,可用于对连续数据进行建模,例如句子中的单词标签。有关python中CRF的更多详细信息和完整实现。 CRF模型能够捕获序列中当前和以前标签的特征,但它无法理解前向标签的上下文;这个缺点加上训练CRF模型所涉及的额外功能工程,使其不太适合行业调整。
- 深度学习方法:
在讨论有关NER的深度学习方法(最新技术)的详细信息之前,我们需要分析适当且清晰的指标来评估模型的性能。在不同迭代(时期)中训练神经网络作为评估度量时,通常使用准确性。但是,在NER的情况下,我们可能正在处理重要的财务、医疗或法律文件,并且这些文件中的命名实体的精确识别决定了模型的成功与否。换句话说,误报和漏报在NER任务中会带来业务成本。因此,我们评估模型的主要指标是F1得分,因为我们需要在精确度和召回之间取得平衡。
构建高性能深度学习方法的另一个重要策略是,考虑到文本是顺序数据格式,了解哪种类型的神经网络能够最有效地解决NER问题。是的,你猜对了......长期短记忆(LSTM)。但这里不是指任何类型的LSTM,我们需要使用双向LSTM,因为使用标准LSTM进行预测只会考虑文本序列中的“过去”信息。对于NER,由于上下文涵盖序列中的过去和未来标签,因此我们需要考虑过去和未来的信息。双向LSTM是两个LSTM的组合 - 一个从“从右到左”向前运行,一个从“从左到右”向后运行。
我们将通过参考实际的研究论文快速浏览四种不同的最先进方法的架构,然后我们将继续以最高的精度实现其中一种。
1.双向LSTM-CRF:
keras中的更多细节和实现。
来自论文(用于序列标记的双向LSTM-CRF模型)
2.双向LSTM-CNN:
在keras中的更多细节和实现。
来自论文(双向LSTM-CNN的命名实体识别)
3.双向LSTM-CNNS-CRF:
来自论文(通过双向LSTM-CNNs-CRF的端到端序列标记)
4. ELMo(从语言模型嵌入):
最近的一篇论文(Deep contextualized word representationations)引入了一种新型的深层语境化词语表示,它模拟了词语使用的复杂特征(例如,语法和语义)以及这些用法如何在语言环境中变化(即模型)一词多义)。新方法(ELMo)有三个重要的表示:
1.上下文:每个单词的表示取决于使用它的整个上下文。
2.深度:单词表示结合了深度预训练神经网络的所有层。
3.基于字符:ELMo表示纯粹基于字符,允许网络使用形态学线索为训练中未见的词汇表外标记形成表示。
ELMo对语言有很好的理解,因为它是在大量数据集上训练的,ELMo嵌入是在10亿字基准上进行训练的。训练被称为双向语言模型(biLM),可以从过去学习并预测像句子这样的单词序列中的下一个单词。让我们看看如何实现这种方法。我们将使用来自kaggle的数据集(https://www.kaggle.com/abhinavwalia95/entity-annotated-corpus/home)。
我们的数据集中有47958个句子,35179个不同的单词和17个不同的命名实体(标签)。
我们来看看数据集中句子长度的分布:
这个类负责将每个带有命名实体(标签)的句子转换为元组列表[(word,named entity),...]
因此,最长的句子中有140个单词,我们可以看到几乎所有的句子都少于60个单词。
这种方法的最大好处之一是我们不需要任何特征工程;我们需要的只是句子及其标记的单词,其余的工作由ELMo嵌入进行。为了将我们的句子提供给LSTM网络,它们都需要具有相同的大小。查看分布图,我们可以将所有句子的长度设置为50,并为空格添加一个通用词;这个过程称为填充。(50是一个好数字的另一个原因是我的笔记本电脑无法处理更长的句子)。
这同样适用于命名实体,但这次我们需要将标签映射到数字:
接下来,我们将数据分成训练和测试集,然后我们导入tensorflow Hub(用于发布、发现和消耗机器学习模型的可重用部分的库)以加载ELMo嵌入功能和keras以开始构建我们的网络。
首次运行上面的代码块需要一些时间,因为ELMo几乎是400 MB。接下来我们使用函数将句子转换为ELMo嵌入:
现在让我们构建神经网络:
由于我们有32个作为批处理大小,所以网络的馈送必须是32个倍数的块:
最初的目标是使用参数调整来实现更高的准确性,但我的笔记本电脑无法处理超过3个epoch和大于32的批处理大小,也不能增加测试大小。我在Geforce GTX 1060上运行keras,并且花了将近45分钟来训练这3个epoch,如果你有更好的GPU,可以通过改变其中的一些参数来实现它。
0.9873验证精度是一个很好的分数,但我们没有兴趣用Accuracy metric评估我们的模型。让我们看看如何获得精度、召回率和F1得分:
0.82 F1得分是一项了不起的成就。 它胜过本节开头提到的所有其他三种深度学习方法,并且可以很容易地被业界采用。
最后,让我们看看我们的预测是什么样的:
代码传送门:https://github.com/nxs5899/Named-Entity-Recognition_DeepLearning-keras
参考文献:
https://www.depends-on-the-definition.com/named-entity-recognition-with-residual-lstm-and-elmo/
http://www.wildml.com/2016/08/rnns-in-tensorflow-a-practical-guide-and-undocumented-features/
https://allennlp.org/elmo
https://jalammar.github.io/illustrated-bert/