Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 生成器不是迭代器?_Python_Gensim_Word2vec - Fatal编程技术网

Python 生成器不是迭代器?

Python 生成器不是迭代器?,python,gensim,word2vec,Python,Gensim,Word2vec,我有一个生成器(一个生成东西的函数),但是当试图将它传递给gensim.Word2Vec时,我得到以下错误: TypeError:不能将生成器作为句子参数传递。试试迭代器 生成器不是一种迭代器吗?如果不是,如何从中生成迭代器 查看库代码,它似乎只是在enumerate(Sequences)中对x迭代类似的句子,这在我的生成器中运行得很好。那么,是什么原因导致了错误?发电机在经过一个循环后耗尽。Word2vec只需遍历语句多次(并且可能获取给定索引的项,这对于生成器来说是不可能的,因为生成器只是一

我有一个生成器(一个生成东西的函数),但是当试图将它传递给gensim.Word2Vec时,我得到以下错误:

TypeError:不能将生成器作为句子参数传递。试试迭代器

生成器不是一种迭代器吗?如果不是,如何从中生成迭代器


查看库代码,它似乎只是在enumerate(Sequences)中对x迭代类似的句子,这在我的生成器中运行得很好。那么,是什么原因导致了错误?

发电机在经过一个循环后耗尽。Word2vec只需遍历语句多次(并且可能获取给定索引的项,这对于生成器来说是不可能的,因为生成器只是一种只能弹出的堆栈),因此需要更坚实的东西,比如列表

特别是在他们的代码中,他们调用了两个不同的函数,两个函数都迭代语句(因此,如果使用生成器,第二个函数将在空集上运行)

它应该适用于任何实现
\uu iter\uu
而不是
生成器类型
的东西。因此,将函数包装在一个iterable接口中,并确保可以多次遍历它,这意味着

sentences = your_code
for s in sentences:
  print s
for s in sentences:
  print s

将您的收藏打印两次

gensim似乎抛出了一条误导性的错误消息

Gensim希望对数据进行多次迭代。大多数库只是从输入构建一个列表,因此用户不必关心提供一个多iterable序列。当然,生成内存中的列表可能非常消耗资源,例如,在对文件进行迭代时,可以在不将整个文件存储在内存中的情况下完成


在您的情况下,只需将生成器更改为列表压缩就可以解决问题。

正如前面的海报所提到的,生成器的行为类似于迭代器,但有两个显著的区别:生成器耗尽,而您无法索引一个

我很快查阅了文档,在这一页上--

文件指出:

gensim.models.word2vec.word2vec(句子=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字符串)列表

我冒昧地猜测,函数内部的逻辑内在地需要一个或多个列表属性,例如项索引,可能有一个显式的assert语句或引发错误的if语句

一个可以解决问题的简单方法是将生成器转换为列表理解。您的程序将承受CPU性能损失,并将增加其内存使用量,但这至少会使代码正常工作

my_iterator = [x for x in generator_obj]

其他答案指出,Gensim需要两个过程来构建
Word2Vec
模型:一个是构建词汇表(
self.build\u vocab
),另一个是训练模型(
self.train
)。通过分解
build\u 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)

好。。。他们费了很大的劲才阻止你使用生成器:这毫无意义。@user2357112——也许输入需要多次迭代。文档说列表是一个OK输入。(当然,在这种情况下,
迭代器
肯定是错误的术语,不能放在错误消息中)。@riv然后您可以将生成器更改为列表压缩。当时,评论链中的人似乎对词汇没有清晰的理解。这个错误消息肯定应该被更改(也许他们应该添加
或者iter(句子)是iter(句子)
,以捕获其他迭代器类型)。所有迭代器在一个循环后都会耗尽,而不仅仅是生成器创建的迭代器。(事实上,在耗尽后继续调用
StopIteration
,对
next
进行后续调用是一项要求。)错误消息可能表示iterable而不是iterator。正如您在回答中正确解释的那样,一些iterables可以循环多次。我明白了,但是如果迭代器在
\uuuuuuuiter\uuuuuuuu
中返回self,它不是只能循环一次吗?我还认为错误消息的意思是iterable。@riv迭代器必须在
中返回
self
。但是,iterable不能(对于内置容器也是如此)返回一个从一开始就开始的新迭代器。我刚刚创建了一个类,在
\uuuuuuuuuuuuuuuuuuuuu
方法中返回我的生成器(并且没有其他方法),它工作了。@riv它看起来好像在工作,因为你不再得到异常,但它工作正常吗?如果
build\u vocab
train
都迭代
语句
迭代器,
train
将遇到一个空迭代器。很可能代码根本就没有经过训练。Alex Volkov解释了正确的修复方法,除了它可以更简短地拼写为
list(generator\u obj)
。请注意,在您的答案中,通过理解创建的列表是一个iterable(具有
\uuuu iter\uuuuu
方法),但不是迭代器(没有
next
方法)。是的,这是列表理解,不是迭代器,我会改变我的答案。但这意味着你不能在一个非常大的语料库上训练word2vec。然而,Gensim库以其高效的内存而自豪。这是解决这个特殊问题的快速方法。您可能需要为您的案例编写更复杂的内容,即实现您自己的迭代器,该迭代器可以循环多次,您可以通过多次重新读取文件来权衡内存使用与i/O,请参见--sample iterat
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)