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

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

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

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

为了说的更明白,咱们来举个例子。假设咱们有下面这条推:
请输入图片描述
一个普通人能够轻易地分辨出一个名为 PSI Pax 的组织在 Baltimore 有个空缺的职位。可是咱们怎么用编程的方式来完成这个识别呢? 最简单的办法是维护一个包含全部组织名称、地点的列表,而后对这个列表进行搜索。然而,这种作法的可扩展性太差了。web

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

什么是 斯坦福 NER?

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

前期准备

  1. 一些基本的 Java 知识是须要的。在你的操做系统上安装最新版本的 JDK,你能够安装 OpenJDK 或者 Oracle JDK 7。OpenShift 支持 OpenJDK 6 和 7.api

  2. 从官网中下载斯坦福 NER 软件包安全

  3. 注册一个 OpenShift 帐户。这是彻底免费的,并且红帽(Red Hat)会给每一个用户三个免费的 Gears,在 Gears 上你能够运行你的程序。在这篇文章写的时候,OpenShift 会为每一个用户分配 1.5GB 的内存和 3GB 的硬盘空间。ruby

  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.nlp</groupId>
    <artifactId>stanford-corenlp</artifactId>
    <version>3.2.0</version>
</dependency>

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

<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.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 的内容:

<beans xmlns="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
public class ClassifierConfig {

    private String serializedClassifier = "classifiers/english.all.3class.distsim.crf.ser.gz";
    private CRFClassifier<CoreLabel> classifier;

    @PostConstruct
    public void postConstruct() {
        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 class JaxrsInitializer extends 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")
public class ClassifierRestResource {

    @Inject
    private CRFClassifier<CoreLabel> classifier;

    @GET
    @Path(value = "/{text}")
    @Produces(value = MediaType.APPLICATION_JSON)
    public List<Result> findNer(@PathParam("text") String text) {
        List<List<CoreLabel>> classify = classifier.classify(text);
        List<Result> results = new ArrayList<>();
        for (List<CoreLabel> coreLabels : classify) {
            for (CoreLabel coreLabel : coreLabels) {
                String word = coreLabel.word();
                String answer = coreLabel.get(CoreAnnotations.AnswerAnnotation.class);
                if(!"O".equals(answer)){
                    results.add(new Result(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"}
]

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

接下来


原文:Day 14: Stanford NER--How To Setup Your Own Name, Entity, and Recognition Server in the Cloud
翻译 SegmentFault

相关文章
相关标签/搜索