2009-07-19 13 views
7

У меня возникают проблемы с NLTK под Python, в частности методом .generate().Создание случайных предложений из пользовательского текста в NLTK Python?

генерации (самостоятельная, длина = 100)

печати случайный текст, сгенерированный с использованием модели языка Триграмма.

Параметры:

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

Вот упрощенная версия того, что я пытаюсь.

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) 

Это всегда генерировать

Building ngram index... 
The quick brown 
None 

В отличие от построения случайной фразы из слов.

Вот мой выходной, когда я

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 

Опять же, начиная с того же самого текста, но затем изменяя его. Я также попытался использовать первую главу из 1984 года Оруэлла. Снова, что всегда начинается с первых 3 жетонов (один из которых является пространством в этом случае) и , тогда продолжает случайное генерирование текста.

Что я здесь делаю неправильно?

ответ

-1

Возможно, вы можете отсортировать массив токенов случайным образом, прежде чем генерировать предложение.

+1

NLTK использует контекст слов для определения их использования. Например, они имеют весь текст «Моби Дика» в NLTK для примера. Использование генерации с этим будет генерировать звуковые предложения Meville. Поэтому, если вы не знаете чего-то, чего я не знаю, я предполагаю, что вы не хотите прибегать к словам, потому что исходный контекст является значительным. –

+1

Вы правы. Если вы перетасовываете слова, вы теряете информацию о том, что все триграммы. – Mastermind

-1

Вы уверены, что используете word_tokenize правильный подход?

This Google groups page имеет пример:

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

Но я никогда не использовал NLTK, так что я не могу сказать, работает ли это так, как вы хотите.

+1

nltk.corpus.brown.words() - это всего лишь совокупность слов, которые поставляются с NLTK. Я пытаюсь засеять генератор своими словами. –

+0

Вы сравнили свой собственный токен с коричневым корпусом? – Mastermind

1

Ваш образец корпуса скорее всего будет слишком мал. Я не знаю, как именно nltk строит свою модель триграмм, но обычной практикой является то, что начало и конец предложений обрабатываются каким-то образом. Поскольку в вашем корпусе есть только одно начало предложения, это может быть причиной того, что каждое предложение имеет одно и то же начало.

+0

Ну, это был образец для целей SO. Мой фактический образец больше. Итак, вам нужны знаки препинания, чтобы компенсировать предложения? –

+0

I thoght так, но если вы уже пробовали целую главу Оруэлла (с пунктуацией, которую я предполагаю), я думаю, я был неправ. – Mastermind

9

Чтобы сгенерировать случайный текст, U нужно использовать Markov Chains

код, чтобы сделать это: 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) 

Explaination: Generating pseudo random text with Markov chains using Python

7

Вы должны быть "обучение" модели Маркова с несколькими последовательностями , так что вы точно проберете вероятности начального состояния (так называемый «pi» в марковском разговоре). Если вы используете одну последовательность, вы всегда будете в том же состоянии.

В случае 1984 года Оруэлла вы хотели бы сначала использовать токенирование предложения (NLTK очень хорош в этом), а затем токенизация слова (приводящий список списков токенов, а не только один список токенов), а затем каждое предложение отдельно к марковской модели. Это позволит ему правильно моделировать запуск последовательности, вместо того, чтобы застрять на одном пути, чтобы начать каждую последовательность.