
SDK de Java para construir canalizaciones de análisis que procesan y enriquecen datos de texto no estructurados con anotaciones, sistemas de tipos y motores de análisis modulares.
Apache UIMA le ayuda a gestionar datos no estructurados (como textos) que se enriquecen con información útil. Por ejemplo, si desea identificar una mención de una entidad en un texto o vincular esa entidad a un conjunto de datos de referencia, Apache UIMA proporciona:
Tenga en cuenta que el SDK de Java de Apache UIMA solo proporciona un framework para construir analíticas, pero no proporciona analíticas. Sin embargo, existen varios terceros que se basan en Apache UIMA y que proporcionan colecciones de componentes de análisis o soluciones ya preparadas.
Apache UIMA v3.6.0 y versiones posteriores requieren Java 17 o posterior.
Para ejecutar las herramientas del plugin de Eclipse para UIMA, debe iniciar Eclipse 4.25 (2022-09) o posterior con Java 17 o posterior.
Ejecutar la herramienta de migración en archivos de clase requiere un Java JDK, no un Java JRE.
Las plataformas compatibles son: Windows, Linux y macOS. Otras implementaciones de la plataforma Java deberían funcionar, pero no se han probado de forma significativa.
Muchos de los scripts del directorio /bin invocan Java. Usan el valor de la variable de entorno para localizar el Java que se va a usar; si no está definida, invocan esperando encontrar un Java adecuado en su variable .
JAVA_HOMEjavaPATHPuede añadir el SDK de Java de Apache UIMA a su proyecto fácilmente en la mayoría de las herramientas de compilación importándolo desde Maven Central. Por ejemplo, si usa Maven, puede añadir la siguiente dependencia a su proyecto:
<dependency>
<groupId>org.apache.uima</groupId>
<artifactId>uimaj-core</artifactId>
<version>3.6.0</version>
</dependency>
A continuación, ofrecemos algunos ejemplos breves de cómo usar el SDK de Java de Apache UIMA y la librería Apache uimaFIT. Apache uimaFIT es una dependencia separada que puede añadir:
<dependency>
<groupId>org.apache.uima</groupId>
<artifactId>uimafit-core</artifactId>
<version>3.6.0</version>
</dependency>
El sistema de tipos define el tipo de información que queremos adjuntar a la información no estructurada (aquí, un documento de texto). En nuestro ejemplo, queremos identificar menciones de entidades, por lo que definimos un tipo my.Entity con una característica category que puede usarse para almacenar la categoría a la que pertenece la entidad.
Para ilustrar la información que UIMA mantiene internamente sobre el esquema de anotaciones, escribimos el esquema generado como XML en pantalla.
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);
Ahora creamos un objeto de la Estructura Común de Análisis (CAS) en el que almacenamos el texto que queremos analizar.
De nuevo, para ilustrar la información que UIMA almacena internamente en el objeto CAS, escribimos una representación XML del objeto en pantalla.
var cas = CasFactory.createCas(tsd);
cas.setDocumentText("Welcome to Apache UIMA.");
cas.setDocumentLanguage("en");
CasIOUtils.save(cas, System.out, SerialFormat.XMI_PRETTY);
Ahora, creamos una anotación del tipo my.Entity para identificar la mención de Apache UIMA en el texto de ejemplo.
Finalmente, iteramos sobre todas las anotaciones del CAS y las imprimimos en pantalla. Esto incluye la DocumentAnnotation predeterminada que UIMA siempre crea, así como la anotación my.Entity que creamos nosotros mismos.
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());
}
Para organizar diferentes tipos de análisis en pasos, normalmente los empaquetamos en motores de análisis individuales. Ahora ilustramos cómo se pueden construir estos componentes y cómo se pueden ejecutar como una canalización de análisis (pipeline).
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());
}
La configuración de los componentes de UIMA se logra generalmente creando archivos de descriptores XML que indican al framework en tiempo de ejecución cómo deben instanciarse e implementarse los componentes. Estos archivos de descriptores XML están muy acoplados a la implementación Java de los componentes que describen. Hemos encontrado que es muy difícil mantener los dos consistentes entre sí, especialmente cuando la refactorización de código es muy frecuente. uimaFIT proporciona anotaciones Java para describir componentes de UIMA que pueden usarse para describir directamente los componentes de UIMA en el código. Esto simplifica enormemente la refactorización de una definición de componente (por ejemplo, cambiar el nombre de un parámetro de configuración). También hace posible generar archivos de descriptores XML como parte del ciclo de compilación en lugar de realizarse manualmente en paralelo con la creación de código. uimaFIT también facilita la instanciación de componentes de UIMA sin usar archivos de descriptores XML en absoluto, proporcionando una serie de métodos de fábrica convenientes que permiten la instanciación programática/dinámica de componentes de UIMA. Esto convierte a uimaFIT en una biblioteca ideal para probar componentes de UIMA porque el componente puede ser fácilmente instanciado e invocado sin requerir que se cree primero un archivo descriptor. uimaFIT también es útil en entornos de investigación donde la instanciación programática/dinámica de un pipeline puede simplificar la experimentación. Por ejemplo, al realizar una validación cruzada de 10 pliegues en varias condiciones experimentales, puede ser bastante laborioso crear un conjunto diferente de archivos descriptores para cada ejecución o incluso un script que genere dichos archivos. uimaFIT es agnóstico respecto al sistema de tipos y no depende (ni proporciona) de un sistema de tipos específico.
uimaFIT es una biblioteca que proporciona fábricas, inyección y utilidades de prueba para UIMA. La siguiente lista destaca algunas de las características que ofrece uimaFIT:
Fábricas: simplifican la instanciación programática de componentes de UIMA sin archivos descriptores. Por ejemplo, para instanciar un AnalysisEngine se podría hacer una llamada como esta:
AnalysisEngineFactory.createEngine(MyAEImpl.class, myTypeSystem,
paramName1, paramValue2,
paramName2, paramValue2,
...)
Inyección: gestiona el enlace de los valores de los parámetros de configuración con las
variables miembro correspondientes en los motores de análisis y gestiona el enlace de
recursos externos. Por ejemplo, para vincular un parámetro de configuración basta con anotar
una variable miembro con @ConfigurationParameter. Los recursos externos también se pueden
inyectar mediante la anotación @ExternalResource.
Luego añada una línea de código a su método initialize:
ConfigurationParameterInitializer.initialize(this, uimaContext).
Esto se maneja automáticamente si extiende la clase JCasAnnotator_ImplBase de uimaFIT.
Pruebas: uimaFIT simplifica las pruebas de varias maneras descritas en la documentación. Al facilitar la instanciación de sus componentes sin archivos descriptores, se puede eliminar una gran cantidad de XML innecesario y difícil de mantener del código de prueba. Esto hace que las pruebas sean más fáciles de escribir y mantener. Además, ejecutar componentes como un pipeline se puede lograr con una llamada a un método como esta:
SimplePipeline.runPipeline(reader, ae1, ..., aeN, consumer1, ... consumerN)
uimaFIT es parte del proyecto Apache UIMA(TM). uimaFIT solo puede usarse junto con una versión compatible de la versión Java del SDK de Apache UIMA. Para su comodidad, el paquete de distribución binaria de uimaFIT incluye todas las bibliotecas necesarias para usar uimaFIT. En particular, para los usuarios novatos, se recomienda encarecidamente obtener una copia del SDK completo de UIMA por separado.
uimaFIT está disponible a través de Maven Central. Si usa Maven para su entorno de compilación, puede añadir uimaFIT como dependencia a su archivo pom.xml con lo siguiente:
<dependencies>
<dependency>
<groupId>org.apache.uima</groupId>
<artifactId>uimafit-core</artifactId>
<version>3.6.0</version>
</dependency>
</dependencies>
Módulos
Para compilar Apache UIMA, necesita al menos un JDK de Java 17 y una versión reciente de Maven 3.
Después de extraer el ZIP de la distribución de fuentes o clonar el repositorio, cambie al directorio creado y ejecute el siguiente comando:
mvn clean install
Para más detalles, consulte http://uima.apache.org/building-uima.html
Puede descargar las distribuciones de fuentes y binarias desde el sitio web de Apache UIMA.
Después de descomprimir la distribución de Apache UIMA del paquete de su elección (por ejemplo, .zip o .gz), realice los siguientes pasos para configurar UIMA y que funcione correctamente.
Establezca JAVA_HOME en el directorio de su instalación de JRE que desee usar para UIMA.
Establezca UIMA_HOME en el directorio apache-uima de su distribución de Apache UIMA descomprimida
Añada UIMA_HOME/bin a su PATH
Ejecute el script UIMA_HOME/bin/adjustExamplePaths.bat (o .sh) para actualizar
las rutas en los ejemplos según la ruta real del directorio UIMA_HOME.
Este script ejecuta un programa Java; debe tener java en su PATH o establecer la variable
de entorno JAVA_HOME en un JRE adecuado.
Nota: Los procedimientos del sistema operativo Mac OS X para configurar las variables de entorno globales se describen aquí: consulte http://developer.apple.com/qa/qa2001/qa1067.html.
Para probar la instalación, ejecute el archivo documentAnalyzer.bat (o .sh) ubicado en el subdirectorio bin. Esto debería abrir una ventana de Document Analyzer. Establezca los valores que se muestran en esta GUI de la siguiente manera:
UIMA_HOME/examples/dataUIMA_HOME/examples/data/processedUIMA_HOME/examples/descriptors/analysis_engine/PersonTitleAnnotator.xmlReemplace UIMA_HOME arriba con la ruta de su instalación de Apache UIMA.
A continuación, haga clic en el botón Run, que debería, tras una breve pausa, abrir una ventana de Analyzed Results. Haga doble clic en uno de los documentos para mostrar los resultados del análisis de ese documento.
Esta es una lista de varios proyectos conocidos que proporcionan sus herramientas de análisis como componentes UIMA o que envuelven herramientas de análisis de terceros como componentes UIMA:
Esta no es una lista exhaustiva. Si cree que algún proyecto en particular debería aparecer aquí, por favor háganoslo saber. Puede encontrar otros, por ejemplo:
El SDK de Java de Apache UIMA se puede usar con cualquier lenguaje de programación basado en la Máquina Virtual de Java, incluidos Java, Groovy, Scala y muchos otros lenguajes.
La interoperabilidad con Python se puede lograr, por ejemplo, mediante la biblioteca de terceros DKPro Cassis, que se puede usar para leer, manipular y escribir datos CAS en el formato XMI.
El SDK de Java de Apache UIMA es una implementación basada en Java de la especificación UIMA.
Por favor, dirija sus preguntas a [email protected].
Si usa uimaFIT para apoyar la investigación académica, por favor considere citar el siguiente artículo cuando corresponda:
@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}
}
Principios de la década de 2000: UIMA fue desarrollado originalmente por IBM como parte de la investigación sobre el análisis de información no estructurada (como texto, audio y video). Fue diseñado para procesar grandes volúmenes de datos no estructurados de forma escalable, orientado a aplicaciones de procesamiento de lenguaje natural (NLP).
2004: UIMA se convirtió en código abierto, lo que permitió un uso más amplio y contribuciones externas a IBM.
2006: El proyecto UIMA fue aceptado en el Apache Incubator, iniciando el proceso formal para convertirse en un proyecto Apache.
2008: UIMA se graduó del Apache Incubator y se convirtió en un proyecto Apache de primer nivel, lo que significó su madurez y desarrollo activo.
2009: Se introdujo Apache UIMA-AS (Asynchronous Scaleout), que permite el procesamiento distribuido y asíncrono de pipelines de UIMA.
2012: uimaFIT fue contribuido al proyecto Apache UIMA. Apache uimaFIT se conocía anteriormente como uimaFIT, que a su vez se conocía como UUTUC. Antes de su contribución, era un esfuerzo colaborativo entre el Center for Computational Pharmacology de la Universidad de Colorado Denver, el Center for Computational Language and Education Research de la Universidad de Colorado en Boulder y el Ubiquitous Knowledge Processing (UKP) Lab de la Technische Universität Darmstadt.
2013: Se introdujo UIMA DUCC (Distributed UIMA Cluster Computing) como subproyecto de Apache UIMA.
2016: Se introdujo Apache UIMA Ruta (Rule-based Text Annotation) como extensión, proporcionando un lenguaje de scripting para el procesamiento de texto basado en reglas.
2023: UIMA DUCC y UIMA-AS se retiraron.
2024: uimaFIT se ha fusionado en el SDK de Java de UIMA