Day14:使用斯坦福 NER 软件包实现你自己的命名实体识别器(Named Entity Recognition,NER)

本文涉及的产品
NLP自然语言处理_基础版,每接口每天50万次
NLP自然语言处理_高级版,每接口累计50万次
NLP 自学习平台,3个模型定制额度 1个月
简介: 我并不是一个机器学习(Machine Learning)、自然语言处理(Natural Text Processing,NLP)等的狂热者,但我总会想到一些需要用到它们的主意。我们今天在这篇博文中要实现的目标是:利用 Twitter 数据建立一个实时的职位搜索。每个单独的搜索结果要包括提供职位的公司名称、工作的地点、去公司应聘时联系的人。这需要我们从 个人(Person)、地点(Location)、组织(Organisation)三方面去分析每一条推(tweet)。这类问题被归为命名实体识别(Named Entity Recognition,NER)问题。

编者注:我们发现了有趣的一系列文章《30天学习30种新技术》,正在翻译中,一天一篇更新,年终礼包。下面是第 14 天的内容。


我并不是一个机器学习(Machine Learning)、自然语言处理(Natural Text Processing,NLP)等的狂热者,但我总会想到一些需要用到它们的主意。我们今天在这篇博文中要实现的目标是:利用 Twitter 数据建立一个实时的职位搜索。每个单独的搜索结果要包括提供职位的公司名称、工作的地点、去公司应聘时联系的人。这需要我们从 个人(Person)、地点(Location)、组织(Organisation)三方面去分析每一条推(tweet)。这类问题被归为命名实体识别(Named Entity Recognition,NER)问题。

根据维基百科的资料,命名实体识别是信息提取(Information Extraction)的一个子任务,它把文字的原子元素(Atomic Element)定位和分类好,然后输出为固定格式的目录,例如: 人名、组织、位置、时间的表示、数量、货币值、百分比等。


为了说的更明白,我们来举个例子。假设我们有下面这条推:

image.png

一个普通人可以轻易地分辨出一个名为 PSI Pax 的组织在 Baltimore 有个空缺的职位。但是我们怎么用编程的方式来完成这个识别呢? 最简单的办法是维护一个包含所有组织名称、地点的列表,然后对这个列表进行搜索。然而,这种做法的可扩展性太差了。

今天,在这篇博文中,我会描述如何用斯坦福 NER(Stanford NER) 软件包去设置我们自己的 NER 服务器。


什么是 斯坦福 NER?

斯坦福 NER 命名实体识别(Named Entity Recognizer,NER)的 Java 实现。 NER 标识一段文字中的一系列名词,例如人名、公司名,又或者基因名、蛋白质名。


前期准备

  1. 一些基本的 Java 知识是需要的。在你的操作系统上安装最新版本的 JDK,你可以安装 OpenJDK 或者 Oracle JDK 7。OpenShift 支持 OpenJDK 6 和 7.
  2. 从官网中下载斯坦福 NER 软件包
  3. 注册一个 OpenShift 账户。这是完全免费的,而且红帽(Red Hat)会给每个用户三个免费的 Gears,在 Gears 上你可以运行你的程序。在这篇文章写的时候,OpenShift 会为每个用户分配 1.5GB 的内存和 3GB 的硬盘空间。
  4. 在本机上,安装 rhc 客户端工具。rhc 是一个 ruby gem,所以你需要机子上安装好 ruby 1.8.7 及以上的 ruby。要安装 rhc,输入:

sudo gem install rhc


更新 rhc 到最新版本,执行:

sudo gem updatge rhc

如果需要阅读额外的安装 rhc 命令行工具时的帮助文件,可以浏览:https://openshift.redhat.com/community/developers/rhc-client-tools-install

5.使用 rhc setup 命令设置好 OpenShift 账户,这个命令会为你创建一个命名空间,然后上传你的 ssh keys 到 OpenShift 服务器上。


第一步:创建一个 JBoss EAP 应用

我们现在开始创建这个演示应用。这个应用的名称是 nerdemo

rhc create-app nerdemo jbosseap

如果你可以访问媒介齿轮(Medium Gears),你可以使用下面的命令:

$ rhc create-app nerdemo jbosseap -g medium

它会为我们创建一个应用容器,叫做 Gear,会自动设置好需要的 SELinux/cgroup 配置。OpenShift 也会为我们建立一个私密的 git 仓库,然后可克隆这个仓库到本地系统上。最后,OpenShift 还会部署一个连接外面的 DNS。部署的应用可以通过链接: http://linkbin-domain-name.rhcloud.com/ 来访问。把领域换成自己的 OpenShit 领域(有时候叫 命令空间)


