2013-02-21 11 views
13

mam (duży) wykaz analizowanych zdań (które były analizowana z wykorzystaniem parser Stanford), na przykład zdanie: „Teraz można się bawić” ma następujące drzewa:Jak używać NLTK do generowania zdań z indukowanej gramatyki?

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

Używam zestaw drzew zdanie do wywołania gramatykę używając 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) 

teraz chciałbym użyć grammar do generowania nowych, przypadkowych zdań. Mam nadzieję, że skoro gramatyka została wyuczona z określonego zbioru przykładów wejściowych, to wygenerowane zdania będą semantycznie podobne. Czy mogę to zrobić w Nltk?

Jeśli nie mogę użyć nltk, aby to zrobić, czy istnieją jakieś inne narzędzia, które mogą zająć (prawdopodobnie przeformatowane) grammar i generować zdania?

+0

W tym samym miejscu, proszę sprawdzić ten wątek http: //stackoverflow.com/questions/39061349/paraphrasing-using-nltk –

Odpowiedz

4

Po pierwsze, jeśli generujesz losowe zdania, mogą one być semantycznie poprawne, ale prawdopodobnie stracą sens.

(to brzmi dla mnie trochę jak tych studentów MIT zrobili z ich SCIgen program który jest automatycznie generując pracę naukową. Bardzo interesujący btw.)

W każdym razie, nigdy nie zrobił to sam, ale wydaje się możliwe z nltk.bigrams, możesz przejść do have a look there pod Generowanie losowego tekstu z Bigrams.

Możesz również generate all subtrees of a current tree, nie jestem pewien, czy to jest to, co chcesz.

12

W NLTK 2.0 można użyć nltk.parse.generate wygenerować wszystkie możliwie sentences for a given grammar.

Ten kod definiuje funkcję, która powinna generować pojedyncze zdanie na podstawie reguł produkcji w (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 

Aby skorzystać z ciężarkami w PCFG, będziesz oczywiście chcą wykorzystywać lepszą metodę próbkowania niż choice(), która niejawnie przyjmuje wszystkie ekspansje bieżącego węzła są jednakowo prawdopodobne.

2

Moje rozwiązanie do generowania losowego zdania z istniejącego nltk.CFG gramatyki:

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

A teraz może być używany:

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

Wiersz 'generate_sample (d, frags)' powinien odczytać 'generate_sample (gramatyka, d, frags)'. –

Powiązane problemy