
Java SDK para construir pipelines de análise que processam e enriquecem dados de texto não estruturados com anotações, sistemas de tipos e motores de análise modulares.
Apache UIMA ajuda você a gerenciar dados não estruturados (como textos) que são enriquecidos com informações úteis. Por exemplo, se você deseja identificar uma menção a uma entidade em um texto ou possivelmente vincular essa entidade a um conjunto de dados de referência, o Apache UIMA fornece:
Observe que o Apache UIMA Java SDK fornece apenas uma estrutura para construir análises, mas não fornece nenhuma análise. No entanto, existem vários terceiros que constroem sobre o Apache UIMA e fornecem coleções de componentes de análise ou soluções prontas.
Apache UIMA v3.6.0 e posteriores exigem Java versão 17 ou superior.
Executar o plugin Eclipse para UIMA requer iniciar o Eclipse 4.25 (2022-09) ou posterior usando um Java 17 ou superior.
Executar a ferramenta de migração em arquivos de classe requer executar com um Java JDK, não um Java JRE.
As plataformas suportadas são: Windows, Linux e macOS. Outras implementações da plataforma Java devem funcionar, mas não foram significativamente testadas.
Muitos dos scripts no diretório /bin invocam Java. Eles usam o valor da variável de ambiente para localizar o Java a ser usado; se não estiver definida, eles invocam esperando encontrar um Java apropriado na sua variável .
JAVA_HOMEjavaPATHVocê pode adicionar o Apache UIMA Java SDK ao seu projeto facilmente na maioria das ferramentas de build importando-o do Maven Central. Por exemplo, se você usa Maven, pode adicionar a seguinte dependência ao seu projeto:
<dependency>
<groupId>org.apache.uima</groupId>
<artifactId>uimaj-core</artifactId>
<version>3.6.0</version>
</dependency>
A seguir, damos alguns breves exemplos de como usar o Apache UIMA Java SDK e a biblioteca Apache uimaFIT. Apache uimaFIT é uma dependência separada que você pode adicionar:
<dependency>
<groupId>org.apache.uima</groupId>
<artifactId>uimafit-core</artifactId>
<version>3.6.0</version>
</dependency>
O sistema de tipos define o tipo de informação que queremos anexar à informação não estruturada (aqui um documento de texto). Em nosso exemplo, queremos identificar menções de entidades, então definimos um tipo my.Entity com um recurso category que pode ser usado para armazenar a categoria à qual a entidade pertence.
Para ilustrar a informação que a UIMA mantém internamente sobre o esquema de anotação, escrevemos o esquema gerado como XML na tela.
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);
Agora criamos um objeto Common Analysis Structure (CAS) no qual armazenamos o texto que queremos analisar.
Novamente, para ilustrar a informação que a UIMA armazena internamente no objeto CAS, escrevemos uma representação XML do objeto na tela.
var cas = CasFactory.createCas(tsd);
cas.setDocumentText("Welcome to Apache UIMA.");
cas.setDocumentLanguage("en");
CasIOUtils.save(cas, System.out, SerialFormat.XMI_PRETTY);
Agora, criamos uma anotação do tipo my.Entity para identificar a menção de Apache UIMA no texto de exemplo.
Finalmente, iteramos sobre todas as anotações na CAS e as imprimimos na tela. Isso inclui a DocumentAnnotation padrão que é sempre criada pela UIMA, bem como a anotação my.Entity que criamos nós mesmos.
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álise em etapas, geralmente os empacotamos em motores de análise individuais. Ilustramos agora como esses componentes podem ser construídos e como podem ser executados como um pipeline de análise.
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());
}
Configurar componentes UIMA geralmente é feito criando arquivos descritores XML que informam ao framework em tempo de execução como os componentes devem ser instanciados e implantados. Esses arquivos descritores XML são muito fortemente acoplados à implementação Java dos componentes que descrevem. Descobrimos que é muito difícil manter os dois consistentes entre si, especialmente quando a refatoração de código é muito frequente. O uimaFIT fornece anotações Java para descrever componentes UIMA que podem ser usadas para descrever diretamente os componentes UIMA no código. Isso simplifica muito a refatoração de uma definição de componente (por exemplo, alterar o nome de um parâmetro de configuração). Também torna possível gerar arquivos descritores XML como parte do ciclo de construção, em vez de serem realizados manualmente em paralelo com a criação do código. O uimaFIT também facilita a instanciação de componentes UIMA sem usar arquivos descritores XML, fornecendo vários métodos de fábrica convenientes que permitem a instanciação programática/dinâmica de componentes UIMA. Isso torna o uimaFIT uma biblioteca ideal para testar componentes UIMA, pois o componente pode ser facilmente instanciado e invocado sem exigir que um arquivo descritor seja criado primeiro. O uimaFIT também é útil em ambientes de pesquisa nos quais a instanciação programática/dinâmica de um pipeline pode simplificar a experimentação. Por exemplo, ao realizar validação cruzada de 10 dobras em várias condições experimentais, pode ser bastante trabalhoso criar um conjunto diferente de arquivos descritores para cada execução ou até mesmo um script que gere esses arquivos descritores. O uimaFIT é agnóstico em relação ao sistema de tipos e não depende (nem fornece) de um sistema de tipos específico.
uimaFIT é uma biblioteca que fornece fábricas, injeção e utilitários de teste para UIMA. A lista a seguir destaca alguns dos recursos que o uimaFIT oferece:
Fábricas: simplificam a instanciação programática de componentes UIMA sem arquivos descritores. Por exemplo, para instanciar um AnalysisEngine, uma chamada como esta poderia ser feita:
AnalysisEngineFactory.createEngine(MyAEImpl.class, myTypeSystem,
paramName1, paramValue2,
paramName2, paramValue2,
...)
Injeção: lida com a vinculação dos valores dos parâmetros de configuração às variáveis de membro correspondentes nos motores de análise e lida com a vinculação de recursos externos. Por exemplo, para vincular um parâmetro de configuração, basta anotar uma variável de membro com @ConfigurationParameter. Recursos externos também podem ser injetados por meio da anotação @ExternalResource.
Em seguida, adicione uma linha de código ao seu método de inicialização:
ConfigurationParameterInitializer.initialize(this, uimaContext).
Isso é tratado automaticamente se você estender a classe uimaFIT JCasAnnotator_ImplBase.
Testes: o uimaFIT simplifica os testes de várias maneiras descritas na documentação. Ao tornar fácil instanciar seus componentes sem arquivos descritores, uma grande quantidade de XML difícil de manter e desnecessário pode ser eliminada do seu código de teste. Isso torna os testes mais fáceis de escrever e manter. Além disso, executar componentes como um pipeline pode ser realizado com uma chamada de método como esta:
SimplePipeline.runPipeline(reader, ae1, ..., aeN, consumer1, ... consumerN)
O uimaFIT faz parte do projeto Apache UIMA(TM). O uimaFIT só pode ser usado em conjunto com uma versão compatível da versão Java do Apache UIMA SDK. Para sua conveniência, o pacote de distribuição binária do uimaFIT inclui todas as bibliotecas necessárias para usar o uimaFIT. Em particular para usuários novatos, é fortemente aconselhável obter uma cópia do UIMA SDK completo separadamente.
O uimaFIT está disponível via Maven Central. Se você usa Maven para seu ambiente de build, pode adicionar o uimaFIT como uma dependência ao seu arquivo pom.xml com o seguinte:
<dependencies>
<dependency>
<groupId>org.apache.uima</groupId>
<artifactId>uimafit-core</artifactId>
<version>3.6.0</version>
</dependency>
</dependencies>
Módulos
Para construir o Apache UIMA, você precisa de pelo menos um JDK Java 17 e uma versão recente do Maven 3.
Após extrair o ZIP da distribuição de origem ou clonar o repositório, acesse o diretório criado e execute o seguinte comando:
mvn clean install
Para mais detalhes, consulte http://uima.apache.org/building-uima.html
Você pode baixar as distribuições de origem e binária do site do Apache UIMA.
Depois de descompactar a distribuição do Apache UIMA do pacote de sua escolha (por exemplo, .zip ou .gz), execute as etapas abaixo para configurar o UIMA para que funcione corretamente.
Defina JAVA_HOME para o diretório da sua instalação JRE que você deseja usar para o UIMA.
Defina UIMA_HOME para o diretório apache-uima da sua distribuição Apache UIMA descompactada
Acrescente UIMA_HOME/bin ao seu PATH
Execute o script UIMA_HOME/bin/adjustExamplePaths.bat (ou .sh) para atualizar os caminhos nos exemplos com base no caminho real do diretório UIMA_HOME. Este script executa um programa Java; você deve ter java em seu PATH ou definir a variável de ambiente JAVA_HOME para um JRE adequado.
Nota: Os procedimentos do sistema operacional Mac OS X para configurar variáveis de ambiente globais são descritos aqui: consulte http://developer.apple.com/qa/qa2001/qa1067.html.
Para testar a instalação, execute o arquivo documentAnalyzer.bat (ou .sh) localizado no subdiretório bin. Isso deve abrir uma janela Document Analyzer. Defina os valores exibidos nesta GUI da seguinte forma:
UIMA_HOME/examples/dataUIMA_HOME/examples/data/processedUIMA_HOME/examples/descriptors/analysis_engine/PersonTitleAnnotator.xmlSubstitua UIMA_HOME acima pelo caminho da sua instalação do Apache UIMA.
Em seguida, clique no botão Run, que, após uma breve pausa, deve abrir uma janela Analyzed Results. Clique duas vezes em um dos documentos para exibir os resultados da análise para esse documento.
Aqui está uma lista de vários projetos conhecidos que fornecem suas ferramentas de análise como componentes UIMA ou que encapsulam ferramentas de análise de terceiros como componentes UIMA:
Esta não é uma lista exaustiva. Se você acha que algum projeto em particular deveria estar listado aqui, por favor nos avise. Você pode encontrar outros, por exemplo, por:
O Apache UIMA Java SDK pode ser usado com qualquer linguagem de programação baseada na Java Virtual Machine, incluindo Java, Groovy, Scala e muitas outras linguagens.
A interoperabilidade com Python pode, por exemplo, ser alcançada por meio da biblioteca de terceiros DKPro Cassis, que pode ser usada para ler, manipular e escrever dados CAS no formato XMI.
O Apache UIMA Java SDK é uma implementação baseada em Java da especificação UIMA.
Por favor, direcione perguntas para [email protected].
Se você usa o uimaFIT para apoiar pesquisa acadêmica, considere citar o seguinte artigo conforme apropriado:
@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}
}
Início dos anos 2000: A UIMA foi originalmente desenvolvida pela IBM como parte de pesquisas sobre análise de informações não estruturadas (como texto, áudio e vídeo). Foi projetada para processar grandes volumes de dados não estruturados de forma escalável, visando aplicações de processamento de linguagem natural (PLN).
2004: A UIMA foi disponibilizada como código aberto, permitindo uso mais amplo e contribuições de fora da IBM.
2006: O projeto UIMA foi aceito no Apache Incubator, iniciando o processo formal de se tornar um projeto Apache.
2008: A UIMA se formou no Apache Incubator e se tornou um projeto Apache de alto nível, significando sua maturidade e desenvolvimento ativo.
2009: O Apache UIMA-AS (Asynchronous Scaleout) foi introduzido, permitindo processamento distribuído e assíncrono de pipelines UIMA.
2012: O uimaFIT foi contribuído para o projeto Apache UIMA. O Apache uimaFIT era anteriormente conhecido como uimaFIT, que por sua vez era anteriormente conhecido como UUTUC. Antes de sua contribuição, foi um esforço colaborativo entre o Center for Computational Pharmacology da University of Colorado Denver, o Center for Computational Language and Education Research da University of Colorado at Boulder e o Ubiquitous Knowledge Processing (UKP) Lab da Technische Universität Darmstadt.
2013: O UIMA DUCC (Distributed UIMA Cluster Computing) foi introduzido como um subprojeto do Apache UIMA.
2016: O Apache UIMA Ruta (Rule-based Text Annotation) foi introduzido como uma extensão, fornecendo uma linguagem de script para processamento de texto baseado em regras.
2023: UIMA DUCC e UIMA-AS foram retirados.
2024: O uimaFIT foi mesclado ao UIMA Java SDK