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

]


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


接下来


相关文章
|
机器学习/深度学习 自然语言处理 算法
文本分析-使用jieba库进行中文分词和去除停用词(附案例实战)
文本分析-使用jieba库进行中文分词和去除停用词(附案例实战)
9746 0
|
5天前
|
人工智能 自然语言处理 数据可视化
三步入门:利用 Dify 可视化工作流连接 LLM 与工具
还在为如何将大语言模型与天气查询、数据处理等外部工具集成而烦恼?Dify的可视化工作流让这一切变得直观高效。无需处理复杂代码,只需拖拽节点、配置提示词和API参数,即可快速搭建从“用户提问”到“工具调用”再到“格式化回复”的完整AI应用链路。本文将手把手教你创建智能天气助手,解锁低门槛的AI应用开发。
|
3月前
|
人工智能 调度 开发工具
MemOS 正式上线魔搭社区 MCP 广场,让你的智能体拥有「长期记忆」
MemOS 正式上线魔搭社区 MCP 广场,作为首个大模型记忆操作系统,支持标准化记忆读写,7天调用量超14.9万次。开发者可一键集成,让AI具备持久化、可调度的记忆能力,实现连续思考与长期进化。
625 3
|
4月前
|
机器学习/深度学习 自然语言处理 监控
13_命名实体识别:精准提取文本中的关键信息
在当今信息爆炸的时代,人们每天需要处理海量文本数据。如何从这些非结构化文本中高效地提取关键信息,成为了自然语言处理(NLP)领域的核心挑战之一。命名实体识别(Named Entity Recognition,简称NER)技术正是解决这一问题的关键技术,它能够自动识别并分类文本中的人名、地名、组织机构名、时间、日期、金额等具有特定含义的实体。
|
8月前
|
机器学习/深度学习 数据采集 缓存
《深度剖析:Java中用Stanford NLP工具包优化命名实体识别》
命名实体识别(NER)是自然语言处理中的关键任务,而Stanford NLP工具包作为Java环境下的强大工具,为开发者提供了词性标注、句法分析和NER等功能。针对特定领域(如金融、医疗),默认模型可能无法满足需求,因此优化至关重要。优化方法包括数据预处理(文本清洗、分词、词性标注)、模型定制(微调CRF模型或融合多模型)、特征工程(上下文特征、领域词典)及性能提升(模型压缩、并行计算)。以金融科技公司为例,通过优化,NER准确率从70%提升至90%以上,处理速度显著提高,助力业务决策。
341 1
|
搜索推荐 算法 大数据
大数据无处不在:揭秘日常生活中的大数据魔力
大数据无处不在:揭秘日常生活中的大数据魔力
615 10
|
SQL 存储 关系型数据库
【SQL技术】不同数据库引擎 SQL 优化方案剖析
不同数据库系统(MySQL、PostgreSQL、Doris、Hive)的SQL优化策略。存储引擎特点、SQL执行流程及常见操作(如条件查询、排序、聚合函数)的优化方法。针对各数据库,索引使用、分区裁剪、谓词下推等技术,并提供了具体的SQL示例。通用的SQL调优技巧,如避免使用`COUNT(DISTINCT)`、减少小文件问题、慎重使用`SELECT *`等。通过合理选择和应用这些优化策略,可以显著提升数据库查询性能和系统稳定性。
561 9
|
传感器 人工智能 安全
智能窗户:自动调节光线与温度的玻璃
【10月更文挑战第20天】智能窗户通过内置传感器和控制系统,自动调节光线与温度,提升家居舒适度并实现节能减排。本文探讨其基本原理、技术创新、实际应用及未来发展趋势,展示这一高科技产品如何改变我们的生活方式。
|
数据采集 人工智能 监控
赌你一定想要!OpenDataLab首款大模型多模态标注平台Label-LLM正式开源
Label-LLM 是一款专为大模型训练设计的多模态文本对话标注工具,支持团队协作,让标注工作变得简单高效。它不仅涵盖丰富的任务类型,如回答采集、偏好收集和内容评估等,还支持多模态数据标注,包括图像、视频和音频。Label-LLM具备预标注载入功能,能大幅提升工作效率,并提供全方位的任务管理与可视化分析,确保标注质量。快来体验这款强大的标注平台吧![部署文档](https://github.com/opendatalab/LabelLLM)
3237 0
赌你一定想要!OpenDataLab首款大模型多模态标注平台Label-LLM正式开源
|
算法 调度 Python
Python高级算法——贪心算法(Greedy Algorithm)
Python高级算法——贪心算法(Greedy Algorithm)
1137 3