第二步:增加 Maven 依赖

在 pom.xml 文件中,增加一下依赖:

<dependency>

   <groupId>edu.stanford.nlpgroupId>

   <artifactId>stanford-corenlpartifactId>

   <version>3.2.0version>

dependency>

然后,通过更新 pom.xml 文件中的一些属性把 Maven 项目更新到 Java 7

compiler.source>1.7compiler.source>

compiler.target>1.7compiler.target>

现在,通过 右击 > Maven > 更新项目 更新 Maven


第三步:开启 CDI

我们会使用 CDI 来进行依赖项注入(Dependency Injection)。CDI(Context and Dependency Injection)是 Java EE 6 的一个特性,它允许在 Java EE 6 项目中的依赖项注入。CDI 为 Java EE 定义一个类型安全(type-safe) 的 依赖项注入机制。几乎任何 POJO 可以作为 CDI 豆(bean)那样被注入。

在 src/main/webapp/WEB-INF 目录下,创建一个名为 beans.xml 的 xml 文件。用下面的内容代替 beans.xml 的内容:

<beansxmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">

beans>


第四步:应用程序作用域分类器的豆(Application Scoped Classifier Bean)

现在,我们创建一个应用程序作用域的豆(bean),这个豆会创建 CRFClassifier 类的实例。这个分类器用于检测文字中的名字、地点和组织

package com.nerdemo;

import javax.annotation.PostConstruct;

import javax.enterprise.context.ApplicationScoped;

import javax.enterprise.inject.Produces;

import javax.inject.Named;

import edu.stanford.nlp.ie.crf.CRFClassifier;

import edu.stanford.nlp.ling.CoreLabel;

@ApplicationScoped

publicclassClassifierConfig {

   privateString serializedClassifier = "classifiers/english.all.3class.distsim.crf.ser.gz";

   private CRFClassifier<CoreLabel> classifier;

   @PostConstruct

   publicvoidpostConstruct() {

       CRFClassifier<CoreLabel> classifier = CRFClassifier.getClassifierNoExceptions(serializedClassifier);

       this.classifier = classifier;

   }

   @Produces

   @Named

   public CRFClassifier<CoreLabel> classifier() {

       return classifier;

   }

}

从下载的斯坦福 NER 软件包中复制 english.all.3class.distsim.crf.ser.gz 分类器到 src/main/resources/classifiers 目录下。


第五步:开启 AX-RS

为了开启 AX-RS,创建一个扩展 javax.ws.rs.core.Application 的类,然后用下面 javax.ws.rs.ApplicationPath 的标记法标记应用程序的路径:

package com.nerdemo;

import javax.ws.rs.ApplicationPath;

import javax.ws.rs.core.Application;

@ApplicationPath("/api/v1")

public classJaxrsInitializerextends Application{

}


第六步:创建 ClassifyRestResource 类

现在我们要创建 ClassifyRestResource 类,它返回一个 NER 结果。创建一个新的 ClassifyRestResource 类,然后用下面代码代替它:

package com.nerdemo;

import java.util.ArrayList;

import java.util.List;

import javax.inject.Inject;

import javax.ws.rs.GET;

import javax.ws.rs.Path;

import javax.ws.rs.PathParam;

import javax.ws.rs.Produces;

import javax.ws.rs.core.MediaType;

import edu.stanford.nlp.ie.crf.CRFClassifier;

import edu.stanford.nlp.ling.CoreAnnotations;

import edu.stanford.nlp.ling.CoreLabel;

@Path("/classify")

publicclassClassifierRestResource {

   @Inject

   private CRFClassifier classifier;

   @GET

   @Path(value = "/{text}")

   @Produces(value = MediaType.APPLICATION_JSON)

   public List findNer(@PathParam("text") String text) {

       List> classify = classifier.classify(text);

       List results = newArrayList<>();

       for (List coreLabels : classify) {

           for (CoreLabel coreLabel : coreLabels) {

               Stringword= coreLabel.word();

               Stringanswer= coreLabel.get(CoreAnnotations.AnswerAnnotation.class);

               if(!"O".equals(answer)){

                   results.add(newResult(word, answer));

               }

           }

       }

       return results;

   }

}


部署到 OpenShift

最后,部署所做的改变到 OpenShift:

$ git add .

$ git commit -am "NER demo app"

