python - docs - ¿El generador no es un iterador?
python pep8 function comments (3)
Tengo un generador (una función que produce cosas), pero cuando intento pasarlo a gensim.Word2Vec
me sale el siguiente error:
Error de tipo: no puede pasar un generador como argumento de oraciones. Pruebe un iterador.
¿No es un generador un tipo de iterador? Si no, ¿cómo hago un iterador a partir de él?
Mirando el código de la biblioteca, parece simplemente iterar sobre oraciones como for x in enumerate(sentences)
, lo que funciona bien con mi generador. ¿Qué está causando el error entonces?
Como se mencionó en los carteles anteriores, el generador actúa de manera similar al iterador con dos diferencias significativas: los generadores se agotan y no se puede indexar uno.
Busqué rápidamente la documentación en esta página: https://radimrehurek.com/gensim/models/word2vec.html
La documentación establece que
gensim.models.word2vec.Word2Vec (oraciones = Ninguna, tamaño = 100, alfa = 0.025, ventana = 5, cuenta_min = 5, max_vocab_size = Ninguna, muestra = 0, semilla = 1, trabajadores = 1, min_alpha = 0.0001, sg = 1, hs = 1, negativo = 0, cbow_mean = 0, hashfxn =, iter = 1, null_word = 0, trim_rule = None, sorted_vocab = 1) ...
Inicializa el modelo a partir de una iterable de oraciones. Cada oración es una lista de palabras (cadenas Unicode) que se utilizarán para el entrenamiento.
Me atrevo a adivinar que la lógica dentro de la función requiere inherentemente una o más propiedades de lista, como la indexación de elementos, puede haber una declaración de afirmación explícita o una declaración que genere un error.
Un truco simple que puede resolver su problema es convertir su generador en una lista de comprensión. Su programa mantendrá la penalización del rendimiento de la CPU y aumentará el uso de la memoria, pero esto debería al menos hacer que el código funcione.
my_iterator = [x for x in generator_obj]
El generador se agota después de un bucle sobre él. Word2vec simplemente necesita atravesar las oraciones varias veces (y probablemente obtenga un ítem para un índice dado, lo que no es posible para generadores que son solo un tipo de pilas en las que solo puede hacer estallar), por lo que requiere algo más sólido, como una lista.
En particular, en su código llaman a dos funciones diferentes, ambas iteran sobre las oraciones (por lo tanto, si usa el generador, la segunda se ejecutará en un conjunto vacío)
self.build_vocab(sentences, trim_rule=trim_rule)
self.train(sentences)
Debería funcionar con cualquier cosa implementando __iter__
que no sea GeneratorType
. Así que envuelva su función en una interfaz iterable y asegúrese de que pueda recorrerla varias veces, lo que significa que
sentences = your_code
for s in sentences:
print s
for s in sentences:
print s
imprime tu colección dos veces
Parece que Gensim lanza un mensaje de error engañoso.
Gensim quiere iterar sobre sus datos varias veces. La mayoría de las bibliotecas simplemente crean una lista a partir de la entrada, de modo que el usuario no tiene que preocuparse por suministrar una secuencia múltiple iterable. Por supuesto, generar una lista en memoria puede consumir muchos recursos, mientras que la iteración de un archivo, por ejemplo, se puede hacer sin almacenar todo el archivo en la memoria.
En su caso, simplemente cambiando el generador a una lista de compresión debe resolver el problema.