2014-06-05 5 views
2

UIMA와 StanfordNLP는 입력 텍스트에서 토큰 화를 수행 한 다음 POS 태깅을 수행 할 때 POS 태깅을 수행하려는 경우처럼 파이프 라인 작업 후에 출력을 생성합니다.UIMA, Standford Core NLP 함께 사용

UIMA의 토큰 화를 사용하고 Standford CoreNLP의 POS 태거에서 해당 토큰을 사용하고 싶습니다. 그러나 Standford CoreNLP의 POS tagger는 POS tagger 이전에 tokenizer를 실행해야합니다.

따라서 동일한 API에서 다른 API를 사용할 수 있습니까? UIMA 토큰 화기와 Standford CoreNLP를 함께 사용할 수 있습니까?

도와주세요.

+0

스탠포드 토크 나이저의 UIMA 토크 나이저는 어떻게 다릅니 까? – Daniel

+0

또한 왜 UIMA tokenizer를 사용하고 싶은지 알지 못합니다. – Daniel

+0

@ Daniel UIMA와 Standford Tokenizer의 다른 점은 다른 데이터 구조로 출력을 제공한다는 것입니다. 이러한 데이터 구조에서 토큰을 추출 할 수 있지만 Standford POS Tagger의 POS 태깅에서 UIMA 토큰 화 도구로 만든 토큰을 사용하는 방법 같은 속성으로 Standford POS를 실행하려고합니다. 속성 props = new Properties(); props.put ("annotators", "tokenize, ssplit, pos"); 다음과 같이 실행하려고하면 : 속성 props = new Properties(); props.put ("annotators", "pos"); 토크 나이저로 인해 오류가 발생하고 ssplit가 누락되었습니다. – Kshitij

답변

5

UIMA에서 서로 다른 툴 체인 (예 : OpenNLP, Stanford CoreNLP 등)의 분석 단계를 결합하는 일반적인 방법은 UIMA 분석 엔진으로 각각을 랩핑하는 것입니다. 분석 엔진은 UIMA 데이터 구조 (CAS)와 개별 도구 (예 : OpenNLP POS 태그러 또는 CoreNLP 파서)로 사용되는 데이터 구조 간의 어댑터 역할을합니다. 그런 다음 UIMA 수준에서 이러한 구성 요소를 파이프 라인으로 결합 할 수 있습니다.

이러한 도구 체인을 래핑하는 UIMA 구성 요소의 다양한 컬렉션이 있습니다. ClearTK, DKPro Core 또는 U-Compare입니다.

다음 예는 OpenNLP 분류기 (토큰 화기/문장 분할기)와 Stanford CoreNLP 파서 (이 예에서 POS 태그를 생성 함)를 결합한 것입니다. 이 예는 uimaFIT API을 사용하는 Groovy 스크립트로 구현되어 DKPro Core 컬렉션의 구성 요소를 사용하여 파이프 라인을 만들고 실행합니다. (로그 출력을 많이 후)

#!/usr/bin/env groovy 
@Grab(group='de.tudarmstadt.ukp.dkpro.core', 
     module='de.tudarmstadt.ukp.dkpro.core.opennlp-asl', 
     version='1.5.0') 
@Grab(group='de.tudarmstadt.ukp.dkpro.core', 
     module='de.tudarmstadt.ukp.dkpro.core.stanfordnlp-gpl', 
     version='1.5.0') 

import static org.apache.uima.fit.pipeline.SimplePipeline.*; 
import static org.apache.uima.fit.util.JCasUtil.*; 
import static org.apache.uima.fit.factory.AnalysisEngineFactory.*; 
import org.apache.uima.fit.factory.JCasFactory; 

import de.tudarmstadt.ukp.dkpro.core.opennlp.*; 
import de.tudarmstadt.ukp.dkpro.core.stanfordnlp.*; 
import de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.*; 
import de.tudarmstadt.ukp.dkpro.core.api.syntax.type.*; 

