当前位置: 首页 > 知识库问答 >
问题:

使用UIMA和斯坦福核心NLP

咸疏珂
2023-03-14

UIMA和StanfordNLP在流水线操作之后生成输出,比如如果我们想做词性标记,那么在输入文本中首先进行标记化,然后进行词性标记。

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

那么,是否可以在同一管道中使用不同的API?是否可以同时使用UIMA标记器和Stanford CoreNLP?

共有2个答案

戚承业
2023-03-14

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

>

  • 强制CoreNLP忽略这些要求。

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

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

    向管道中添加自定义注释器。

    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的浓缩版本。

  • 葛书
    2023-03-14

    在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)))))
    

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

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

    披露:我正在从事DKPro核心和Apache UIMA uimaFIT项目。

     类似资料:
    • 我曾使用grep和awk从斯坦福CRF-NER的“内联XML”中提取英语文本中的命名实体,我希望在其他人类语言中使用相同的更大工作流。 我一直在尝试法语(西班牙语似乎给我带来了一个Java错误,这是另一个故事),并使用我得到标准文本输出,每个句子都有各种类型的注释,包括正确组合在一起的多单词实体,如下所示: 我知道解析它是可能的,但当我真的只是想要整个文件中的实体列表时,这似乎浪费了很多处理。 我

    • 我是Java和Stanford NLP工具包的新手,并试图在一个项目中使用它们。具体地说,我尝试使用Stanford Corenlp toolkit来注释文本(使用Netbeans而不是命令行),并尝试使用http://nlp.Stanford.edu/software/Corenlp.shtml#Usage上提供的代码(使用Stanford Corenlp API)。问题是:有人能告诉我如何在文

    • 有人能让我知道核心NLP的区别吗 http://stanfordnlp.github.io/CoreNLP/ 斯坦福大学NLP http://nlp.stanford.edu/

    • 它工作得很好,但需要很多时间;假设我们在一个问答系统中使用它,那么对于每一个新的输入,都必须运行pipeAnnotation。正如你所知道的,每次都要提取一些规则,训练一些数据等,以生成一个带有NLP标记的句子,如POS,NER和...... 首先,我想用RMI和EJB解决这个问题,但是失败了,因为不管是什么JAVA架构,对于每一个新的句子,pipeAnnotation都应该从头开始学习。查看in

    • 我正在注释和分析一系列文本文件。 pipeline.annotate方法每次读取文件时都会变得越来越慢。最终,我得到了一个OutOfMemoryError。 管道初始化一次: 然后,我使用相同的管道实例处理每个文件(如SO和斯坦福大学在其他地方推荐的)。 明确地说,我希望问题出在我的配置上。但是,我确信失速和内存问题发生在pipeline.annotate(file)方法上。 在处理每个文件后,我

    • 我是斯坦福核心NLP的新手。我想用它来从英语,德语,法语的文本中拆分句子。这是哪一个班的工作?提前谢谢。