2009-07-19 11 views
7

Mam problem z NLTK w Pythonie, w szczególności z metodą .generate().Generowanie losowych zdań z własnego tekstu w języku NLTK w Pythonie?

generowanie (self, długość = 100)

Print losowy tekst, wygenerowane przy użyciu modelu języka trygram.

Parametry:

* length (int) - The length of text to generate (default=100) 

Oto uproszczona wersja tego, co mam próby.

import nltk 

words = 'The quick brown fox jumps over the lazy dog' 
tokens = nltk.word_tokenize(words) 
text = nltk.Text(tokens) 
print text.generate(3) 

Będzie zawsze generować

Building ngram index... 
The quick brown 
None 

W przeciwieństwie do budowania losowy zdanie z tych słów.

Oto moje wyjście kiedy robię

print text.generate() 

Building ngram index... 
The quick brown fox jumps over the lazy dog fox jumps over the lazy 
dog dog The quick brown fox jumps over the lazy dog dog brown fox 
jumps over the lazy dog over the lazy dog The quick brown fox jumps 
over the lazy dog fox jumps over the lazy dog lazy dog The quick brown 
fox jumps over the lazy dog the lazy dog The quick brown fox jumps 
over the lazy dog jumps over the lazy dog over the lazy dog brown fox 
jumps over the lazy dog quick brown fox jumps over the lazy dog The 
None 

Znowu zaczynasz z tym samym tekstem, ale następnie zmieniając go. Próbowałem także użyć pierwszego rozdziału z 1984 Orwella. Znowu, zawsze zaczyna się od pierwszych 3 tokenów (z których jednym jest w tym przypadku spacja) i , a następnie przechodzi do losowego generowania tekstu.

Co ja tu robię źle?

Odpowiedz

-1

Być może możesz losowo sortować tablice żetonów przed wygenerowaniem zdania.

+1

NLTK używa kontekstu słów do określenia ich użycia. Na przykład mają na przykład cały tekst "Moby Dick" w NLTK. Korzystanie z generowania tego wygeneruje zdania brzmiące w Meville. Więc jeśli nie wiesz czegoś, czego nie robię, zakładam, że nie chcesz uciec się do słów, ponieważ początkowy kontekst jest znaczący. –

+1

masz rację. Jeśli przetasujesz słowa, tracisz informacje, którymi są trygramy. – Mastermind

-1

Czy jesteś pewien, że właściwe jest zastosowanie metody word_tokenize?

This Google groups page ma przykład:

>>> import nltk 
>>> text = nltk.Text(nltk.corpus.brown.words()) # Get text from brown 
>>> text.generate() 

Ale nigdy nie używałem NLTK, więc nie mogę powiedzieć, czy działa tak, jak chcesz.

+1

nltk.corpus.brown.words() to tylko zbiór słów, które są dostarczane z NLTK. Próbuję zasiać generator własnymi słowami. –

+0

Czy porównałeś własną tokenlistę z brązowym ciałem? – Mastermind

1

Twój przykładowy korpus jest najprawdopodobniej za mały. Nie wiem, jak dokładnie nltk buduje swój trygramowy model, ale powszechną praktyką jest, że jakoś rozwiązuje się początek i koniec zdań. Ponieważ w twoim korpusie jest tylko jeden początek zdania, może to być powodem, dla którego każde zdanie ma ten sam początek.

+0

Cóż, to była próbka do celów SO. Moja rzeczywista próbka jest większa. Czy potrzebujesz interpunkcji, aby zrównoważyć zdania? –

+0

Tak, ale jeśli już wypróbowałeś cały rozdział Orwella (z interpunkcją, zakładam), myślę, że się myliłem. – Mastermind

9

Aby wygenerować losowy tekst, U trzeba użyć Markov Chains

kod, aby to zrobić: from here

import random 

class Markov(object): 

    def __init__(self, open_file): 
    self.cache = {} 
    self.open_file = open_file 
    self.words = self.file_to_words() 
    self.word_size = len(self.words) 
    self.database() 


    def file_to_words(self): 
    self.open_file.seek(0) 
    data = self.open_file.read() 
    words = data.split() 
    return words 


    def triples(self): 
    """ Generates triples from the given data string. So if our string were 
    "What a lovely day", we'd generate (What, a, lovely) and then 
    (a, lovely, day). 
    """ 

    if len(self.words) < 3: 
     return 

    for i in range(len(self.words) - 2): 
     yield (self.words[i], self.words[i+1], self.words[i+2]) 

    def database(self): 
    for w1, w2, w3 in self.triples(): 
     key = (w1, w2) 
     if key in self.cache: 
    self.cache[key].append(w3) 
     else: 
    self.cache[key] = [w3] 

    def generate_markov_text(self, size=25): 
    seed = random.randint(0, self.word_size-3) 
    seed_word, next_word = self.words[seed], self.words[seed+1] 
    w1, w2 = seed_word, next_word 
    gen_words = [] 
    for i in xrange(size): 
     gen_words.append(w1) 
     w1, w2 = w2, random.choice(self.cache[(w1, w2)]) 
    gen_words.append(w2) 
    return ' '.join(gen_words) 

wyjaśnieniu: Generating pseudo random text with Markov chains using Python

7

powinna być "szkolenie" model Markowa z wieloma sekwencjami , aby dokładnie wypróbować także prawdopodobieństwa stanu początkowego (zwane "pi" w Markov-speak). Jeśli użyjesz pojedynczej sekwencji, zawsze zaczniesz w tym samym stanie.

W przypadku 1984 Orwella chciałbyś najpierw użyć tokenizacji zdania (NLTK jest w tym bardzo dobry), a następnie tokenizacji słowa (tworząc listę list tokenów, a nie tylko jedną listę żetonów), a następnie podać każde zdanie oddzielnie do modelu Markowa. Umożliwi to prawidłowe modelowanie sekwencji, zamiast utknąć w jeden sposób, aby rozpocząć każdą sekwencję.

Powiązane problemy