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

相關文章
相關標籤/搜索