2013-02-12 7 views
19

Ho chunked una frase utilizzando:Come navigare in un nltk.tree.Tree?

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

Il risultato è simile:

(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 
    ./.) 

Ma ora mi sono bloccato cercando di capire come navigare questo. Voglio essere in grado di trovare la sottostruttura NVN e accedere alla frase di sinistra ("The_Pigs"), al verbo ("sono") e alla frase di nome a destra ("una band punk rock basata a Bristol") . Come lo faccio?

+0

potrebbe si registra la completa grammatica con i nodi foglia, allora ti posso dare una chiara esempio? – alvas

risposta

4

Prova questo:

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.*" 

E Risulterà:

[('The_Pigs', 'NNS')]

('sono', 'VBP')

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

8

Si potrebbe, naturalmente, scrivere il proprio d prima ricerca ... ma c'è un modo (migliore) più semplice. Se si desidera che ogni sottostruttura sia radicata su NVM, utilizzare il metodo della sottostruttura di Tree con il parametro del filtro definito.

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

con Python 3.5 e NLTK 3.2.2, la funzione lambda dovrebbe utilizzare la proprietà label() del nodo: filter = lambda x: x.label() == "NP" – Maciej

14

Prova:

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

Un altro esempio DFS (con 'ParentedTree'): http : //stackoverflow.com/a/25972853/4115369 –

+0

Sì grazie. Siate consapevoli che l'interfaccia di NLTK può cambiare gli straordinari. – danger89

3

ecco un esempio di codice per la generazione di tutte le sottostrutture con un'etichetta 'NP'

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

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

per i fratelli, si potrebbe desiderare di dare un'occhiata al metodo ParentedTree.left_siblings()

per ulteriori dettagli, ecco alcuni link utili.

http://www.nltk.org/howto/tree.html # Alcuni uso di base e con l'esempio http://nbviewer.ipython.org/github/gmonce/nltk_parsing/blob/master/1.%20NLTK%20Syntax%20Trees.ipynb #a notebook visualizzarloWith questi metodi

http://www.nltk.org/_modules/nltk/tree.html #all API con fonte