
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][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 JAVA_HOME para localizar el Java que se va a usar; si no está definida, invocan java esperando encontrar un Java adecuado en su variable PATH.
Puede 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][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());
}