Apache UIMA 帮助您管理包含丰富有用信息的非结构化数据(例如文本)。例如,如果您想识别文本中实体的提及或可能将该实体链接到参考数据集,Apache UIMA 提供:
请注意,Apache UIMA Java SDK 仅提供了一个构建分析工具的框架,但不提供任何分析工具。然而,有多家第三方在 Apache UIMA 之上构建,并提供分析组件集合或现成的解决方案。
Apache UIMA v3.6.0 及更高版本需要 Java 17 或更高版本。
运行 UIMA 的 Eclipse 插件工具要求您使用 Java 17 或更高版本启动 Eclipse 4.25(2022-09)或更高版本。
在类文件上运行迁移工具需要运行 Java JDK,而不是 Java JRE。
支持的平台包括:Windows、Linux 和 macOS。其他 Java 平台实现应该也能工作,但未经过大量测试。
/bin 目录中的许多脚本会调用 Java。它们使用环境变量 JAVA_HOME 的值来定位要使用的 Java;如果未设置,它们会调用 java,期望能在您的 PATH 变量中找到合适的 Java。
您可以通过从 Maven Central 导入,在大多数构建工具中轻松将 Apache UIMA Java SDK 添加到您的项目。例如,如果您使用 Maven,可以将以下依赖项添加到您的项目:
<dependency>
<groupId>org.apache.uima</groupId>
<artifactId>uimaj-core</artifactId>
<version>3.6.0</version>
</dependency>
接下来,我们给出几个如何使用 Apache UIMA Java SDK 和 Apache uimaFIT 库的简短示例。 Apache uimaFIT 是一个单独的依赖项,您也可以添加:
<dependency>
<groupId>org.apache.uima</groupId>
<artifactId>uimafit-core</artifactId>
<version>3.6.0</version>
</dependency>
类型系统定义了我们想要附加到非结构化信息(此处为文本文档)的信息类型。在我们的示例中,我们想要识别实体的提及,因此我们定义一个类型 my.Entity,并带有一个特性 category,可用于存储实体所属的类别。
为了说明 UIMA 内部维护的关于注释模式的信息,我们将生成的模式以 XML 格式输出到屏幕。
String TYPE_NAME_ENTITY = "my.Entity";
String TYPE_NAME_TOKEN = "my.Token";
String FEAT_NAME_CATEGORY = "category";
var tsd = UIMAFramework.getResourceSpecifierFactory().createTypeSystemDescription();
tsd.addType(TYPE_NAME_TOKEN, "", CAS.TYPE_NAME_ANNOTATION);
var entityTypeDesc = tsd.addType(TYPE_NAME_ENTITY, "", CAS.TYPE_NAME_ANNOTATION);
entityTypeDesc.addFeature(FEAT_NAME_CATEGORY, "", CAS.TYPE_NAME_STRING);
tsd.toXML(System.out);
现在我们创建一个通用分析结构(CAS)对象,用于存储我们想要分析的文本。
同样,为了说明 UIMA 内部存储在 CAS 对象中的信息,我们将对象的 XML 表示输出到屏幕。
var cas = CasFactory.createCas(tsd);
cas.setDocumentText("Welcome to Apache UIMA.");
cas.setDocumentLanguage("en");
CasIOUtils.save(cas, System.out, SerialFormat.XMI_PRETTY);
现在,我们创建一个类型为 my.Entity 的注释,以识别示例文本中 Apache UIMA 的提及。
最后,我们迭代 CAS 中的所有注释并将其打印到屏幕。这包括 UIMA 始终创建的默认 DocumentAnnotation,以及我们自己创建的 my.Entity 注释。
var entityType = cas.getTypeSystem().getType(TYPE_NAME_ENTITY);
var entity = cas.createAnnotation(entityType, 11, 22);
cas.addFsToIndexes(entity);
for (var anno : cas.<Annotation>select(entityType)) {
System.out.printf("%s: [%s]%n", anno.getType().getName(), anno.getCoveredText());
}
为了将不同类型的分析组织成步骤,我们通常将它们打包到单独的分析引擎中。我们现在说明如何构建这样的组件,以及如何将它们作为分析管道执行。
class TokenAnnotator extends CasAnnotator_ImplBase {
public void process(CAS cas) throws AnalysisEngineProcessException {
var tokenType = cas.getTypeSystem().getType(TYPE_NAME_TOKEN);
var bi = BreakIterator.getWordInstance();
bi.setText(cas.getDocumentText());
int begin = bi.first();
int end;
for (end = bi.next(); end != BreakIterator.DONE; end = bi.next()) {
var token = cas.createAnnotation(tokenType, begin, end);
cas.addFsToIndexes(token);
begin = end;
}
}
}
class EntityAnnotator extends CasAnnotator_ImplBase {
public void process(CAS cas) throws AnalysisEngineProcessException {
var tokenType = cas.getTypeSystem().getType(TYPE_NAME_TOKEN);
var entityType = cas.getTypeSystem().getType(TYPE_NAME_ENTITY);
for (var token : cas.<Annotation>select(tokenType)) {
if (Character.isUpperCase(token.getCoveredText().charAt(0))) {
var entity = cas.createAnnotation(entityType, token.getBegin(), token.getEnd());
cas.addFsToIndexes(entity);
}
}
}
}
cas = CasFactory.createCas(tsd);
cas.setDocumentText("John likes Apache UIMA.");
cas.setDocumentLanguage("en");
var pipeline = AnalysisEngineFactory.createEngineDescription(
AnalysisEngineFactory.createEngineDescription(TokenAnnotator.class),
AnalysisEngineFactory.createEngineDescription(EntityAnnotator.class));
SimplePipeline.runPipeline(cas, pipeline);
for (var anno : cas.<Annotation>select(entityType)) {
System.out.printf("%s: [%s]%n", anno.getType().getName(), anno.getCoveredText());
}
配置 UIMA 组件通常通过创建 XML 描述符文件来实现,这些文件在运行时告诉框架如何实例化和部署组件。这些 XML 描述符文件与它们所描述的组件的 Java 实现紧密耦合。我们发现,在代码重构频繁的情况下,很难保持两者一致。uimaFIT 提供了用于描述 UIMA 组件的 Java 注解,可以直接在代码中描述 UIMA 组件。这大大简化了组件定义的重构(例如更改配置参数名称)。它还使得在构建周期中生成 XML 描述符文件成为可能,而不是手动与代码创建并行进行。uimaFIT 还通过提供许多便捷的工厂方法,使得无需 XML 描述符文件即可轻松实例化 UIMA 组件,从而允许以编程方式/动态地实例化 UIMA 组件。这使得 uimaFIT 成为测试 UIMA 组件的理想库,因为无需先创建描述符文件即可轻松实例化和调用组件。uimaFIT 在研究环境中也很有帮助,其中以编程方式/动态实例化管道可以简化实验。例如,在多个实验条件下执行 10 折交叉验证时,为每次运行创建一组不同的描述符文件,甚至创建生成这些描述符文件的脚本,都是非常费力的。uimaFIT 与类型系统无关,并且不依赖(也不提供)特定的类型系统。
uimaFIT 是一个提供工厂、注入和测试实用程序的库,用于 UIMA。以下列表重点介绍了 uimaFIT 提供的一些功能:
工厂: 简化为 UIMA 组件以编程方式实例化,无需描述符文件。例如,要实例化一个 AnalysisEngine,可以这样调用:
AnalysisEngineFactory.createEngine(MyAEImpl.class, myTypeSystem,
paramName1, paramValue2,
paramName2, paramValue2,
...)
注入: 处理配置参数值到分析引擎中相应成员变量的绑定,以及处理外部资源的绑定。例如,要绑定一个配置参数,只需使用 @ConfigurationParameter 注解一个成员变量。外部资源同样可以通过 @ExternalResource 注解注入。然后在您的初始化方法中添加一行代码:
ConfigurationParameterInitializer.initialize(this, uimaContext).
如果您扩展了 uimaFIT 的 JCasAnnotator_ImplBase 类,则会自动处理此操作。
测试: uimaFIT 通过文档中描述的多种方式简化了测试。通过使您无需描述符文件即可轻松实例化组件,可以从测试代码中消除大量难以维护且不必要的 XML。这使得测试更易于编写和维护。此外,通过如下方法调用即可将组件作为管道运行:
SimplePipeline.runPipeline(reader, ae1, ..., aeN, consumer1, ... consumerN)
uimaFIT 是 Apache UIMA(TM) 项目的一部分。uimaFIT 只能与兼容版本的 Apache UIMA Java SDK 一起使用。为方便起见,uimaFIT 的二进制分发包包含使用 uimaFIT 所需的所有库。特别是对于新手用户,强烈建议单独获取完整 UIMA SDK 的副本。
uimaFIT 可通过 Maven Central 获取。如果您使用 Maven 构建环境,则可以通过以下方式将 uimaFIT 作为依赖项添加到您的 pom.xml 文件中:
<dependencies>
<dependency>
<groupId>org.apache.uima</groupId>
<artifactId>uimafit-core</artifactId>
<version>3.6.0</version>
</dependency>
</dependencies>
模块
要构建 Apache UIMA,您至少需要 Java 17 JDK 和较新的 Maven 3 版本。
解压源代码分发 ZIP 或克隆存储库后,切换到创建的目录并运行以下命令:
mvn clean install
有关更多详细信息,请参阅 http://uima.apache.org/building-uima.html
您可以从 Apache UIMA 网站 下载源代码和二进制分发。
从您选择的包(例如 .zip 或 .gz)解压 Apache UIMA 分发后,执行以下步骤设置 UIMA 以确保其正常工作。
将 JAVA_HOME 设置为您要为 UIMA 使用的 JRE 安装目录。
将 UIMA_HOME 设置为解压后的 Apache UIMA 分发的 apache-uima 目录
将 UIMA_HOME/bin 附加到您的 PATH 中
运行脚本 UIMA_HOME/bin/adjustExamplePaths.bat(或 .sh),以根据实际的 UIMA_HOME 目录路径更新示例中的路径。
该脚本运行一个 Java 程序;您必须将 java 包含在 PATH 中,或者将环境变量 JAVA_HOME 设置为合适的 JRE。
注意:Mac OS X 操作系统设置全局环境变量的过程描述如下:请参阅 http://developer.apple.com/qa/qa2001/qa1067.html。
要测试安装,请运行位于 bin 子目录中的 documentAnalyzer.bat(或 .sh)文件。这应该会弹出一个 文档分析器 窗口。将该 GUI 中显示的值设置如下:
UIMA_HOME/examples/dataUIMA_HOME/examples/data/processedUIMA_HOME/examples/descriptors/analysis_engine/PersonTitleAnnotator.xml将上述 UIMA_HOME 替换为您的 Apache UIMA 安装路径。
接下来,单击 运行 按钮,稍等片刻后,应该会弹出一个 分析结果 窗口。双击其中一个文档以显示该文档的分析结果。
以下是几个知名项目的列表,这些项目将其分析工具作为 UIMA 组件提供,或将第三方分析工具包装为 UIMA 组件:
这不是一个详尽的列表。如果您认为某个特定项目应在此处列出,请告知我们。 您可以通过以下方式找到其他项目:
Apache UIMA Java SDK 可以与基于 Java 虚拟机的任何编程语言一起使用,包括 Java、Groovy、Scala 和许多其他语言。
与 Python 的互操作性可以通过第三方 DKPro Cassis 库实现,该库可用于读取、操作和写入 XMI 格式的 CAS 数据。
Apache UIMA Java SDK 是基于 Java 的 UIMA 规范 的实现。
请将问题发送至 [email protected]。
如果您使用 uimaFIT 支持学术研究,请考虑引用以下论文:
@InProceedings{ogren-bethard:2009:SETQA-NLP,
author = {Ogren, Philip and Bethard, Steven},
title = {Building Test Suites for {UIMA} Components},
booktitle = {Proceedings of the Workshop on Software Engineering, Testing, and Quality Assurance for Natural Language Processing (SETQA-NLP 2009)},
month = {June},
year = {2009},
address = {Boulder, Colorado},
publisher = {Association for Computational Linguistics},
pages = {1--4},
url = {http://www.aclweb.org/anthology/W/W09/W09-1501}
}
2000 年代初期: UIMA 最初由 IBM 开发,作为分析非结构化信息(如文本、音频和视频)研究的一部分。它旨在以可扩展的方式处理大量非结构化数据,针对自然语言处理(NLP)应用。
2004 年: UIMA 开源,允许更广泛的使用和来自 IBM 外部的贡献。
2006 年: UIMA 项目被接受进入 Apache 孵化器,开始了成为 Apache 项目的正式过程。
2008 年: UIMA 从 Apache 孵化器毕业,成为 Apache 顶级项目,标志着其成熟和活跃开发。
2009 年: Apache UIMA-AS(异步扩展)被引入,支持 UIMA 管道的分布式和异步处理。
2012 年: uimaFIT 被贡献给 Apache UIMA 项目。Apache uimaFIT 以前称为 uimaFIT,而 uimaFIT 又曾被称为 UUTUC。在贡献之前,它是科罗拉多大学丹佛分校计算药理学中心、科罗拉多大学博尔德分校计算语言与教育研究中心以及达姆施塔特工业大学普适知识处理(UKP)实验室的合作成果。
2013 年: UIMA DUCC(分布式 UIMA 集群计算)作为 Apache UIMA 的子项目被引入。
2016 年: Apache UIMA Ruta(基于规则的文本注释)作为扩展被引入,提供了一种用于基于规则文本处理的脚本语言。
2023 年: UIMA DUCC 和 UIMA-AS 被弃用。
2024 年: uimaFIT 已合并到 UIMA Java SDK 中