在 Stanford CoreNLP 流水线中输入 Penn Treebank 组成树

Input Penn Treebank constituent trees in a Stanford CoreNLP pipeline

我正在使用斯坦福 NLP 库中的 OpenIE 工具从句子中获取最少的从句。这是我到目前为止的想法(主要是从他们的演示代码中获得灵感):

public static void main(String[] args) {
    Properties props = new Properties();
    props.setProperty("annotators", "tokenize,ssplit,pos,lemma,depparse,natlog,openie");
    StanfordCoreNLP pipeline = new StanfordCoreNLP(props);

    Annotation doc = new Annotation("Obama was born in Hawaii. He is our president.");
    pipeline.annotate(doc);

    for (CoreMap sentence : doc.get(CoreAnnotations.SentencesAnnotation.class)) {

        OpenIE split = new OpenIE(props);
        List<SentenceFragment> clauses = split.clausesInSentence(sentence);
        for (SentenceFragment clause : clauses) {
            List<SentenceFragment> short_clauses = split.entailmentsFromClause(clause);
            for (SentenceFragment short_clause : short_clauses){
                System.out.println(short_clause.parseTree);
            }
        }
    }
}

我现在想使用 PTB 组成树作为输入而不是纯文本,然后只使用 depparsenatlogopenie 注释器获取子句。

我知道我可以使用 PTB 树作为 Stanford 解析器的输入(如解释的 here),但还没有想出如何将其集成到管道中。

这是我认为其实不平凡的。如果有人在管道中有一个干净的方法来做到这一点,请插话!但是,如果我要这样做,我可能只是手动调用代码的组件位。这意味着:

  • 从选区树的GrammaticalStructure创建一个SemanticGraph对象。

  • 为语义图中的每个IndexedWord添加一个词条注释。这可以通过在每个标记上调用 Morphology#lemma(word, posTag) 并将 LemmaAnnotation 设置为此来完成。

  • 运行 通过自然逻辑注释器会很棘手。一种选择是模拟一个 Annotation 对象并通过通常的 annotate() 方法推送它。但是,如果您不太关心 OpenIE 系统识别否定,您可以通过将值 Polarity#DEFAULT 添加到 SemanticGraph 键上的每个标记来跳过此注释器。

  • 现在您的依赖关系树应该准备好通过 OpenIE 注释器了。你想在这里打三个电话:

    • OpenIE#clausesInSentence(SemanticGraph) 将从给定的图形中生成一组子句。
    • OpenIE#entailmentsFromClause(SentenceFragment) 将从每个子句生成短蕴涵。您想将上述函数的每个输出传递给它,并收集所有生成的片段。
    • OpenIE#relationsInFragment(SentenceFragment) 会将一个短蕴涵分割成一个关系三元组。它 returns 和 Optional -- 大多数片段不分割成任何三元组。您想要将从上述调用中收集的每个短蕴涵传递给此函数,并收集在此函数的输出中定义的关系三元组。这些是您的 OpenIE 三元组。

出于好奇,你到底想做什么?也许有更简单的方法来实现相同的目标。