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"}

]


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


接下来


相关文章
|
7月前
|
人工智能 自然语言处理 数据可视化
作为一名在读博士生,我在日常是如何与 AI 协作的
本文是一位AI方向博士生的AI协作实践手记:主张“当同事,不当工具”,提出元提示词、苏格拉底追问、多模型协同与经验沉淀四大方法论,覆盖划词问答、文献研读、科研绘图、代码开发等全科研场景,强调人机共生、流程提效与持续进化。
|
机器学习/深度学习 人工智能 编解码
AI视频生成也能自动补全!Wan2.1 FLF2V:阿里通义开源14B视频生成模型,用首尾两帧生成过渡动画
万相首尾帧模型是阿里通义开源的14B参数规模视频生成模型,基于DiT架构和高效视频压缩VAE,能够根据首尾帧图像自动生成5秒720p高清视频,支持多种风格变换和细节复刻。
3768 9
AI视频生成也能自动补全!Wan2.1 FLF2V:阿里通义开源14B视频生成模型,用首尾两帧生成过渡动画
|
9月前
|
自然语言处理 数据挖掘 测试技术
Qwen3-VL-Embedding系列上新:探索统一多模态表征与排序
2025年6月,Qwen3-VL-Embedding与Qwen3-VL-Reranker开源,基于Qwen3-VL打造,支持文本、图像、视频等多模态检索与跨模态理解,具备统一表示学习、高精度重排序能力,广泛适用于全球化多语言场景,助力高效多模态信息检索。
2998 5
|
人工智能
[AI Mem0] 快速开始:智能记忆管理,让你的数据活起来!
[AI Mem0] 快速开始:智能记忆管理,让你的数据活起来!
1264 7
|
缓存 Java 关系型数据库
【超全详解】Maven工程配置与常见问题解决指南
检查Maven配置包括验证路径、设置pom.xml与Project Structure的Java版本。基本操作有`clean-compile`、`install`和`package`,其中`install`会将jar包放入本地仓库。获取他人工程后需修改配置、清除缓存、更新依赖等。配置文件应从Maven Repository找寻,选择稳定高版本。创建Maven工程可选archetype如`quickstart`或直接创建Java工程。基本目录结构遵循分层设计原则,常见问题包括假性导包、端口占用、时区问题等,对应解决方案包括删除本地仓库文件、调整系统设置或重新加载项目。
2704 6
【超全详解】Maven工程配置与常见问题解决指南
|
NoSQL Java 关系型数据库
这个评论系统设计碉堡了
先赞后看,南哥助你Java进阶一大半官网给出了Facebook评论系统的高级设计图,Facebook的评论竟然是支持实时刷新的。也就是说用户不用刷新帖子,只要帖子有新的评论就会自动推送到用户端,这里Facebook使用的便是每天在全球有设备在使用的WebSocket技术。我是南哥,一个Java学习与进阶的领路人。相信对你通关面试、拿下Offer进入心心念念的公司有所帮助。
1142 5
这个评论系统设计碉堡了
|
传感器 人工智能 安全
智能窗户:自动调节光线与温度的玻璃
【10月更文挑战第20天】智能窗户通过内置传感器和控制系统,自动调节光线与温度,提升家居舒适度并实现节能减排。本文探讨其基本原理、技术创新、实际应用及未来发展趋势,展示这一高科技产品如何改变我们的生活方式。
|
存储 Linux 测试技术
【Docker项目实战】使用Docker部署Raneto知识库平台
【2月更文挑战第11天】使用Docker部署Raneto知识库平台
740 2
【Docker项目实战】使用Docker部署Raneto知识库平台
|
人工智能 API Python
[AI MoA] 原来这就是 MoA(Mixture-of-Agents)
介绍一个项目,Mixture-of-Agents (MoA)。MoA 是一种新颖的方法,它利用多个 LLMs 的集体优势来增强性能,实现最先进的结果。通过采用每层包含多个 LLM 代理的分层架构,MoA 仅使用开源模型,在 AlpacaEval 2.0 上的得分为 65.1%,显着优于 GPT-4 Omni 的 57.5%!

热门文章

最新文章