[30天学习30种技术] 第十四天 这篇博客我想探讨一下利用twitter数据构建实时搜索引擎,用斯坦福NER命名识别实体实现。

前言

我没有特别热衷机器学习或者自然文字处理(NLP),不过也总能想到办法用他们。这篇博客我想探讨一下利用twitter数据构建实时搜索引擎。例如提供工作,Tweets会包含公司名字,公司地址,公司联系人,这就需要我们从Tweet上分析人,位置,公司信息。这类问题就落到了Named Entity Recognition(NER)身上。

 

维基解释

命名实体识别(NER)是一个信息提取子任务,用于探索位置和把文字中的分类原子元素归到预先定义好的如人名,机构,地理位置,时间表述,质量,货币价值,百分比等类别中。

 

为了更清晰的表述,来看一个示例,假如我们有一下一段信息。

常人可以很容易的指出公司PSI Pax开在Baltmore. 但是我们怎样让程序来识别呢?最简单的方法是维护一个列表,收集所有的公司和地址,通过这个列表来搜索,但是,这个工作量无法衡量。

今天,我们来讨论怎样用Standford NER包来安装我们自己的NER服务。 

什么是Stanford NER?

Stanford NER是用Java编写的命名识别实体,它给文中的文字针对名字贴上标签,像人名,公司名,基因,蛋白质名等。 

前提准备

  1. Java基础知识。安装最新Java Development      Kit(JDK), 可以装OpenJDK7或者Oracle JDK 7. OpenShift支持OpenJDK 6和7
  2. 从官网下载Stanford NER包.
  3. OpenShift Account上注册。 OpenShift完全免费,红帽给每个用户免费提供了3个Gears来运行程序。目前,这个资源分配合计有每人1.5GB内存,3GB磁盘空间。
  4. 在本机安装rhc 客户端工具,rhc是ruby gem包,所以你需要安装1.8.7或以上版本的ruby。安装rhc,输入
 sudo gem install rhc

        如果已经安装了,确保是最新的,要更新rhc,输入

sudo gem update rhc

          想了解rhc command-line 工具,更多帮助参考https://openshift.redhat.com/community/developers/rhc-client-tools-install。

  1. 用rhc setup 命令安装OpenShift. 执行命令可以帮你创建空间,上传ssh 密钥到OpenShift服务器。 

第一步:创建一个Jboss EAP程序

我们从建一个demo开始,程序叫nerdemo.

$ rhc create-app nerdemo jbosseap

如果你能访问普通gears, 可以用以下命令。

$ rhc create-app nerdemo jbosseap -g medium

这会创建一个程序容器,叫gear,安装所需的SELinux策略和cgroup配置。OpenShift也会为你安装一个私有的git仓库,并克隆到本地。最后,OpenShift会把DNS 扩散到网络中。程序可访问http://linkbin-domain-name.rhcloud.com/. 替换你自己唯一的OpenShift域名(有时也叫命名空间)。 

第二步:添加Maven依赖

在pom.xml文件里添加以下依赖:

<dependency>
    <groupId>edu.stanford.nlp</groupId>
    <artifactId>stanford-corenlp</artifactId>
    <version>3.2.0</version>
</dependency>

View Code

同时通过更新pom.xml里的几个属性把maven项目更新到Java 7.

<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>

View Code

现在更新Maven项目右击> Maven >Update Project.

第三步:激活CDI

我们用CDI添加依赖,CDI或者内容和依赖注入用来在Java EE 6项目中激活依赖注入。CDIJava EE定义了安全类型的依赖注入机制,基本上所有POJO可以作为CDI bean注入。

 

src/main/webapp/WEB-INF文件下新建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>

View Code

第四步:程序作用域分类器Bean

现在我们创建一个ApplicationScoped 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;
    }
}

View Code

从下载的Stanford NER包中复制english.all.3class.distsim.crf.ser.gz分类器到文件夹src/main/resources/classifiers.

第五步:激活JAX-RS

要激活JAX-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{
 
 
}

View Code

第六步:创建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;
    }
}

View Code

发布到云

最后,把更新发布上OpenShift.

$ git add .
$ git commit -am "NER demo app"
$ git push

View Code

 

代码和war成功推送和发布后,我们可以看到程序在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"}
]

View Code

 

这是今天的内容,继续给反馈吧。 

 

原文:https://www.openshift.com/blogs/day-14-stanford-ner-how-to-setup-your-own-name-entity-and-recognition-server-in-the-cloud

版权声明:本文为endless-on原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/endless-on/p/3494497.html