中文NER的一些探索

1.初识NER

NER(命名实体识别)其实是一个非常基础且古老的问题,关系抽取,事件抽取都是建立在其之上的,简而言之,NER任务是从一段文本中识别固定类型的实体,如时间,地点,人名,组织名等。其实就是一个序列标注问题。在传统机器学习时代,这个问题是由HMM,CRF解决的,其中HMM仅考虑了前一个word的影响,而CRF在所有特征进行全局归一化,因此可以求得全局的最优值,因而可以容纳任意的上下文信息,特征设计灵活。使用维特比算法,计算整个标记序列的联合概率分布。

在深度学习时代,出现了BiLSTM+CRF的方法,在Bert时代出现了Bert+LSTM+CRF的方法。

2.BERT+LSTM+CRF

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

先放github,再讲解一下使用过程。


Bert+lstm+crf代码

①下载bert-lstm-crf代码(https://github.com/macanv/BERT-BiLSTM-CRF-NER)

②下载预训练的中文BERT模型
https://storage.googleapis.com/bert_models/2018_11_03/chinese_L-12_H-768_A-12.zip(里面包含了BERT的中文预训练模型以及词汇列表txt)

③修改bert_base/train/train_helper.py文件(设置路径,也可以修改超参,其中bert_path与root_path是必须要提供的)

红框windows系统,紫框linux系统

bert_path改成②中下载的目录

root_path下有两个文件output(存放训练好的模型,以及中间过程的产出),NERdata(训练集)


root_path

其中NERdata下的文件为 train.txt 、dev.txt 、 test.txt(即为我们要训练模型的数据集)

需要注意的是,训练集中,每个句子与每个句子之间需要有一个空行。标签格式大致为 B-PER I-PER(B/I在前)


训练集,一行一个字以及与之对应的标签,句与句之前有空行

④运行run.py开始训练代码,训练完后会自动输出精确度等信息

⑤训练完成后使用terminal_predict.py使用模型,注意,也需要更改代码中的模型路径。


model_dir路径为之前训练出的模型的路径,bert_dir为预训练模型的路径


测试效果如图

具体的过程也可以参考:https://blog.csdn.net/macanv/article/details/85684284

但实际上BERT并不太适用于NER任务。

虽然Transformer模型在其它NLP任务中取得了很大成功,并且在并行性和长程依赖方面有巨大优势,但其在NER中表现不佳。我们分析了Transformer的注意力机制,发现其在方向性、相对位置、稀疏性方面不太适合NER任务。——邱锡鹏 


BERT+CRF并不是很适合NER任务

解释一下实体边界错误,比如我们希望识别出来的地名是“苏州市姑苏区”,而BERT+CRF训练出的模型有可能识别结果是“州市姑苏”、“州市姑苏区X”。


识别赛事所出现的边界错误问题

之后我们将探索两个解决方法

3.解决方法1:

TENER: Adapting Transformer Encoder for Named Entity Recognition

paper地址:https://arxiv.org/abs/1911.04474

代码地址:https://github.com/fastnlp/TENER

该模型通过对注意力打分函数的简单改进,使得Transformer结构在NER任务上性能大幅提升。

3.1论文笔记

paper首先分析了为什么BERT再NER任务上的表现没有其在其他NLP任务上的表现好:

①transformer encoder中的position embedding主要到了距离,但忽略了方向性。在BERT出现之前,应用最广泛的BiLSTM+CRF模型中的LSTM可以区分地从其左右两侧收集token的上下文信息,但transformer却不具备这个能力,它只能反映距离,无法反映方向。为了解决这个问题,作者提出了distance-aware使transformer在一定程度上具备方向性。

②transformer encoder中的 scale dot-product attention比较平滑,NER需要的是一个不那么平滑的attention,因为一句话中只有少量的word需要被标注。为了解决这个问题,作者采用un-scale dot-product attention。


TENER模型结构

3.1.1 TENER——embedding module

本层用于得到word embedding( = extracted character feature  concat  pre-trained word embedding)

字符级别的特征提取用的是transformer,大多数NER模型通过使用CNN character encoder去缓解数据稀疏性以及OOV问题,而作者选择transformer是因为其能够提取到不同n-grams的模式以及一些非连续的word的字符模式,例如"unhappily"和"uneasily"中的“un..ily"模式(CNN的kernel通常设置为3,提取不到这种模式。 )

3.1.2 TENER——Encoding Layer with Adapted Transformer

该层算是模型的核心了,再回顾一下之前提到的transformer encoder对于方向性的无奈,在本层中作者使用了 relative positional encoding,而不是transformer encoder原先的固定position embedding。


relative positional encoding

relative positional encoding是由Peter Shaw提出的(Self-Attention with Relative Position Representations)(2018 NAACL)之后也有一系列改进工作例如transformer-XL(2019 ACL)


本篇中使用的relative positional encoding正是前人们的成果

除了relative positional encoding之外,作者采用un-scale dot-product attention


transformer encoder中的scale dot-product attention

作者分析原先的attention中,除以会使得softmax函数的输出更加平滑,而直接将分母去除,会使softmax的输出变得陡峭(sharper),而NER任务中sharper更好(一个句子中只有少量的字需要被标注)

3.1.3 TENER——CRF Layerd

条件随机场,懂得都懂,不多说了,为了利用不同tag之间的依赖关系,例如形容词后面基本是名词而不是动词。

3.2代码实战

4.解决方法2:

BERT-EntityNameEmbedding 模型 (来自CCKS&百度 2019中文短文本的实体链指 第一名解决方案

代码地址:https://github.com/panchunguang/ccks_baidu_entity_link(readme有详细介绍)

你可能感兴趣的:(中文NER的一些探索)