¿Generando oraciones al azar a partir de texto personalizado en NLTK de Python?

Estoy teniendo problemas con el NLTK en Python, específicamente con el método .generate ().

generar (auto, longitud = 100)

Imprimir texto aleatorio, generado utilizando un modelo de lenguaje trigtwig.

Parámetros:

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

Aquí hay una versión simplificada de lo que estoy intentando.

 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) 

Esto siempre generará

 Building ngram index... The quick brown None 

A diferencia de construir una frase al azar a partir de las palabras.

Aquí está mi salida cuando lo hago

 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 

Nuevamente comenzando con el mismo texto, pero luego variándolo. También he intentado usar el primer capítulo de Orwell en 1984. De nuevo, eso siempre comienza con las primeras 3 fichas (una de las cuales es un espacio en este caso) y luego continúa para generar texto de forma aleatoria.

¿Qué estoy haciendo mal aquí?

Para generar texto aleatorio, U necesita usar cadenas de Markov

Código para hacer eso: desde aquí.

 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) 

Explicación: generar texto pseudoaleatorio con cadenas de Markov usando Python

Debería estar “entrenando” el modelo de Markov con múltiples secuencias, de modo que también muestre con precisión las probabilidades del estado inicial (llamado “pi” en el lenguaje Markov). Si utiliza una secuencia única, siempre comenzará en el mismo estado.

En el caso de Orwell’s 1984, querría usar la tokenización de oraciones primero (NLTK es muy bueno en eso), luego la tokenización de palabras (que produce una lista de listas de tokens, no solo una lista de tokens) y luego alimenta cada oración por separado para El modelo de Markov. Esto le permitirá modelar correctamente los inicios de secuencia, en lugar de estar atascado en una sola forma de comenzar cada secuencia.

Es probable que su cuerpo de muestra sea demasiado pequeño. No sé cómo exactamente nltk construye su modelo de trigtwig, pero es una práctica común que el principio y el final de las oraciones se manejen de alguna manera. Dado que solo hay un principio de oración en su cuerpo, esta podría ser la razón por la cual cada oración tiene el mismo principio.

Tal vez pueda ordenar la matriz de tokens al azar antes de generar una oración.

¿Estás seguro de que usar word_tokenize es el enfoque correcto?

Esta página de grupos de Google tiene el ejemplo:

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

Pero nunca he usado nltk, así que no puedo decir si funciona de la manera que quieres.