2013-02-12 3 views
19

Ich habe einen Satz chunked mit:Wie navigiere ich in einem nltk.tree.Tree?

grammar = '''                            
    NP:                              
     {<DT>*(<NN.*>|<JJ.*>)*<NN.*>}                      
    NVN:                             
     {<NP><VB.*><NP>}                          
    ''' 
chunker = nltk.chunk.RegexpParser(grammar) 
tree = chunker.parse(tagged) 
print tree 

Das Ergebnis sieht so aus:

(S 
    (NVN 
    (NP The_Pigs/NNS) 
    are/VBP 
    (NP a/DT Bristol-based/JJ punk/NN rock/NN band/NN)) 
    that/WDT 
    formed/VBN 
    in/IN 
    1977/CD 
    ./.) 

Aber jetzt ich bin stecken versucht, herauszufinden, wie das navigieren. Ich möchte in der Lage sein, den NVN-Unterbaum zu finden und auf die linksseitige Nominalphrase ("The_Pigs"), das Verb ("are") und die rechtsseitige Nominalphrase ("eine Bristol-basierte Punkrockband") zuzugreifen. . Wie mache ich das?

+0

könnten Sie die vollständige Grammatik mit den Blattknoten zu veröffentlichen, dann kann ich Ihnen eine klare Beispiel? – alvas

Antwort

4

Try this:

for a in tree: 
     if type(a) is nltk.Tree: 
      if a.node == 'NVN': # This climbs into your NVN tree 
       for b in a: 
        if type(b) is nltk.Tree and b.node == 'NP': 
         print b.leaves() # This outputs your "NP" 
        else: 
         print b # This outputs your "VB.*" 

Es gibt dieses:

[('The_Pigs', 'NNS')]

('sind', 'VBP)

[('a', 'DT'), ('Bristol-basiert', 'JJ'), ('punk', 'NN'), ('rock', 'NN'), ('band', 'NN ')]

8

Sie könnten natürlich Ihre eigenen d schreiben epth erste Suche ... aber es gibt einen leichteren (besseren) Weg. Wenn Sie möchten, dass jeder Teilbaum in NVM verwurzelt ist, verwenden Sie die Teilbaummethode von Tree mit dem definierten Filterparameter.

>>> print t 
(S 
    (NVN 
     (NP The_Pigs/NNS) 
     are/VBP 
     (NP a/DT Bristol-based/JJ punk/NN rock/NN band/NN)) 
    that/WDT 
    formed/VBN 
    in/IN 
    1977/CD 
    ./.) 
>>> for i in t.subtrees(filter=lambda x: x.node == 'NVN'): 
...  print i 
... 
(NVN 
    (NP The_Pigs/NNS) 
    are/VBP 
    (NP a/DT Bristol-based/JJ punk/NN rock/NN band/NN)) 
+2

mit Python 3.5 und NLTK 3.2.2, sollte die Lambda-Funktion die label() -Eigenschaft von Knoten verwenden: filter = Lambda x: x.label() == "NP" – Maciej

14

Versuchen:

ROOT = 'ROOT' 
tree = ... 
def getNodes(parent): 
    for node in parent: 
     if type(node) is nltk.Tree: 
      if node.label() == ROOT: 
       print "======== Sentence =========" 
       print "Sentence:", " ".join(node.leaves()) 
      else: 
       print "Label:", node.label() 
       print "Leaves:", node.leaves() 

      getNodes(node) 
     else: 
      print "Word:", node 

getNodes(tree) 
+0

Ein anderes DFS-Beispiel (mit 'ParentedTree'): http : //stackoverflow.com/a/25972853/4115369 –

+0

Ja danke. Beachten Sie, dass sich die Benutzeroberfläche von NLTK über die Zeit ändern kann. – danger89

3

hier ist ein Codebeispiel

def filt(x): 
    return x.label()=='NP' 

for subtree in t.subtrees(filter = filt): # Generate all subtrees 
    print subtree 

für Geschwister alle Teilbäume mit einem Label 'NP' zur Erzeugung, könnten Sie einen Blick auf die Methode wollen nehmen ParentedTree.left_siblings()

für weitere Details, hier sind einige nützliche Links.

http://www.nltk.org/howto/tree.html #Some grundlegende Verwendung und Beispiel http://nbviewer.ipython.org/github/gmonce/nltk_parsing/blob/master/1.%20NLTK%20Syntax%20Trees.ipynb #a Notebook playwith dieser Methoden

http://www.nltk.org/_modules/nltk/tree.html #all api mit Quelle

Verwandte Themen