生成器不是迭代器?
Generator is not an iterator?
我有一个生成器(一个生成东西的函数),但是当试图将它传递给 gensim.Word2Vec
时,我收到以下错误:
TypeError: You can't pass a generator as the sentences argument. Try an iterator.
生成器不是迭代器的一种吗?如果没有,我如何从中创建迭代器?
查看库代码,它似乎只是简单地迭代像 for x in enumerate(sentences)
这样的句子,这对我的生成器来说工作得很好。那么是什么导致了错误?
生成器在一个循环后耗尽。 Word2vec 只需要多次遍历句子(并且可能获得给定索引的项目,这对于生成器来说是不可能的,它只是一种只能弹出的堆栈),因此需要更可靠的东西,比如列表。
特别是在他们的代码中,他们调用了两个不同的函数,都对句子进行迭代(因此,如果您使用生成器,第二个函数将 运行 在一个空集上)
self.build_vocab(sentences, trim_rule=trim_rule)
self.train(sentences)
它应该与任何实现 __iter__
而不是 GeneratorType
的东西一起工作。所以将你的函数包装在一个可迭代的接口中,并确保你可以多次遍历它,这意味着
sentences = your_code
for s in sentences:
print s
for s in sentences:
print s
打印你的collection两次
gensim 似乎抛出了误导性的错误消息。
Gensim 想要多次迭代您的数据。大多数库只是根据输入构建一个列表,因此用户不必关心提供多个可迭代序列。当然,生成内存中的列表可能会非常耗费资源,而例如遍历文件时,可以在不将整个文件存储在内存中的情况下完成。
对于您的情况,只需将生成器更改为列表推导即可解决问题。
正如之前的海报所提到的,生成器的行为类似于迭代器,但有两个显着差异:生成器会耗尽,并且您无法索引一个。
我快速查找了文档,在此页面上 -- https://radimrehurek.com/gensim/models/word2vec.html
文档指出
gensim.models.word2vec.Word2Vec(sentences=None, size=100, alpha=0.025, window=5, min_count= 5、max_vocab_size=None, sample=0, seed=1, workers=1, min_alpha=0.0001, sg=1, hs=1, negative=0, cbow_mean=0, hashfxn=, iter=1, null_word=0, trim_rule=None, sorted_vocab=1)
...
从可迭代的句子中初始化模型。每个句子都是将用于训练的单词列表(unicode 字符串)。
我敢猜测函数内部的逻辑本质上需要一个或多个列表属性,例如项目索引,可能有一个显式的断言语句或引发错误的 if 语句。
可以解决您的问题的一个简单技巧是将您的生成器变成列表推导式。您的程序将承受 CPU 性能损失并将增加其内存使用量,但这至少应该使代码正常工作。
my_iterator = [x for x in generator_obj]
其他答案指出 Gensim 需要两遍来构建 Word2Vec
模型:一次构建词汇表 (self.build_vocab
),第二次训练模型 (self.train
).您仍然可以通过拆分 build_vocab
和 train
方法将生成器传递给 train
方法(例如,如果您正在传输数据)。
from gensim.models import Word2Vec
model = Word2Vec()
sentences = my_generator() # first pass
model.build_vocab(sentences)
sentences = my_generator() # second pass of same data
model.train(sentences2,
total_examples=num_sentences, # total number of documents to process
epochs=model.epochs)
我有一个生成器(一个生成东西的函数),但是当试图将它传递给 gensim.Word2Vec
时,我收到以下错误:
TypeError: You can't pass a generator as the sentences argument. Try an iterator.
生成器不是迭代器的一种吗?如果没有,我如何从中创建迭代器?
查看库代码,它似乎只是简单地迭代像 for x in enumerate(sentences)
这样的句子,这对我的生成器来说工作得很好。那么是什么导致了错误?
生成器在一个循环后耗尽。 Word2vec 只需要多次遍历句子(并且可能获得给定索引的项目,这对于生成器来说是不可能的,它只是一种只能弹出的堆栈),因此需要更可靠的东西,比如列表。
特别是在他们的代码中,他们调用了两个不同的函数,都对句子进行迭代(因此,如果您使用生成器,第二个函数将 运行 在一个空集上)
self.build_vocab(sentences, trim_rule=trim_rule)
self.train(sentences)
它应该与任何实现 __iter__
而不是 GeneratorType
的东西一起工作。所以将你的函数包装在一个可迭代的接口中,并确保你可以多次遍历它,这意味着
sentences = your_code
for s in sentences:
print s
for s in sentences:
print s
打印你的collection两次
gensim 似乎抛出了误导性的错误消息。
Gensim 想要多次迭代您的数据。大多数库只是根据输入构建一个列表,因此用户不必关心提供多个可迭代序列。当然,生成内存中的列表可能会非常耗费资源,而例如遍历文件时,可以在不将整个文件存储在内存中的情况下完成。
对于您的情况,只需将生成器更改为列表推导即可解决问题。
正如之前的海报所提到的,生成器的行为类似于迭代器,但有两个显着差异:生成器会耗尽,并且您无法索引一个。
我快速查找了文档,在此页面上 -- https://radimrehurek.com/gensim/models/word2vec.html
文档指出
gensim.models.word2vec.Word2Vec(sentences=None, size=100, alpha=0.025, window=5, min_count= 5、max_vocab_size=None, sample=0, seed=1, workers=1, min_alpha=0.0001, sg=1, hs=1, negative=0, cbow_mean=0, hashfxn=, iter=1, null_word=0, trim_rule=None, sorted_vocab=1) ...
从可迭代的句子中初始化模型。每个句子都是将用于训练的单词列表(unicode 字符串)。
我敢猜测函数内部的逻辑本质上需要一个或多个列表属性,例如项目索引,可能有一个显式的断言语句或引发错误的 if 语句。
可以解决您的问题的一个简单技巧是将您的生成器变成列表推导式。您的程序将承受 CPU 性能损失并将增加其内存使用量,但这至少应该使代码正常工作。
my_iterator = [x for x in generator_obj]
其他答案指出 Gensim 需要两遍来构建 Word2Vec
模型:一次构建词汇表 (self.build_vocab
),第二次训练模型 (self.train
).您仍然可以通过拆分 build_vocab
和 train
方法将生成器传递给 train
方法(例如,如果您正在传输数据)。
from gensim.models import Word2Vec
model = Word2Vec()
sentences = my_generator() # first pass
model.build_vocab(sentences)
sentences = my_generator() # second pass of same data
model.train(sentences2,
total_examples=num_sentences, # total number of documents to process
epochs=model.epochs)