问题
I have this parse tree here:
What I want is to get all words from a common parent given a word in the set of children of a subtree. For example if you take the word "bottles" then I want to get "the Voss bottles" or maybe even "the Voss bottles of water" but I don't know how to do that.
Annotation document = new Annotation(sentenceText);
this.pipeline.annotate(document);
List<CoreMap> sentences = document.get(SentencesAnnotation.class);
for (CoreMap sentence : sentences) {
Tree tree = sentence.get(TreeAnnotation.class);
List<Tree> leaves = new ArrayList<>();
leaves = tree.getLeaves(leaves);
for (Tree leave : leaves) {
String compare = leave.toString().toLowerCase();
if(compare.equals(word) == true) {
// Get other nodes in the same subtree
}
}
}
Calling leave.parent()
does not work. I also tried tree.parent(leave)
but that doesn't work either (returns null
).
I also tried
for (Tree leave : tree) {
String compare = leave.toString().toLowerCase();
if(compare.equals(word) == true) {
// ..
}
}
but I get the same.
public Tree parent(Tree root)
Return the parent of the tree node. This routine will traverse a tree (depth first) from the given root, and will correctly find the parent, regardless of whether the concrete class stores parents. It will only return null if this node is the root node, or if this node is not contained within the tree rooted at root.
How can I manage to do that? #EverythingIsBrokenAllTheTime
回答1:
This example line should give you two levels up for a given word (note that there are nodes for POS tags, so you need to do parent twice ; the first parent returns the subtree with the POS tag as the root)
Tree root = (leave.parent(tree)).parent(tree);
"leave" should be the node for the word "tree" should be the tree for the entire sentence
This method goes through the tree from the root, keeping track of the nodes it passes through. When it hits the node you want (in this example "leave") it returns the appropriate parent.
full code:
import java.io.*;
import java.util.*;
import edu.stanford.nlp.io.*;
import edu.stanford.nlp.ling.*;
import edu.stanford.nlp.pipeline.*;
import edu.stanford.nlp.trees.*;
import edu.stanford.nlp.trees.TreeCoreAnnotations.*;
import edu.stanford.nlp.semgraph.*;
import edu.stanford.nlp.ling.CoreAnnotations.*;
import edu.stanford.nlp.util.*;
public class RootFinderExample {
public static void main (String[] args) throws IOException {
// build pipeline
Properties props = new Properties();
props.setProperty("annotators","tokenize, ssplit, pos, lemma, ner, parse");
StanfordCoreNLP pipeline = new StanfordCoreNLP(props);
String text = "We were offered water for the table but were not told the Voss bottles of water were $8 a piece.";
Annotation annotation = new Annotation(text);
pipeline.annotate(annotation);
List<CoreMap> sentences = annotation.get(SentencesAnnotation.class);
for (CoreMap sentence : sentences) {
Tree tree = sentence.get(TreeAnnotation.class);
List<Tree> leaves = new ArrayList<>();
leaves = tree.getLeaves(leaves);
for (Tree leave : leaves) {
String compare = leave.toString().toLowerCase();
if(compare.equals("bottles") == true) {
System.out.println(tree);
System.out.println("---");
System.out.println(leave);
System.out.println(leave.parent(tree));
System.out.println((leave.parent(tree)).parent(tree));
}
}
}
}
}
来源:https://stackoverflow.com/questions/34928739/how-to-get-the-root-node-in-stanford-parse-tree