使用UIMA,Stanford Corenlp

时间:2014-06-05 04:25:23

标签: nlp tokenize stanford-nlp opennlp uima

UIMA和StanfordNLP在操作流程之后产生输出,就像我们想要进行POS标记一样,所以在输入文本中首先进行标记化,然后进行POS标记。

我想使用UIMA的标记化,并在Standford CoreNLP的POS标记器中使用该标记。但是Standford CoreNLP的POS标签需要在POS标记之前运行标记器。

那么,是否可以在同一管道中使用不同的API? 是否可以将UIMA tokenizer和Standford CoreNLP一起使用?

请帮忙。

2 个答案:

答案 0 :(得分:5)

在UIMA中组合来自不同工具链(例如OpenNLPStanford CoreNLP等)的分析步骤的典型方法是将每个工具链包装为UIMA分析引擎。分析引擎充当UIMA数据结构(CAS)之间的适配器,并且使用的数据结构是各个工具(例如OpenNLP POS标记器或CoreNLP解析器)。在UIMA级别,这些组件可以组合成管道。

有各种各样的UIMA组件包装这样的工具链,例如: ClearTKDKPro CoreU-Compare

以下示例结合了OpenNLP分段器(标记器/句子分割器)和Stanford CoreNLP解析器(在本示例中也创建了POS标签)。该示例实现为Groovy脚本,使用uimaFIT API使用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)))))

我以Groovy脚本为例,因为它开箱即用。 Java程序看起来非常相似,但通常会使用例如Java程序。 Maven或Ivy获取所需的库。

如果您想尝试脚本并需要有关安装Groovy和潜在故障排除的更多信息,可以找到更多信息here

披露:我正在开发DKPro Core和Apache UIMA uimaFIT项目。

答案 1 :(得分:4)

如果要将CoreNLP用作管道,至少有两种方法可以处理此问题。

  1. 强制CoreNLP忽略这些要求。

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

    这将消除“缺少要求”错误。但是,CoreNLP中的POSTaggerAnnotator期望令牌为CoreLabel对象,并且期望句子为CoreMap对象(实例化为ArrayCoreMap),因此您必须转换它们。

  2. 将自定义注释器添加到管道中。

    CoreMaps / CoreLabels是带有类作为键的映射,因此您需要一个用于自定义注释的类/键:

    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();
        }
    
    }
    

    最后:

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

    UIMA / OpenNLP /等。可以以类似的方式将句子注释添加为自定义注释器。 查看http://nlp.stanford.edu/software/corenlp-faq.shtml#custom以获取选项#2的精简版本。