def jcas = JCasFactory.createJCas(); 
jcas.documentText = "This is a test"; 
jcas.documentLanguage = "en"; 

runPipeline(jcas, 
    createEngineDescription(OpenNlpSegmenter), 
    createEngineDescription(StanfordParser, 
    StanfordParser.PARAM_WRITE_PENN_TREE, true)); 

select(jcas, Token).each { println "${it.coveredText} ${it.pos.posValue}" } 

select(jcas, PennTree).each { println it.pennTree } 

그것의 출력은 다음과 같아야합니다 : 그것은 상자 밖으로 작동하기 때문에

This DT 
is VBZ 
a DT 
test NN 
(ROOT 
    (S 
    (NP (DT This)) 
    (VP (VBZ is) 
     (NP (DT a) (NN test))))) 

나는 예제로 그루비 스크립트를했다. Java 프로그램은 매우 유사하지만 일반적으로 예를 들어 Maven 또는 Ivy를 사용하여 필요한 라이브러리를 얻습니다.

스크립트를 사용하고 Groovy 설치 및 잠재적 인 문제 해결에 대한 자세한 정보가 필요하면 here을 참조하십시오.

공개 : DKPro Core 및 Apache UIMA uimaFIT 프로젝트를 진행하고 있습니다.

4

CoreNLP를 파이프 라인으로 사용하려면이 작업을 처리하는 방법이 적어도 두 가지가 있습니다.

  1. CoreNLP가 요구 사항을 무시하도록합니다.

    Properties props = new Properties(); 
    props.put("enforceRequirements", "false"); 
    props.put("annotators", "pos"); 
    

    이렇게하면 "누락 된 요구 사항"오류가 제거됩니다. 그러나 CoreNLP의 POSTaggerAnnotator는 토큰이 CoreLabel 객체이기를 기대하며 문장을 CoreMap 객체 (ArrayCoreMap으로 인스턴스화)로 예상하므로 변환해야합니다.

  2. 파이프 라인에 사용자 지정 주석자를 추가하십시오.

    public class CustomAnnotations {   
    
        //this class will act as a key 
        public static class UIMATokensAnnotation 
          implements CoreAnnotation<List<CoreLabel>> {   
    
         //getType() defines/restricts the Type of the value associated with this key 
         public Class<List<CoreLabel>> getType() { 
          return ErasureUtils.<Class<List<CoreLabel>>> uncheckedCast(List.class); 
         } 
        } 
    } 
    

    당신은 또한 주석 자 클래스가 필요합니다 :

    public class UIMATokensAnnotator implements Annotator{ 
    
        //this constructor signature is expected by StanfordCoreNLP.class 
        public UIMATokensAnnotator(String name, Properties props) { 
         //initialize whatever you need 
        } 
    
        @Override 
        public void annotate(Annotation annotation) { 
         List<CoreLabel> tokens = //run the UIMA tokenization and convert output to CoreLabels 
         annotation.set(CustomAnnotations.UIMATokensAnnotation.class, tokens); 
        } 
    
        @Override 
        public Set<Requirement> requirementsSatisfied() { 
         return Collections.singleton(TOKENIZE_REQUIREMENT); 
        } 
    
        @Override 
        public Set<Requirement> requires() { 
         return Collections.emptySet(); 
        } 
    
    } 
    

    CoreMaps을/CoreLabels는 사용자 정의 주석에 대한 클래스/키가 필요합니다 그래서 키와 같은 클래스와지도는 마지막으로 :

    props.put("customAnnotatorClass.UIMAtokenize", "UIMATokensAnnotator") 
    props.put("annotators", "UIMAtokenize, ssplit, pos") 
    

    UIMA/OpenNLP/etc. 문장 어노테이션은 유사한 방식으로 커스텀 어노 테이터로 추가 될 수 있습니다. 옵션 # 2 압축 버전의 경우 http://nlp.stanford.edu/software/corenlp-faq.shtml#custom을 확인하십시오.