$ git push


当代码成功部署之后,我们可以通过访问 http://nerdemo-{domain-name}.rhcloud.com 看到应用运行。我的示例应用运行在: http://nerdemo-t20.rhcloud.com

现在,发送一个请求: http://nerdemo-t20.rhcloud.com/api/v1/classify/Microsoft%20SCCM%20Windows%20Server%202012%20Web%20Development%20Expert%20(SME3)%20at%20PSI%20Pax%20(Baltimore,%20MD)

然后,你就会得到一个 JSON 格式的结果:

[

{"word":"Microsoft","answer":"ORGANIZATION"},

{"word":"PSI","answer":"ORGANIZATION"},

{"word":"Pax","answer":"ORGANIZATION"},

{"word":"Baltimore","answer":"LOCATION"}

]


这就是今天的内容了,保持反馈!


接下来


相关文章
|
自然语言处理 索引 算法
HanLP分词命名实体提取详解
文本挖掘是抽取有效、新颖、有用、可理解的、散布在文本文件中的有价值知识,并且利用这些知识更好地组织信息的过程。对于文本来说,由于语言组织形式各异,表达方式多样,文本里面提到的很多要素,如人名、手机号、组织名、地名等都称之为实体。
7446 0
|
1月前
|
机器学习/深度学习 自然语言处理 监控
命名实体识别(Named Entity Recognition, NER)
命名实体识别(Named Entity Recognition, NER)
|
2月前
|
存储 JSON 自然语言处理
数据标注工具 doccano | 命名实体识别(Named Entity Recognition,简称NER)
数据标注工具 doccano | 命名实体识别(Named Entity Recognition,简称NER)
36 1
|
2月前
|
自然语言处理 算法 Windows
HanLP — 命名实体识别
HanLP — 命名实体识别
42 1
|
2月前
|
自然语言处理 BI 数据处理
自然语言处理 Paddle NLP - 基于预训练模型完成实体关系抽取
自然语言处理 Paddle NLP - 基于预训练模型完成实体关系抽取
61 1
|
5月前
|
自然语言处理 安全 算法
【ACL 2023-NER注入到PLM】基于上下文学习的命名实体识别 Learning In-context Learning for Named Entity Recognition
【ACL 2023-NER注入到PLM】基于上下文学习的命名实体识别 Learning In-context Learning for Named Entity Recognition
141 0
|
5月前
|
JSON 自然语言处理 数据挖掘
【ACL 2023-NER注入到PLM】数据集+实验解读:基于上下文学习的命名实体识别 Learning In-context Learning for Named Entity Recognitio
【ACL 2023-NER注入到PLM】数据集+实验解读:基于上下文学习的命名实体识别 Learning In-context Learning for Named Entity Recognitio
66 0
|
自然语言处理 数据可视化 API
ESRE 系列(二):如何部署自然语言处理 (NLP):命名实体识别 (NER) 示例
本文采用示例讲解的方式,介绍使用一个命名实体识别 (NER) NLP 模型来定位和提取非结构化文本字段中预定义类别的实体。我们将通过一个公开可用的模型向您展示如何完成以下几种操作:部署模型到 Elasticsearch 中,利用 new _infer API 查找文本中的命名实体,以及在 Ingest 管道中使用 NER 模型,在文档被采集到 Elasticsearch 中时提取实体。
18198 12
ESRE 系列(二):如何部署自然语言处理 (NLP):命名实体识别 (NER) 示例
|
自然语言处理 数据处理
浅析命名实体识别(NER)的三种序列标注方法
简述序列标注 序列标注(Sequence Tagging)是NLP中最基础的任务,应用十分广泛,如分词、词性标注(POS tagging)、命名实体识别(Named Entity Recognition,NER)、关键词抽取、语义角色标注(Semantic Role Labeling)、槽位抽取(Slot Filling)等实质上都属于序列标注的范畴。
|
机器学习/深度学习 人工智能 自然语言处理
深度学习应用篇-自然语言处理-命名实体识别[9]:BiLSTM+CRF实现命名实体识别、实体、关系、属性抽取实战项目合集(含智能标注)
深度学习应用篇-自然语言处理-命名实体识别[9]:BiLSTM+CRF实现命名实体识别、实体、关系、属性抽取实战项目合集(含智能标注)
深度学习应用篇-自然语言处理-命名实体识别[9]:BiLSTM+CRF实现命名实体识别、实体、关系、属性抽取实战项目合集(含智能标注)