传递给 Gensim 语言模型的句子迭代器

Sentence iterator to pass to Gensim language model

我对 NLP 比较陌生,我正在尝试创建自己的词嵌入,并在我的个人文档语料库中训练。

我正在尝试执行以下代码来创建我自己的词嵌入:

model = gensim.models.Word2Vec(sentences)

句子是句子列表。 因为我无法传递成千上万的句子,所以我需要一个迭代器

# with mini batch_dir a directory with the text files
# MySentences is a class iterating over sentences.
sentences = MySentences(minibatch_dir) # a memory-friendly iterator

我从 gensim 的创建者那里找到了这个解决方案:

class MySentences(object):
    def __init__(self, dirname):
        self.dirname = dirname

    def __iter__(self):
        for fname in os.listdir(self.dirname):
            for line in open(os.path.join(self.dirname, fname)):
                yield line.split()

它对我不起作用。 如果我知道如何从每个文档中获取句子列表,我该如何创建迭代器?

第二个非常相关的问题: 如果我的目标是比较特定语料库中的文档相似性,那么从头开始使用该特定语料库的所有文档创建词嵌入总是比使用 GloVec 或 word2vec 更好? 文档量40000左右

干杯

更早

您的插图 class MySentences 假定每行一个句子。您的数据可能并非如此。

需要注意的一件事是 - 调用 Word2Vec(sentences, iter=1) 将 运行 遍历句子迭代器两次(或者,通常 iter+1 次遍历;默认 iter=5)。第一遍收集单词及其频率以构建内部词典树结构。第二遍和后续遍训练神经模型。如果您的输入流是 non-repeatable(您只能负担一次),这两个(或 iter+1)遍也可以手动启动,并且您可以通过其他方式初始化词汇表:

model = gensim.models.Word2Vec(iter=1)  # an empty model, no training yet
model.build_vocab(some_sentences)  # can be a non-repeatable, 1-pass generator
model.train(other_sentences)  # can be a non-repeatable, 1-pass generator

例如,如果您尝试读取存储在数据库中的数据集,您的生成器函数直接从数据库流式传输文本,将抛出 TypeError:

TypeError: You can't pass a generator as the sentences argument. Try an iterator.

发电机只能消耗一次,然后就被遗忘了。因此,您可以编写一个具有迭代器接口但在底层使用生成器的包装器。

class SentencesIterator():
    def __init__(self, generator_function):
        self.generator_function = generator_function
        self.generator = self.generator_function()

    def __iter__(self):
        # reset the generator
        self.generator = self.generator_function()
        return self

    def __next__(self):
        result = next(self.generator)
        if result is None:
            raise StopIteration
        else:
            return result

生成器函数也被存储,因此它可以像这样重置并在 Gensim 中使用:

from gensim.models import FastText

sentences = SentencesIterator(tokens_generator)
model = FastText(sentences)