2013-02-21 16 views
13

Ho un (grande) lista di frasi analizzati (che sono stati analizzati utilizzando il parser Stanford), per esempio, la frase "ora che è possibile divertirsi" ha il seguente albero:Come utilizzare NLTK per generare frasi da una grammatica indotta?

(ROOT 
    (S 
    (ADVP (RB Now)) 
    (, ,) 
    (NP (PRP you)) 
    (VP (MD can) 
     (VP (VB be) 
     (VP (VBN entertained)))) 
    (. .))) 

Sto usando la set di alberi di frase per indurre una grammatica utilizzando NLTK:

import nltk 

# ... for each sentence tree t, add its production to allProductions 
allProductions += t.productions() 

# Induce the grammar 
S = nltk.Nonterminal('S') 
grammar = nltk.induce_pcfg(S, allProductions) 

Ora vorrei usare grammar per generare nuove, frasi casuali. La mia speranza è che, poiché la grammatica è stata appresa da una serie specifica di esempi di input, le frasi generate saranno semanticamente simili. Posso farlo in nltk?

Se non riesco a utilizzare nltk per eseguire questa operazione, esistono altri strumenti che possono utilizzare lo grammar (eventualmente riformattato) e generare frasi?

+0

In stesso posto, per favore controlla questo filo http: //stackoverflow.com/questions/39061349/paraphrasing-using-nltk –

risposta

4

Prima di tutto, se si generano frasi casuali, potrebbero essere semanticamente corrette, ma probabilmente perderanno il loro senso.

(è Suona per me un po 'come quegli studenti del MIT ha fatto con il loro SCIgen program che è auto-generazione di documento scientifico. Molto interessante btw.)

In ogni caso, non ho mai fatto io, ma sembra possibile con nltk.bigrams, è possibile passare a have a look there in Generare testo casuale con Bigram.

È inoltre possibile generate all subtrees of a current tree, non sono sicuro se è quello che vuoi sia.

12

In NLTK 2.0 è possibile utilizzare per generare nltk.parse.generatetutti possibile sentences for a given grammar.

Questo codice definisce una funzione che dovrebbe generare una singola frase basata sulle regole di produzione in un (P) CFG.

# This example uses choice to choose from possible expansions 
from random import choice 
# This function is based on _generate_all() in nltk.parse.generate 
# It therefore assumes the same import environment otherwise. 
def generate_sample(grammar, items=["S"]): 
    frags = [] 
    if len(items) == 1: 
     if isinstance(items[0], Nonterminal): 
      for prod in grammar.productions(lhs=items[0]): 
       frags.append(generate_sample(grammar, prod.rhs())) 
     else: 
      frags.append(items[0]) 
    else: 
     # This is where we need to make our changes 
     chosen_expansion = choice(items) 
     frags.append(generate_sample,chosen_expansion) 
    return frags 

Per usufruire dei pesi nel vostro PCFG, si ovviamente desidera utilizzare un metodo di campionamento migliore rispetto choice(), che presuppone implicitamente tutte le espansioni del nodo corrente sono equiprobabili.

2

La mia soluzione per generare una frase a caso da un nltk.CFG grammatica esistente:

def generate_sample(grammar, prod, frags):   
    if prod in grammar._lhs_index: # Derivation 
     derivations = grammar._lhs_index[prod]    
     derivation = random.choice(derivations)    
     for d in derivation._rhs:    
      generate_sample(grammar, d, frags) 
    elif prod in grammar._rhs_index: 
     # terminal 
     frags.append(str(prod)) 

E ora può essere utilizzato:

frags = [] 
generate_sample(grammar, grammar.start(), frags) 
print(' '.join(frags)) 
+1

La riga 'generate_sample (d, frags)' dovrebbe leggere 'generate_sample (grammar, d, frags)'. –

Problemi correlati