Home

gentlesnow

13 Jul 2019

【NLP基础任务】 4 命名实体识别

命名实体识别(英语:Named Entity Recognition),简称NER, 是指识别文本中具有特定意义的实体,主要包括人名、地名、机构名、专有名词等, 以及时间、数量、货币、比例数值等文字。

NER又称作专名识别,是自然语言处理中的一项基础任务,应用范围非常广泛。 命名实体一般指的是文本中具有特定意义或者指代性强的实体, 通常包括人名、地名、组织机构名、日期时间、专有名词等。 NER系统就是从非结构化的输入文本中抽取出上述实体,并且可以按照业务需求识别出更多类别的实体, 比如产品名称、型号、价格等。因此实体这个概念可以很广, 只要是业务需要的特殊文本片段都可以称为实体。

学术上NER所涉及的命名实体一般包括3大类(实体类,时间类,数字类) 和7小类(人名、地名、组织机构名、时间、日期、货币、百分比)。

实际应用中,NER模型通常只要识别出人名、地名、组织机构名、日期时间即可 ,一些系统还会给出专有名词结果(比如缩写、会议名、产品名等)。 货币、百分比等数字类实体可通过正则搞定。 另外,在一些应用场景下会给出特定领域内的实体,如书名、歌曲名、期刊名等。

NER是NLP中一项基础性关键任务。 从自然语言处理的流程来看,NER可以看作词法分析中未登录词识别的一种, 是未登录词中数量最多、识别难度最大、对分词效果影响最大问题。 同时NER也是关系抽取、事件抽取、知识图谱、机器翻译、问答系统等诸多NLP任务的基础。

NER当前并不算是一个大热的研究课题,因为学术界部分学者认为这是一个已经解决的问题。 当然也有学者认为这个问题还没有得到很好地解决, 原因主要有:

  1. 命名实体识别只是在有限的文本类型(主要是新闻语料中) 和实体类别(主要是人名、地名、组织机构名)中取得了不错的效果;
  2. 与其他信息检索领域相比,实体命名评测预料较小,容易产生过拟合;
  3. 命名实体识别更侧重高召回率,但在信息检索领域,高准确率更重要;
  4. 通用的识别多种类型的命名实体的系统性能很差。

目前在NER上表现较好的模型都是基于深度学习或者是统计学习的方法的, 这些方法共同的特点都是需要大量的数据来进行学习。

NER一直是NLP领域中的研究热点,从早期基于词典和规则的方法,到传统机器学习的方法, 到近年来基于深度学习的方法,NER研究进展的大概趋势大致如下所示。

  1. 早期的方法
  2. 基于规则的方法 正则
  3. 基于词典的方法
  4. 投票模型 Majority Voting (baseline)
  5. 传统机器学习方法
  6. HMM
  7. MEMM
  8. CRF
  9. 逻辑回归
  10. SVM
  11. 深度学习
  12. RNN+CRF
  13. CNN+CRF
  14. 近期的方法
  15. 注意力模型
  16. 迁移学习

基于规则的方法

正则: 美国电话: (?:\(?[0-9]{3}\)?[0-9]{3}[ -.]?[0-9]{4})

利用词典:

  1. 提前构建词库word_dict
  2. if token.contain(word) and word in word_dict

Majority Voting

统计每个单词的实体类型,记录针对每个单词,概率最大的实体类型。

import numpy as np
import pandas as pd
from sklearn.base import BaseEstmator, TransformerMixin


data = pd.read_csv('ner_dataset.csv', encoding='latin1')
data = data.fillna(method='ffill')

words = list(set(data['word'].values))
n_words = len(words)


class MajorityVotingTagger(BaseEstimator, TransformerMixin):
    def fit(self, x, y):
        """
        x: list of words
        y: list of tags
        """
        word2cnt = {}
        self.tags = []

        for x, t in zip(X, y):
            if t not in self.tags:
                self.tags.appemd(t)
            if x in word2cnt:
                if t in word2cnt[x]:
                    word2cnt[x][t] += 1
                else:
                    word2cnt[x][t] = 1
            else:
                word2cnt[x] = {t: 1}
        self.mjvote = {}

        for k, d in word2cnt.items():
            self.mjvote[k] = max(d, key=d.get)

    def predict(self, X, y=None):
        """
        predict the tag form memory.
        if word is unknown, predict 'o'.
        """
        return [self.mjvote.get(x, 'o') for x in X]



统计学习的方法

特种工程 -> 分类器 -> 分类结果

特征工程:

  1. Bag-of-word features
  2. 词性 features
  3. 前缀&后缀
  4. 当前词的特性
  5. steming + 重复1

在基于机器学习的方法中,NER被当作序列标注问题。 利用大规模语料来学习出标注模型,从而对句子的各个位置进行标注。 NER 任务中的常用模型包括生成式模型HMM、判别式模型CRF等。 条件随机场(ConditionalRandom Field,CRF)是NER目前的主流模型。 它的目标函数不仅考虑输入的状态特征函数,而且还包含了标签转移特征函数。 在训练时可以使用SGD学习模型参数。 在已知模型时,给输入序列求预测输出序列即求使目标函数最大化的最优序列, 是一个动态规划问题,可以使用Viterbi算法解码来得到最优标签序列。 CRF的优点在于其为一个位置进行标注的过程中可以利用丰富的内部及上下文特征信息。

深度学习的方法

近年来,随着硬件计算能力的发展以及词的分布式表示(word embedding)的提出, 神经网络可以有效处理许多NLP任务。 这类方法对于序列标注任务(如CWS、POS、NER)的处理方式是类似的: 将token从离散one-hot表示映射到低维空间中成为稠密的embedding, 随后将句子的embedding序列输入到RNN中,用神经网络自动提取特征,Softmax来预测每个token的标签。

这种方法使得模型的训练成为一个端到端的过程,而非传统的pipeline,不依赖于特征工程, 是一种数据驱动的方法,但网络种类繁多、对参数设置依赖大,模型可解释性差。 此外,这种方法的一个缺点是对每个token打标签的过程是独立的进行, 不能直接利用上文已经预测的标签(只能靠隐含状态传递上文信息), 进而导致预测出的标签序列可能是无效的,例如标签I-PER后面是不可能紧跟着B-PER的, 但Softmax不会利用到这个信息。

学界提出了DL-CRF模型做序列标注。 在神经网络的输出层接入CRF层(重点是利用标签转移概率)来做句子级别的标签预测, 使得标注过程不再是对各个token独立分类。


参考资料

  1. NLP实战-中文命名实体识别
  2. https://createmomo.github.io/2017/11/11/CRF-Layer-on-the-Top-of-BiLSTM-5/
  3. https://zhuanlan.zhihu.com/p/27338210
  4. https://blog.csdn.net/cuihuijun1hao/article/details/79405740

Til next time,
gentlesnow at 21:48

scribble