精华内容
下载资源
问答
  • 命名实体识别(NER)】(1):命名实体识别综述

    万次阅读 多人点赞 2019-03-23 09:41:44
    命名实体识别综述 什么是命名实体识别命名实体识别(Named Entity Recognition,简称NER),又称作**“专名识别”,是自然语言处理中的一项基础任务,应用范围非常广泛。命名实体一般指的是文本中具有特定意义...

    什么是命名实体识别?

    命名实体识别(Named Entity Recognition,简称NER),又称作“专名识别”,是自然语言处理中的一项基础任务,应用范围非常广泛。命名实体一般指的是文本中具有特定意义或者指代性强的实体,通常包括 人名地名机构名日期时间专有名词等。通常包括两部分:

    • 实体的边界识别
    • 确定实体的类型(人名、地名、机构名或其他)

    NER系统就是从非结构化的输入文本中抽取出上述实体,并且可以按照业务需求识别出更多类别的实体,比如产品名称、型号、价格等。因此实体这个概念可以很广,只要是业务需要的特殊文本片段都可以称为实体。

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

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

    命名实体识别的价值和应用领域

    命名实体识别是NLP中一项基本性的关键任务,是关系抽取事件抽取知识图谱信息提取问答系统句法分析机器翻译等诸多NLP任务的基础,被广泛应用在自然语言处理领域,同时在自然语言处理技术走向实用化的过程中占有重要地位。

    • 事件检测: 地点、时间、人物是事件的基本构成部分,在构建事件的摘要时,可以突出相关人物、地点、单位等。在事件搜索系统中,相关的人物、时间、地点可以作为索引关键词。通过事件的几个构成部分之间的关系,可以从语义层面更详细地描述事件。
    • 信息检索: 命名实体可以用来提高和改进检索系统的效果,当用户输入“重大”时,可以发现用户更想检索的是“重庆大学”,而不是其对应的形容词含义。此外,在建立倒排索引的时候,如果把命名实体切成多个单词,将会导致查询效率降低。此外,搜索引擎正在向语义理解、计算答案的方向发展。
    • 语义网络: 语义网络中一般包括概念实例及其对应的关系,例如“国家”是一个概念,中国是一个实例,“中国”是一个“国家”表达实体与概念之间的关系。语义网络中的实例有很大一部分是命名实体。
    • 机器翻译: 命名实体的翻译(尤其像人名、专有名词、机构名等),常常会有某些特殊的翻译规则(例如中国的人名翻译成英文时要使用名字的拼音来表示,有名在前姓在后的规则),而普通的词语要翻译成对应的英文单词。准确识别出文本中的命名实体,对提高机器翻译的效果有直接的意义。
    • 问答系统: 准确识别出问题的各个组成部分问题的相关领域相关概念是问答系统的重点和难点。目前,大部分问答系统都只能搜索答案,而不能计算答案。搜索答案进行的是关键词的匹配,用户根据搜索结果人工提取答案,而更加友好的方式是把答案计算好呈现给用户。问答系统中有一部分问题需要考虑到实体之间的关系,例如“美国第四十五届总统”,目前的搜索引擎会以特殊的格式返回答案“特朗普”。

    命名实体识别的研究现状和难点

    命名实体识别当前并不是一个大热的研究课题,因为学术界部分学者认为这是一个已经解决了的问题,但是也有学者认为这个问题还没有得到很好地解决,原因主要有:

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

    同时,中文的命名实体识别与英文的命名实体识别相比,挑战更大,目前未解决的难题更多。英语中的命名实体具有比较明显的形式标志,即实体中的每个词的第一个字母要大写,所以对实体边界的识别相对容易,任务的重点是确定实体的类别。和英语相比,汉语命名实体识别任务更加复杂,而且相对于实体类别标注任务而言,实体边界的识别更加困难。汉语命名实体识别的难点主要存在于:

    • 汉语文本没有类似英文文本中空格之类的显式标示词的边界标示符,命名实体识别的第一步就是确定词的边界,即中文分词
    • 汉语分词和命名实体识别互相影响
    • 除了英语中定义的实体,外国人名译名地名译名是存在于汉语中的两类特殊实体类型
    • 现代汉语文本,尤其是网络文本,常出现中英文交替使用,此时汉语命名实体识别的任务还包括识别其中的英文命名实体
    • 不同的命名实体具有不同的内部特征,不可能用一个统一的模型来刻画所有的实体内部特征
    • 现代汉语日新月异的发展给命名实体识别也带来了新的困难:(1)标注语料老旧,覆盖不全。譬如说,近年来起名字的习惯用字与以往相比有很大的变化,以及各种复姓识别、国外译名、网络红人、流行用语、虚拟人物和昵称的涌现。(2)命名实体歧义严重,消歧困难

    命名实体识别解决方案

    命名实体识别(NER)一直是NLP领域中的研究热点,从早期基于词典和规则的方法,到传统机器学习的方法,到近年来基于深度学习的方法,命名实体识别(NER)研究进展的大概趋势大致如下图所示:
    在这里插入图片描述

    基于规则和字典的方法

    基于规则的方法多采用语言学专家手工构造规则模板,选用特征包括统计信息标点符号关键字指示词和方向词位置词(如尾字)中心词等方法,以模式和字符串相匹配为主要手段,这类系统大多依赖于知识库和词典的建立。基于规则和词典的方法是命名实体识别中最早使用的方法,它们依赖于手工规则的系统,都使用命名实体库,而且对每一个规则都赋予权值。当遇到规则冲突的时候,选择权值最高的规则来判别命名实体的类型。一般而言,当提取的规则能比较精确地反映语言现象时,基于规则的方法性能要优于基于统计的方法。但基于规则和字典的方法也有其缺陷:

    • 规则往往依赖于具体语言、领域和文本风格,制定规则的过程耗时且难以涵盖所有的语言,特别容易产生错误,系统可移植性差,对于不同的系统需要语言学专家重新书写规则
    • 代价太大,存在系统建设周期长、需要建立不同领域知识库作为辅助以提高系统识别能力等问题

    基于统计机器学习的方法

    基于统计机器学习的方法主要包括:隐马尔可夫模型(Hidden Markov Moder, HMM)最大熵模型(Maximum Entropy Model, MEM)支持向量机(Support Vector Machine, SVM)条件随机场(Conditional Random Field, CRF)等等。在基于机器学习的方法中,NER被当作序列标注问题。利用大规模语料来学习出标注模型,从而对句子的各个位置进行标注。NER 任务中的常用模型包括生成式模型HMM、判别式模型CRF等。条件随机场(Conditional Random Field,CRF)是NER目前的主流模型。

    条件随机场(CRF) 的目标函数不仅考虑输入的状态特征函数,而且还包含了标签转移特征函数。在训练时可以使用SGD学习模型参数。在已知模型时,给输入序列求预测输出序列即求使目标函数最大化的最优序列,是一个动态规划问题,可以使用维特比算法进行解码。CRF的优点在于其为一个位置进行标注的过程中可以利用丰富的内部及上下文特征信息。
    在这里插入图片描述

    在传统机器学习方法中,常用的特征如下:
    在这里插入图片描述

    四种学习方法的优缺点分析

    • 最大熵模型结构紧凑,具有较好的通用性,主要缺点是训练时间复杂性非常高,有时甚至导致训练代价难以承受,而且最大熵模型需要归一化计算,导致开销比较大
    • 条件随机场为命名实体识别提供了一个特征灵活、全局最优的标注框架,但同时存在收敛速度慢、训练时间长的问题
    • 一般说来,最大熵和支持向量机在正确率上要比隐马尔可夫模型高一些,但是隐马尔可夫模型在训练和识别时的速度要快一些,主要是由于在利用Viterbi算法求解命名实体类别序列的效率较高
    • 隐马尔可夫模型更适用于一些对实时性有要求以及像信息检索这样需要处理大量文本的应用,如短文本命名实体识别

    基于统计的方法对特征选取的要求较高,需要从文本中选择对该项任务有影响的各种特征,并将这些特征加入到特征向量中。依据特定命名实体识别所面临的主要困难和所表现出的特性,考虑选择能有效反映该类实体特性的特征集合。主要做法是通过对训练语料所包含的语言信息进行统计和分析,从训练语料中挖掘出特征。有关特征可以分为具体的单词特征上下文特征词典及词性特征停用词特征核心词特征以及语义特征等。基于统计的方法对语料库的依赖也比较大,而可以用来构建和评估命名实体识别系统的大规模通用语料库又比较少,这是此种方法的又一大制约。

    基于深度学习的方法

    NN/CNN-CRF模型

    《Natural language processing (almost) from scratch》 是较早使用神经网络进行NER的代表工作之一。在这篇论文中,作者提出了窗口方法与句子方法两种网络结构来进行NER。这两种结构的主要区别就在于窗口方法仅使用当前预测词的上下文窗口进行输入,然后使用传统的NN结构;而句子方法是以整个句子作为当前预测词的输入,加入了句子中相对位置特征来区分句子中的每个词,然后使用了一层卷积神经网络CNN结构。
    在这里插入图片描述

    在训练阶段,作者也给出了两种目标函数:

    • 词级别的对数似然,即使用softmax来预测标签概率,当成是一个传统分类问题
    • 句子级别的对数似然,其实就是考虑到CRF模型在序列标注问题中的优势,将标签转移得分加入到目标函数中。后来许多相关工作把这个思想称为结合了一层CRF层,所以我这里称为NN/CNN-CRF模型。
      在这里插入图片描述

    在作者的实验中,上述提到的NN和CNN结构效果基本一致,但是句子级别似然函数即加入CRF层在NER的效果上有明显提高。

    RNN-CRF模型

    借鉴上面的CRF思路,出现了一系列使用RNN结构并结合CRF层进行NER的工作。模型结构如下图:
    在这里插入图片描述
    它主要有Embedding层(主要有词向量,字符向量以及一些额外特征),双向RNN层,tanh隐层以及最后的CRF层构成。它与之前NN/CNN-CRF的主要区别就是他使用的是双向RNN代替了NN/CNN。这里RNN常用LSTM或者GRU。实验结果表明RNN-CRF获得了更好的效果,已经达到或者超过了基于丰富特征的CRF模型,成为目前基于深度学习的NER方法中的最主流模型。在特征方面,该模型继承了深度学习方法的优势,无需特征工程,使用词向量以及字符向量就可以达到很好的效果,如果有高质量的词典特征,能够进一步获得提高。

    近期工作

    Attention-based

    《Attending to Characters in Neural Sequence Labeling Models》 该论文还是在RNN-CRF模型结构基础上,重点改进了词向量与字符向量的拼接。使用attention机制将原始的字符向量和词向量拼接改进为了权重求和,使用两层传统神经网络隐层来学习attention的权值,这样就使得模型可以动态地利用词向量和字符向量信息。实验结果表明比原始的拼接方法效果更好。
    在这里插入图片描述
    另一篇论文《Phonologically aware neural model for named entity recognition in low resource transfer settings》,在原始BiLSTM-CRF模型上,加入了音韵特征,并在字符向量上使用attention机制来学习关注更有效的字符,主要改进如下图:
    在这里插入图片描述

    少量标注数据

    对于深度学习方法,一般需要大量标注数据,但是在一些领域并没有海量的标注数据。所以在基于神经网络结构方法中如何使用少量标注数据进行NER也是最近研究的重点。其中包括了迁移学习《Transfer Learning for Sequence Tagging with Hierarchical Recurrent Networks》和半监督学习。这里我提一下最近ACL2017刚录用的一篇论文《Semi-supervised sequence tagging with bidirectional language models》。该论文使用海量无标注语料库训练了一个双向神经网络语言模型,然后使用这个训练好的语言模型来获取当前要标注词的语言模型向量(LM embedding),然后将该向量作为特征加入到原始的双向RNN-CRF模型中。实验结果表明,在少量标注数据上,加入这个语言模型向量能够大幅度提高NER效果,即使在大量的标注训练数据上,加入这个语言模型向量仍能提供原始RNN-CRF模型的效果。整体模型结构如下图:
    在这里插入图片描述

    总结

    对于统计机器学习方法而言,将 NER 视作序列标注任务,利用大规模语料来学习出标注模型,从而对句子的各个位置进行标注。常用的应用到 NER 任务中的模型包括生成式模型HMM、判别式模型CRF等。比较流行的方法是特征模板 + CRF的方案。

    随着硬件能力的发展以及词的分布式表示(word embedding)的出现,神经网络成为可以有效处理许多NLP任务的模型。通过将神经网络与CRF模型相结合的NN/CNN/RNN-CRF模型成为了目前NER的神经网络领域的主流模型。基于神经网络结构的NER方法,继承了深度学习方法的优点,无需大量人工特征。只需词向量和字符向量就能达到主流水平,加入高质量的词典特征能够进一步提升效果。

    近年来,命名实体识别在多媒体索引、半监督和无监督的学习、复杂语言环境和机器翻译等方面取得大量新的研究成果。随着半监督的学习和无监督的学习方法不断被引入到这个领域,采用未标注语料集等方法将逐步解决语料库不足的问题,将会成为未来NER研究领域的热点和重点。

    在后续博客中,我会陆续更新利用HMM、CRF、神经网络+CRF的解决方案解决中文领域命名实体识别任务。请随时关注。

    参考资料

    展开全文
  • 命名实体识别

    万次阅读 2016-09-14 16:46:02
    命名实体识别(Named Entity Recognition, NER)的主要任务是识别出文本中的人名、地名等专有名称和有意义的时间、日期等数量短语加以归类。命名实体识别技术是信息抽取、信息检索、机器翻译、问答系统等多种自然...

    引言

    命名实体识别(Named Entity Recognition, NER)的主要任务是识别出文本中的人名、地名等专有名称和有意义的时间、日期等数量短语加以归类。命名实体识别技术是信息抽取、信息检索、机器翻译、问答系统等多种自然语言处理技术必不可少的组成部分。从语言分析的全过程来看,命名实体识别属于词法分析中未登录词识别的范畴。命名实体是未登录词中数量最多、识别难度最大、对分词效果影响最大的问题。根据SIGHAN(http://www.sighan.org/)Bakeoff数据评测结果,未登录词造成的分词精度损失至少比歧义大5倍以上,可见命名实体地位的重要性。

     

    针对“命名实体识别”和“Named Entity Recognition”两个关键词对

    中国知网(http://www.cnki.net)

    Google学术(http://scholar.google.com/)

    ACL  Anthology(http://www.aclweb.org/anthology/

    ICML 会议(http://machinelearning.org/icml.html

    IEEE(http://ieeexplore.iee.org

    等期刊论文数据库和会议论文集进行文献检索。

     

    命名实体识别研究历史

    国外对于命名识别研究主要包括:Bikel等最早提出了基于隐马尔科夫模型的英文命名实体识别方法,其在MUC-6测试文本集的测试结果为:英文地名、机构名和人名的识别精度分别达到了97%、94%和95%,召回率分别达到了95%、94%和94%;Liao等提出了基于条件随机场模型,采用半监督的学习算法进行命名实体识别;Ratinov等采用未标注文本训练词类模型(Word Class Model)的方法,可以有效地提高NER系统的识别效率,并针对CoNLL-2003的数据集开发出F1值达到90.8%的命名实体识别系统。中文命名实体识别也获得了广泛关注。Tsai等提出基于最大熵的混合的方法;冯元勇等提出基于单字提示特征的中文命名实体识别快速算法;郑逢强等将《知网》中的义原作为特征加入到最大熵模型中,以此来产生性能更好的模型。

     

    2004年举行的863命名实体识别评测,成绩最好的命名实体识别系统的准确率、召回率和F1值分别为81.10%,83.69%、82.83%,其中人名、地名、组织结构名各项的F1值最高分别为85.51%、82.51%、60.81%。可见中文命名实体识别评测结果比英文结果偏低,尤其中文机构名称的识别难度更大一些。

     

    研究主体

    命名实体是命名实体识别的研究主体,一般包括3大类(实体类、时间类和数字类)和7小类(人名、地名、机构名、时间、日期、货币和百分比)命名实体。实际研究中,命名实体的确切含义需要根据具体应用来确定,比如,可能需要把产品名称、旅游景点名称等作为命名实体。在面向生物命名实体信息抽取时,还包括蛋白质、基因、核糖核酸、脱氧核糖核酸、细胞等特殊生物实体。

     

    由于数量、时间、日期、货币等实体识别通常可以采用模式匹配的方式获得较好的识别效果,相比之下人名、地名、机构名较复杂,因此近年来的研究主要以这几种实体为主。同时生物领域的实体识别也比较活跃。这些实体中以机构名和生物实体识别难度最大,普遍存在嵌套和缩写的识别问题。从研究的发展趋势上看,由原来的单独针对人名、地名等进行识别发展到开始采用统一的方法同时进行各类中文命名实体的识别,而且识别效果也得到了提高,其中部分研究成果发表在ACL(http://www.aclweb.org/)年度会议以及COLING(http://nlp.shef.ac.uk/iccl/)、SIGHAN等国际会议上。

     

    这种方法虽然考虑了人名、地名和机构名的共同特点,能够有效地解决多种命名实体间的差异性,制约了整体的识别性能。

     

    命名实体识别特点及难点

    评判一个命名实体是否被正确识别包括两个方面:实体的边界是否正确;实体的类型是否标注正确。主要错误类型包括文本正确,类型可能错误;反之,文本边界错误,而其包含的主要实体词和词类标记可能正确。

    和英语相比,汉语命名实体识别任务更加复杂,由于分词等因素的影响难度较大,其难点主要表现在如下几个方面:

    (1)      命名实体类型多样,数量众多,不断有新的命名实体涌现,如新的人名、地名等,难以建立大而全的姓氏库、名字库、地址库等数据库。

    (2)      命名实体构成结构比较复杂,并且某些类型的命名实体词的长度没有一定的限制,不同的实体有不同的结构,比如组织名存在大量的嵌套、别名、缩略词等问题,没有严格的规律可以遵循;人名中也存在比较长的少数民族人名或翻译过来的外国人名,没有统一的构词规范。因此,这类命名实体识别的召回率相对偏低。

    (3)      在不同领域、场景下,命名实体的外延有差异,存在分类模糊的问题。不同命名实体之间界限不清晰,人名也经常出现在地名和组织名称中,存在大量的交叉和互相包含现象,而且部分命名实体常常容易与普通词混淆,影响识别效率。在个体户等商户中,组织名称中也存在大量的人名、地名、数字的现象,要正确标注这些命名实体类型,通常要涉及上下文语义层面的分析,这些都给命名实体的识别带来困难。

    (4)      在不同的文化、领域、背景下,命名实体的外延有差异。对命名实体的定界和类型确定,目前还没有形成共同遵循的严格的命名规范。

    (5)      命名实体识别过程常常要与中文分词、浅层语法分析等过程相结合,分词、语法分析系统的可靠性也直接决定命名实体识别的有效性,使得中文命名实体识别更加困难。

     

    基于规则和词典的方法

    基于规则的方法多采用语言学专家手工构造规则模板,选用特征包括统计信息、标点符号、关键字、指示词和方向词、位置词(如尾字)、中心词等方法,以模式和字符串相匹配为主要手段,这类系统大多依赖于知识库和词典的建立。

     

    基于统计的方法

    基于统计的方法利用人工标注的语料进行训练,标注语料时不需要广博的语言学知识,并且可以在较短时间内完成。基于统计机器学习的方法主要包括:隐马尔科夫模型(Hidden Markov Model, HMM)、最大熵(MaximunmEntropy, ME)、支持向量机(Support Vector Machine, SVM)、条件随机场(ConditionalRandom Fields, CRF)等。

     

    在这4种学习方法中,最大熵模型结构比较紧凑、具有较好的通用性,主要缺点是训练时间复杂性非常高,有时甚至导致训练代价难以承受,另外由于需要明确的归一化计算,导致开销比较大。而条件随机场为命名实体识别提供了一个特征灵活、全局最优的标注框架,但同时存在收敛速度慢、训练时间长的问题。一般说来,最大熵和支持向量机在正确率上要比隐马尔科夫模型高一些,但是隐马尔科夫模型在训练和识别的速度要快一些,主要是由于在利用Viterbi算法求解命名实体类别序列的效率比较高。隐马尔科夫模型更适用于一些对实时性有要求以及像信息检索这样需要处理大量文本的应用,如短文本命名实体识别。

     

    基于统计的方法对语料库的依赖比较大,而可以用来建设和评估命名实体识别系统的大规模通用语料库又比较少。SIGHAN Bakeoff 08测评中,中文命名实体识别使用的语料主要包括:香港城市大学语料库(1 772 202 字,训练集)、微软亚洲研究院语料库(1 089 050 字,训练集)、北京大学语料库(1 833 177 字,训练集)。这些语料库比较小、因公不广泛,无法应用于大规模的NER系统。因此,目前的问题是如何最大限度地使用这些有限的语料库。

     

    混合方法

    自然语言处理并不完全是一个随机过程,单独使用基于统计的方法使状态搜索空间非常庞大,必须借助规则知识提前进行过滤修剪处理。目前几乎没有单纯使用统计模型而不使用规则知识的命名实体识别系统,在很多情况下是使用混合方法:

    (1)      统计学习方法之间或内部层叠融合,如俞鸿魁等采用层叠隐马尔科夫模型对中文进行分词。

    (2)      规则、词典和机器学习方法之间的融合,其核心是融合方法技术。在基于统计的学习方法中引入部分规则,将机器学习和人工知识结合起来。

    (3)      将各类模型、算法结合起来,将前一级模型的结果作为下一级的训练数据,并用这些训练数据对模型进行训练,得到下一级模型。这种方法在具体实现过程中需要考虑怎样高效地将两种方法结合起来,采用什么样的融合技术。由于命名实体识别在很大程度上依赖于分类技术,在分类方面可以采用的融合技术主要包括如Voting,XVoting, GradingVal,Grading等。

     

    Lin等将最大熵方法与基于词典匹配和规则模式的后处理相结合,前一阶段运行ME方法识别文本中的生物实体,第一阶段机器学习方法可能产生一定程度的边界识别错误和语义分类错误;通过第二阶段基于词典和规则模式匹配的后处理,修正实体边界并改进实体语义分类结果,提高了系统的准确率与召回率。

     

    评测组织

    目前,比较有影响力的评测会议主要有信息理解研讨会(Message Understanding Conference, MUC)、多语种实体评价任务(MultilingualEntity Task Evaluation, MET)、自动内容抽取(Automatic Content Extraction, ACE)、文本理解会议(DocumentUnderstanding Conference, DUG)、SIGHAN的Bakeoff评测等。

    在MUC-7之后,MUC被由NIST主导的ACE评测取代。



























    展开全文
  • 命名实体识别种方法

    万次阅读 2017-09-04 14:04:37
    分别使用NLTK和Stanford的命名实体识别对英文文本进行处理以及方法的比较

    一 、什么是命名实体识别?

    命名实体识别(Named Entity Recognition,简称NER),又称作“专名识别”,是指识别文本中具有特定意义的实体,主要包括人名、地名、机构名、专有名词等。通常包括两部分:(1)实体边界识别;(2) 确定实体类别(人名、地名、机构名或其他)。

    二 、基于NLTK的命名实体识别:

    NLTK:由宾夕法尼亚大学计算机和信息科学使用python语言实现的一种自然语言工具包,其收集的大量公开数据集、模型上提供了全面、易用的口,涵盖了分词、

    词性标注(Part-Of-Speech tag, POS-tag)、命名实体识别(Named Entity Recognition, NER)、句法分析(Syntactic Parse)等各项NLP领域的功能。使用前需要先

    下载NLTK,下载地址为:http://pypi.python.org/pypi/nltk,安装完成后,在python环境下输入import nltk测试是否安装成功,然后输入nltk.download()下载nltk所

    需要的数据包,完成安装。

    Python代码实现(注意文件的编码格式为utf-8无BOM格式):

    # -*- coding: utf-8 -*-
    import sys
    reload(sys)
    sys.setdefaultencoding('utf8')    #让cmd识别正确的编码
    import nltk
    newfile = open('news.txt')
    text = newfile.read()  #读取文件
    tokens = nltk.word_tokenize(text)  #分词
    tagged = nltk.pos_tag(tokens)  #词性标注
    entities = nltk.chunk.ne_chunk(tagged)  #命名实体识别
    a1=str(entities) #将文件转换为字符串
    file_object = open('out.txt', 'w')  
    file_object.write(a1)   #写入到文件中
    file_object.close( )
    print entities

    具体的方法可参考NLTK官网介绍:http://www.nltk.org/,输出的结果为:

    >>> entities = nltk.chunk.ne_chunk(tagged)
    >>> entities
    Tree('S', [('At', 'IN'), ('eight', 'CD'), ("o'clock", 'JJ'),
               ('on', 'IN'), ('Thursday', 'NNP'), ('morning', 'NN'),
           Tree('PERSON', [('Arthur', 'NNP')]),
               ('did', 'VBD'), ("n't", 'RB'), ('feel', 'VB'),
               ('very', 'RB'), ('good', 'JJ'), ('.', '.')])
    当然为了方便查看,我们可以以树结构的形式把结果绘制出来:
    >>> from nltk.corpus import treebank
    >>> t = treebank.parsed_sents('wsj_0001.mrg')[0]
    >>> t.draw()

    此外,关于标注词性的解释,我们可以参考以下文章:http://blog.csdn.net/john159151/article/details/50255101

    三 、基于Stanford的NER:

    Stanford Named Entity Recognizer (NER)是斯坦福大学自然语言研究小组发布的成果之一,主页是:http://nlp.stanford.edu/software/CRF-NER.shtml。Stanford NER 是一个Java实现的命名实体识别(以下简称NER))程序。NER将文本中的实体按类标记出来,例如人名,公司名,地区,基因和蛋白质的名字等。

    NER基于一个训练而得的Model(模型可识别出 Time, Location, Organization, Person, Money, Percent, Date)七类属性,其用于训练的数据即大量人工标记好的文本,理论上用于训练的数据量越大,NER的识别效果就越好。

    因为原始的NER是基于java实现的,所以在使用Python编程之前,要确保自己电脑上已经安装了jar1.8的环境(否则会报关于Socket的错误)。

    然后我们使用Pyner使用python语言实现命名实体识别。下载地址为:https://github.com/dat/pyner

    安装Pyner:解压下载的Pyner,命令行中将工作目录切换到Pyner文件夹下, 输入命令 :python setup.py install 完成安装.

    接下来,还需要下载StanfordNER工具包,下载地址为:http://nlp.stanford.edu/software/stanford-ner-2014-01-04.zip,然后在解压后的目录打开cmd命令窗体,执行,java -mx1000m -cp stanford-ner.jar edu.stanford.nlp.ie.NERServer -loadClassifier classifiers/english.muc.7class.distsim.crf.ser.gz -port 8080 -outputFormat inlineXML,直到结果为:Loading classifier from classifiers/english.muc.7class.distsim.crf.ser.gz ... done [1.2 sec].

            以上操作是因为斯坦福的命名实体识别是基于java的socket写的,所以必要保证有一个窗题与我们执行的命令通信。关于java的socket编程,可以参考以下文章:http://www.cnblogs.com/rond/p/3565113.html

    最后,我们终于可以使用python编程实现NER了:

    import ner
    import sys
    import nltk
    reload(sys)
    sys.setdefaultencoding('utf8')
    newfile = open('news.txt')
    text = newfile.read()
    tagger = ner.SocketNER(host='localhost', port=8080)#socket编程
    result=tagger.get_entities(text)   #stanford实现NER
    a1=str(result)
    file_object = open('outfile.txt', 'w')
    file_object.write(a1)
    file_object.close( )
    print result

    以上是我对文本文件进行的测试,官网的案例https://github.com/dat/pyner运行结果为:

    >>> import ner
    >>> tagger = ner.SocketNER(host='localhost', port=8080)
    >>> tagger.get_entities("University of California is located in California, United States")
    {'LOCATION': ['California', 'United States'],
     'ORGANIZATION': ['University of California']}
    由此可见,stanford的命名实体识别可以更好的把地名,人名,机构名等标注出来。

    四 、两种方法的比较:

    我拿同一个文本文件用两种方法进行命名实体识别,结果如下:

    NLTK:

    Stanford:

    比较两种方式,我们可以发现,NLTK下的命名实体识别更加倾向于分词和词性标准,虽然它也会将组织名,人名,地名等标注出来,但由于它把文件中的谓语,宾语等成分也标注了出来,造成了输出文本的冗余性,不利于读者很好的识别命名实体,需要我们对文本做进一步处理。NLTK下的命名实体识别的有点时,可以使用NLTK下的treebank包将文本绘制为树形,使结果更加清晰易读。相较而言,我更加倾向于Stanford的命名实体识别,它可以把Time, Location, Organization, Person, Money, Percent, Date七类实体很清晰的标注出来,而没有多余的词性。但由于NER是基于java开发的,所以在用python实现时可能由于jar包或是路径问题出现很多bug。

    以上就是关于NLTK和stanford对英文文本的命名实体识别,关于自然语言处理中文文件,我们可以考虑jieba分词:https://www.oschina.net/p/jieba

    谢谢大家!


    展开全文
  • 一、命名实体识别 首先,我们来认识一下命名实体识别的概念。命名实体识别(Named Entities Recognition, NER)研究的命名实体一般分为3大类(实体类、时间类和数字类)和7小类(人名、地名、组织机构名、时间、...

    一、命名实体识别

    首先,我们来认识一下命名实体识别的概念。命名实体识别(Named Entities Recognition, NER)研究的命名实体一般分为3大类(实体类、时间类和数字类)和7小类(人名、地名、组织机构名、时间、日期、货币和百分比),研究的目的是将语料中的这些命名实体识别出来。主要有三种方式:

    1)基于规则的命名实体识别:依赖于手工规则的系统,结合命名实体库,对每条规则进行权重辅助,然后通过实体与规则的相符情况来进行类型判断。大多数时候,规则往往依赖具体语言领域和文本风格,难以覆盖所有的语言现象。

    2)基于统计的命名实体识别:与分词类似,目前流行的基于统计的命名实体识别方法有:隐马尔科夫模型、条件随机场模型等。主要思想是基于人工标注的语料,将命名实体识别任务作为序列标注问题来解决。该方法依赖于语料库。

    3)混合方法:自然语言处理并不完全是一个随机过程,单独使用基于统计的方法使状态搜索空间非常大,必须借助规则知识提前进行过滤修剪处理,很多情况下,命名实体识别都是使用混合方法,结合规则和统计方法。

    二、基于规则的命名实体识别

    这里我们以日期识别为例,详细讲述。假设数据需求背景为:抽取酒店预订系统中日期类的数据,这些数据是非结构化数据,会出现各种形式的日期形式。我们的目的是识别出每条数据中可能的日期信息,并转换为统一的格式输出。

    首先通过jieba分词将带有时间信息的词进行切分,然后记录连续时间信息的词,提取词性为‘m’(数字)、‘t’(时间)的词。

    然后检查日期的有效性,最后将提取到的日期转换为统一格式。具体代码如下:

    # coding=utf-8
    import datetime
    import re
    import jieba.posseg as psg
    from  dateutil import parser                 #就是与日期相关库里的一个日期解析器 能够将字符串 转换为日期格式
    
    UTIL_CN_NUM = {
        '零': 0, '一': 1, '二': 2, '两': 2, '三': 3, '四': 4,
        '五': 5, '六': 6, '七': 7, '八': 8, '九': 9,
        '0': 0, '1': 1, '2': 2, '3': 3, '4': 4,
        '5': 5, '6': 6, '7': 7, '8': 8, '9': 9
    }
    UTIL_CN_UNIT = {'十': 10, '百': 100, '千': 1000, '万': 10000}
    #检查抽取的日期有效性
    def check_time_valid(word):
        m = re.match("\d+$", word)
        if m:
            if len(word) <= 6:
                print(word)
                return None
        word1 = re.sub('[号|日]\d+$', '日', word)
        if word1 != word:
            return check_time_valid(word1)
        else:
            return word1
    
    def cn2dig(src):
        if src == "":
            return None
        m = re.match("\d+", src)
        if m:
            return int(m.group(0))
        rsl = 0
        unit = 1
        for item in src[::-1]:
            if item in UTIL_CN_UNIT.keys():
                unit = UTIL_CN_UNIT[item]
            elif item in UTIL_CN_NUM.keys():
                num = UTIL_CN_NUM[item]
                rsl += num * unit
            else:
                return None
        if rsl < unit:
            rsl += unit
        return rsl
    
    def year2dig(year):
        res = ''
        for item in year:
            if item in UTIL_CN_NUM.keys():
                res = res + str(UTIL_CN_NUM[item])
            else:
                res = res + item
        m = re.match("\d+", res)
        if m:
            if len(m.group(0)) == 2:
                return int(datetime.datetime.today().year/100)*100 + int(m.group(0))
            else:
                return int(m.group(0))
        else:
            return None
    
    def parse_datetime(msg):
        if msg is None or len(msg) == 0:
            return None
        try:
            dt = parser.parse(msg)
            return dt.strftime('%Y-%m-%d %H:%M:%S')
        except Exception as e:
            m = re.match(
                r"([0-9零一二两三四五六七八九十]+年)?([0-9一二两三四五六七八九十]+月)?([0-9一二两三四五六七八九十]+[号日])?([上中下午晚早]+)?([0-9零一二两三四五六七八九十百]+[点:\.时])?([0-9零一二三四五六七八九十百]+分)?([0-9零一二三四五六七八九十百]+秒)?",
                msg)
            if m.group(0):
                res = {
                    "year": m.group(1),
                    "month": m.group(2),
                    "day": m.group(3),
                    "hour": m.group(5) if m.group(5) is not None else '00',
                    "minute": m.group(6) if m.group(6) is not None else '00',
                    "second": m.group(7) if m.group(7) is not None else '00',
                }
                params = {}
                #print(m.group())
                for name in res:
                    if res[name] is not None and len(res[name]) != 0:
                        tmp = None
                        if name == 'year':
                            tmp = year2dig(res[name][:-1])
                        else:
                            tmp = cn2dig(res[name][:-1])
                        if tmp is not None:
                            params[name] = int(tmp)
                target_date = datetime .datetime.today().replace(**params)          #替换给定日期,但不改变原日期
                is_pm = m.group(4)
                if is_pm is not None:
                    if is_pm == u'下午' or is_pm == u'晚上' or is_pm == '中午':
                        hour = target_date.time().hour
                        if hour < 12:
                            target_date = target_date.replace(hour=hour + 12)
                            #print(target_date)
                return target_date.strftime('%Y-%m-%d %H:%M:%S')
            #return m.group(0)                      #group() 同group(0)就是匹配正则表达式整体结果, group(1) 列出第一个括号匹配部分,group(2) 列出第二个括号匹配部分,group(3) 列出第三个括号匹配部分
            else:
                return None
    
    def time_extract(text):
        time_res = []
        word = ''
        keyDate = {'今天': 0, '明天':1, '后天': 2}
        for k, v in psg.cut(text):                 #k是切分的词,v是对应词的词性
            if k in keyDate:
                if word != '':
                    time_res.append(word)
                word = (datetime.datetime.today() + datetime.timedelta(days=keyDate.get(k, 0))).strftime('%Y{y}%m{m}%d{d}') .format(y='年',m='月',d='日')
            elif word != '':
                if v in ['m', 't']:
                    word = word + k
                else:
                    time_res.append(word)
                    word = ''
            elif v in ['m', 't']:
                word = k
        if word != '':
            time_res.append(word)
        result = list(filter(lambda x: x is not None, [check_time_valid(w) for w in time_res]))
        final_res = [parse_datetime(w) for w in result]
        return [x for x in final_res if x is not None]
    
    
    
    if __name__ =='__main__':
        text1='我要预定明天下午3点到后天下午的6个房间。'
        text2='我要预定5月1号至五月5号的房间'
        time_deal=time_extract(text1)
        print(text1,':',time_deal )
        time_deal2 = time_extract(text2)
        print(text2, ':', time_deal2)
    

    最后输出结果为:

    我要预定明天下午3点到后天下午的6个房间。 : ['2020-04-10 15:00:00', '2020-04-11 12:00:00']
    我要预定5月1号至五月5号的房间 : ['2020-05-01 00:00:00', '2020-05-05 00:00:00']

    展开全文
  • 基于BERT预训练的中文命名实体识别TensorFlow实现

    万次阅读 多人点赞 2019-01-03 11:58:25
    BERT-BiLSMT-CRF-NER Tensorflow solution of ...使用谷歌的BERT模型在BLSTM-CRF模型上进行预训练用于中文命名实体识别的Tensorflow代码’ 代码已经托管到GitHub 代码传送门 大家可以去clone 下来亲自体验一下! g...
  • 命名实体识别——日期识别

    千次阅读 2018-07-26 15:36:32
    命名实体识别 其目的是识别语料中的人名、地名、组织结构名等命名实体,由于这些命名实体在不断地更新,很难在词典中全部列出,所以就对这些词的识别在词汇形态处理任务中单独处理,也就是NER技术。 而命名实体...
  • 第二十六章 命名实体识别和实体消歧 1 命名实体识别概论 PART1 什么是命名实体识别 PART2 命名识别识别的应用 PART3 简历中抽取关键信息 2 命名实体识别不同方法 PART1 实体识别方法 基于规则的方法 基于...
  • 中文命名实体识别NER详解

    千次阅读 2019-09-21 14:58:06
    中文命名实体识别是在自然语言处理领域有着具足轻重的地位,因为在很多应用中,我们一定要提取出我们话术中的实体,所以说命名实体识别是非常重要的。一般来说,现在网上有很多NER的开源库,我们通过调用API就可以...
  • 命名实体识别作为序列标注类的典型任务,其使用场景特别广泛。本项目基于PyTorch搭建HMM、CRF、BiLSTM、BiLSTM+CRF及BERT模型,实现中文命名识别任务,部分内容参考了https://zhuanlan.zhihu.com/p/61227299,全部...
  • 命名实体识别总结

    千次阅读 2019-09-27 07:28:51
    一、什么是命名实体识别  命名实体识别(NER)是指在文本中识别出特殊对象,这些对象的语义类别通常在识别前被预定义好,预定义类别如人、地址、组织等。命名实体识别不仅仅是独立的信息抽取任务,它在许多大型nlp...
  • NLP之中文命名实体识别

    万次阅读 2018-09-25 18:45:47
    在MUC-6中首次使用了命名实体(named entity)这一术语,由于当时关注的焦点是信息抽取(information extraction)问题,即从报章等非结构化文本中抽取关于公司...命名实体识别(Named EntitiesRecognition,NER),...
  • 一文了解命名实体识别

    千次阅读 2020-09-04 20:25:53
    导读:从1991年开始,命名实体识别逐渐开始走进人们的视野,在各评测会议...1991年Rau等学者首次提出了命名实体识别任务,但命名实体(named entity,NE)作为一明确的概念和研究对象,是在1995年11月的第六届MUC...
  • 本文主要介绍一些命名实体识别(Name Entity Recognition,NER)相关的基本概念、发展历程和最新的研究进展,并着重介绍基于CRF的命名实体识别原理及实现。后续也会以BiLSTM-CRF、BERT-BiLSTM-CRF为例进行展开。 1....
  • 命名实体识别实战(BERT)

    千次阅读 2021-01-05 09:27:06
    命名实体识别实例(BERT)一、背景二、数据预处理三、训练模型四、对预测结果进行转换 一、背景 本实例是当时参加第八届泰迪杯数据挖掘挑战赛C题的一部分,该赛题是智慧政务方面的,主要是根据群众的留言来了解民意 ...
  • 命名实体识别以及词性自动标注

    千次阅读 2018-07-09 12:04:26
    一、命名实体识别大数据风靡的今天,不从里面挖出点有用的信息都不好意思见人,人工智能号称跨过奇点,统霸世界,从一句话里都识别不出一命名实体?不会的,让我们大话自然语言处理的囊中取物,看看怎么样能让...
  • 命名实体识别研究综述

    万次阅读 2019-04-15 00:35:18
    命名实体识别研究进展综述 1 引 言 命名实体识别(Named Entity Recognition,NER)的主要任务是识别出文本中的人名、地名等专有名称和有意义的时间、日期等数量短语并加以归类[1]。命名实体识别技术是信息抽取、信息...
  • 中文电子病例命名实体识别项目

    万次阅读 多人点赞 2018-11-28 12:10:18
    Medical Named Entity Recognition implement using bi-directional lstm and crf model with char embedding.CCKS2018中文电子病例命名实体识别项目,主要实现使用了基于字向量的四层双向LSTM与CRF模型的网络....
  • NLP 命名实体识别 NER

    2019-08-07 16:03:01
    文章目录1、命名实体识别简介1.1 定义1.2 NER标注方法1.3 难点1.4 发展趋势及主要方法1)基于词典规则匹配的方法2)基于特征的机器学习方式3)基于深度学习的方法2、主要方法2.1 CRF2.2 BiLSTM+CRF 对这几天看到的...
  • NLP基础-命名实体识别(一)基于规则

    千次阅读 2019-06-13 11:19:11
    与自动分词,词性标注一样,命名实体识别也是自然语言处理中的一基础任务,其目的是识别语料中的人名、地名、组织机构名等命名实体。 基于规则的通常有种方法 第一是基于正则表达式的匹配,第二可以通过...
  • 命名实体识别命名实体识别任务是NLP中的一个基础任务。主要是从一句话中识别出命名实体。比如 姚明在NBA打球 从这句话中应该可以识别出姚明(人), NBA(组织)这样两个实体。 常见的方法是对字或者词打上标签。B-...
  • 知识图谱之命名实体识别

    千次阅读 2020-01-05 17:49:24
    本片博文我将讲解两个部分,第一部分讲命名实体识别的发展史,这中间会涉及到整个技术的成熟历程,第二部分讲主流的命名实体识别技术的实现细节。 ...
  • BiLSTM+CRF(二)命名实体识别

    千次阅读 2018-12-03 21:15:11
    前言 前一篇博客里面,我们已经提到了如何构建一双向的LSTM网络,并在原来单层的RNN的基础上,修改少数几行代码即可实现。...这篇博客,我们就来看看如何通过BiLSTM+CRF来进行命名实体识别的任务...
  • 中文命名实体识别

    千次阅读 2014-01-03 10:15:39
    命名实体识别(Named Entity Recognition, NER),又称作“专名识别”,主要任务是识别出文本中的人名、地名等专有名称和有意义的时间、日期等数量短语并加以归类。对很多文本挖掘任务来说,命名实体识别系统是重要的...
  • 融入词汇信息的基于字的命名实体识别方法 基于词的中文命名实体识别方法,前期存在不可避免的分词错误,会导致后期命名实体识别过程中 实体边界识别错误,进而导致方法的性能指标下降。 而基于字的命名实体识别方法...
  • 命名实体识别方法汇总

    千次阅读 2017-10-20 17:50:53
    命名实体识别(Named EntitiesRecognition, NER)是自然语言处理(Natural LanguageProcessing, NLP)的一基础任务。其目的是识别语料中人名、地名、组织机构名等命名实体。由于这些命名实体数量不断增加,通常不可能...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 39,978
精华内容 15,991
关键字:

命名实体识别两个实体