Подтвердить что ты не робот

Генератор не является итератором?

У меня есть генератор (функция, которая дает материал), но при попытке передать его на gensim.Word2Vec я получаю следующую ошибку:

TypeError: вы не можете передать генератор в качестве аргумента предложений. Попробуйте итератор.

Не является генератором своего рода итератором? Если нет, как мне сделать из него итератор?

Глядя на код библиотеки, он просто перебирает предложения типа for x in enumerate(sentences), который отлично работает с моим генератором. Что вызывает ошибку?

4b9b3361

Ответ 1

Генератор исчерпан после одного цикла над ним. 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

дважды печатает вашу коллекцию

Ответ 2

Как упоминалось в предыдущих постерах, генератор действует аналогично итератору с двумя существенными отличиями: генераторы исчерпаны, и вы не можете индексировать один.

Я быстро просмотрел документацию на этой странице - https://radimrehurek.com/gensim/models/word2vec.html

В документации указано, что

gensim.models.word2vec.Word2Vec (предложения = нет, размер = 100, альфа = 0,025, окно = 5, min_count = 5, max_vocab_size = нет, образец = 0, семя = 1, рабочие = 1, min_alpha = 0,0001, sg = 1, hs = 1, отрицательный = 0, cbow_mean = 0, hashfxn =, iter = 1, null_word = 0, trim_rule = нет, sorted_vocab = 1)   ...

Инициализируйте модель из повторяющихся предложений. Каждое предложение представляет собой список слов (строки Unicode), которые будут использоваться для обучения.

Рискну предположить, что логика внутри функции по своей природе требует одного или нескольких свойств списка, таких как индексирование элементов, может быть явное утверждение assert или if, которое вызывает ошибку.

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

my_iterator = [x for x in generator_obj]

Ответ 3

Кажется, gensim выдает ложное сообщение об ошибке.

Gensim хочет многократно перебирать ваши данные. Большинство библиотек просто строят список из ввода, поэтому пользователю не нужно заботиться о поставке многократно повторяемой последовательности. Конечно, создание списка в памяти может быть очень ресурсоемким, в то время как итерация по файлу, например, может быть выполнена без сохранения всего файла в памяти.

В вашем случае простое изменение генератора на компиляцию списка должно решить проблему.

Ответ 4

Другие ответы указывают на то, что Генсиму требуется два прохода для построения модели Word2Vec: один для построения словарного запаса (self.build_vocab), а второй для обучения модели (self.train). Вы все еще можете передать генератор в метод train (например, если вы передаете данные), разбив методы build_vocab и 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)