在 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 组成树作为输入而不是纯文本,然后只使用 depparse、natlog 和 openie 注释器获取子句。
我知道我可以使用 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 三元组。
出于好奇,你到底想做什么?也许有更简单的方法来实现相同的目标。
我正在使用斯坦福 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 组成树作为输入而不是纯文本,然后只使用 depparse、natlog 和 openie 注释器获取子句。
我知道我可以使用 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 三元组。
出于好奇,你到底想做什么?也许有更简单的方法来实现相同的目标。