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

简介: 我并不是一个机器学习(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"}

]


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


接下来


相关文章
|
9天前
|
自然语言处理 算法 数据可视化
R语言中的LDA模型:对文本数据进行主题模型topic modeling分析
R语言中的LDA模型:对文本数据进行主题模型topic modeling分析
10 0
|
8月前
|
自然语言处理 数据可视化 API
ESRE 系列(二):如何部署自然语言处理 (NLP):命名实体识别 (NER) 示例
本文采用示例讲解的方式,介绍使用一个命名实体识别 (NER) NLP 模型来定位和提取非结构化文本字段中预定义类别的实体。我们将通过一个公开可用的模型向您展示如何完成以下几种操作:部署模型到 Elasticsearch 中,利用 new _infer API 查找文本中的命名实体,以及在 Ingest 管道中使用 NER 模型,在文档被采集到 Elasticsearch 中时提取实体。
17997 12
ESRE 系列(二):如何部署自然语言处理 (NLP):命名实体识别 (NER) 示例
|
10月前
|
机器学习/深度学习 人工智能 自然语言处理
论文解读系列| 04:【NER】FLAT模型详解
FLAT也是一种将词汇信息融入character-based模型的解决方案。有2个创新点(1)将lattice结构转为由spans组成的平铺结构,每个span可以是字符或者词及其在原始lattice结构中的位置;(2)基于Transformer设计了一种巧妙position encoding来充分利用lattice结构信息,从而无损地引入词汇信息。
|
自然语言处理 数据处理
浅析命名实体识别(NER)的三种序列标注方法
简述序列标注 序列标注(Sequence Tagging)是NLP中最基础的任务,应用十分广泛,如分词、词性标注(POS tagging)、命名实体识别(Named Entity Recognition,NER)、关键词抽取、语义角色标注(Semantic Role Labeling)、槽位抽取(Slot Filling)等实质上都属于序列标注的范畴。
|
10月前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习应用篇-自然语言处理-命名实体识别[9]:BiLSTM+CRF实现命名实体识别、实体、关系、属性抽取实战项目合集(含智能标注)
深度学习应用篇-自然语言处理-命名实体识别[9]:BiLSTM+CRF实现命名实体识别、实体、关系、属性抽取实战项目合集(含智能标注)
深度学习应用篇-自然语言处理-命名实体识别[9]:BiLSTM+CRF实现命名实体识别、实体、关系、属性抽取实战项目合集(含智能标注)
|
11月前
|
算法 自动驾驶 数据可视化
计算机视觉论文速递(六)GANet: A Keypoint-based Global Association Network for Lane Detection 基于关键点建模的全局关联网络
 在CVPR 2022上,商汤智能汽车-创新研发中心团队提出一种新的基于关键点建模的车道线检测范式,即全局关联网络(GANet),通过直接回归车道线关键点到车道线起始点的偏移,来完成对车道线关键点的并行聚合,从而实现高效且准确的车道线检测。除此以外,本文还提出一个车道线感知的特征增强模块,以增强车道线的局部关键点关联,提升车道线局部连续性。本文所提方法在多个公开数据集上均超越已有方法,取得了良好的精度-速度均衡。
215 0
|
机器学习/深度学习 自然语言处理 算法
基于python BiLSTM-CRF的命名实体识别 附完整代码
基于python BiLSTM-CRF的命名实体识别 附完整代码
392 0
基于python BiLSTM-CRF的命名实体识别 附完整代码
|
机器学习/深度学习 自然语言处理 算法
基于Bi-LSTM与CRF实现中文命名实体识别任务
基于Bi-LSTM与CRF实现中文命名实体识别任务
462 0
基于Bi-LSTM与CRF实现中文命名实体识别任务
|
人工智能 自然语言处理 Shell
【DSW Gallery】基于EasyNLP的序列标注(命名实体识别)
EasyNLP提供多种模型的训练及预测功能,旨在帮助自然语言开发者方便快捷地构建模型并应用于生产。本文以序列标注(命名实体识别)为例,为您介绍如何在PAI-DSW中使用EasyNLP。
【DSW Gallery】基于EasyNLP的序列标注(命名实体识别)
|
自然语言处理 算法 Linux
实体识别(2) -命名实体识别实践CRF
完整代码 https://www.heywhale.com/home/competition/6216f74572960d0017d5e691/content/
304 0
实体识别(2) -命名实体识别实践CRF