我是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。
欢呼
更多前置
答案 0 :(得分:1)
您所图解的课程MySentences
每行假设一个句子。您的数据可能并非如此。
要注意的一件事是-调用Word2Vec(sentences,iter = 1)将在句子iterator上运行两遍(或通常iter + 1遍;默认iter = 5)。第一遍收集单词及其频率,以构建内部字典树结构。第二遍及后续遍历训练神经模型。如果您的输入流不可重复(您只能负担一次),也可以手动启动这两个(或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)