2014-11-14 14 views
5

Sto cercando di estrarre le produzioni CNF-grammaticali di una frase dal suo albero di analisi:Chomsky-normale-forma di estrazione grammatica da un albero di analisi

(ROOT 
    (S 
    (NP (DT the) (NNS kids)) 
    (VP (VBD opened) 
     (NP (DT the) (NN box)) 
     (PP (IN on) 
     (NP (DT the) (NN floor)))))) 

ho messo l'albero buco in una stringa denominata S e quindi:

tree = Tree.fromstring(S) 
tree.chomsky_normal_form() 
for p in tree.productions(): 
    print p 

L'uscita è

(1) NN -> 'box' 
(2) PP -> IN NP 
(3) DT -> 'the' 
(4) ROOT -> S 
(5) NP -> DT NN 
(6) VBD -> 'opened' 
(7) VP|<NP-PP> -> NP PP 
(8) VP -> VBD VP|<NP-PP> 
(9) NP -> DT NNS 
(10) NN -> 'floor' 
(11) IN -> 'on' 
(12) NNS -> 'kids' 
(13) S -> NP VP 

Ma alcune delle produzioni (numero 7 & 8) non sembra essere CNF! Qual è il problema?

risposta

4

VP|<NP-PP> è uno simbolo non terminale. La barra verticale non significa più opzioni nel senso tradizionale. Piuttosto, NLTK lo colloca lì per indicare da dove viene derivata la regola, cioè "questo nuovo simbolo non terminale è stato derivato dalla combinazione di VP e NP-PP." È una nuova regola di produzione che NLTK ha creato per convertire la tua grammatica in forma normale di Chomsky.

Date un'occhiata alle produzioni della pianta, pre-CNF:

ROOT -> S 
S -> NP VP 
NP -> DT NNS 
DT -> 'the' 
NNS -> 'kids' 
VP -> VBD NP PP *** 
VBD -> 'opened' 
NP -> DT NN 
DT -> 'the' 
NN -> 'box' 
PP -> IN NP 
IN -> 'on' 
NP -> DT NN 
DT -> 'the' 
NN -> 'floor' 

In particolare, guarda la regola VP -> VBD NP PP, che non è in CNF (Ci deve essere esattamente due simboli non terminali sul RHS di qualsiasi regola di produzione)

Le due regole (7): VP|<NP-PP> -> NP PP e (8): VP -> VBD VP|<NP-PP> nella domanda sono funzionalmente equivalenti alla regola più generale VP -> VBD NP PP.

quando viene rilevato VP, risultati applicativi regola in:

VBD VP|<NP-PP>

E, VP|<NP-PP> è la sinistra della regola di produzione creata, che si traduce in:

VBD NP PP

Specificamente, se si isola la regola stessa, è possibile dare uno sguardo al simbolo specifico (che è davvero singolare):

>>> tree.chomsky_normal_form() 
>>> prod = tree.productions() 
>>> x = prod[7] # VP|<NP-PP> -> NP PP 
>>> x.lhs().symbol() # Singular! 
u'VP|<NP-PP>' 
+0

Quindi, come posso distinguere tra le barre che significano OR (che sono sempre sul RHS) con barre che non significano OR e possono verificarsi sia su RHS e LHS (come quella che hai citato)? – sabzdarsabz

+1

In quale contesto è necessario "distinguere" tra loro? Al livello più elementare, alimentando un simbolo non terminale sul LHS come 'VP | 'genererà un errore, in quanto i simboli non dovrebbero contenere spazi. Renditi conto anche che la specifica 'A -> B | C' è una scorciatoia per il più formale 'A -> B',' A -> C'. – jayelm

+1

Infatti, NLTK divide queste regole nelle loro forme costitutive, quindi a parte l'inserimento manuale di regole come 'A -> B | C', non troverai occorrenze di '|' che significa "opzioni multiple" nelle grammatiche NLTK. Prova 'nltk.CFG.fromstring (" A -> B | C ")', che crea una grammatica con due regole di produzione. – jayelm