有没有一种方法可以保存和加载Gensim Doc2Vec模型的词汇表

时间:2019-05-22 07:51:27

标签: python pyspark gensim doc2vec

  

编辑

火车语料库是我在此步骤之前构建的Spark数据框。我从实木复合地板格式加载它,并创建了一个“ Feed”类,该类将Gencorp火车上的迭代器提供给Gensim lib:

class Feed():
    def __init__(self, train_data):
        self.train_data = train_data

    def __iter__(self):
        for row in self.train_data.rdd.toLocalIterator():
            yield \
                gensim.models.doc2vec.TaggedDocument(\
                words=[kw.lower() for kw in row["keywords"]] + list(row["tokens_filtered"]),\
                tags=[row["id"]])


sdf = spark.read.parquet(save_dirname)
train_corpus = Feed(sdf)
  

结束编辑

我希望在约900万个新闻文本文档上训练Gensim Doc2Vec模型。这是我的模型定义:

model = gensim.models.doc2vec.Doc2Vec(
        workers=8,
        vector_size=300,
        min_count=50,
        epochs=10)

第一步是获取词汇表:

model.build_vocab(train_corpus)

它在90分钟内结束。这是此过程结束时的日志记录信息:

INFO:gensim.models.doc2vec:collected 4202859 word types and 8950263 unique tags from a corpus of 8950339 examples and 1565845381 words
INFO:gensim.models.word2vec:Loading a fresh vocabulary
INFO:gensim.models.word2vec:min_count=50 retains 325027 unique words (7% of original 4202859, drops 3877832)
INFO:gensim.models.word2vec:min_count=50 leaves 1546772183 word corpus (98% of original 1565845381, drops 19073198)
INFO:gensim.models.word2vec:deleting the raw counts dictionary of 4202859 items
INFO:gensim.models.word2vec:sample=0.001 downsamples 9 most-common words
INFO:gensim.models.word2vec:downsampling leaves estimated 1536820314 word corpus (99.4% of prior 1546772183)
INFO:gensim.models.base_any2vec:estimated required memory for 325027 words and 300 dimensions: 13472946500 bytes

然后我在训练语料库上使用迭代器类训练模型:

model.train(train_corpus, total_examples=nb_rows, epochs=model.epochs)

最后的训练记录是:

INFO:gensim.models.base_any2vec:EPOCH 1 - PROGRESS: at 99.99% examples, 201921 words/s, in_qsize 16, out_qsize 0
INFO:gensim.models.base_any2vec:worker thread finished; awaiting finish of 7 more threads
INFO:gensim.models.base_any2vec:worker thread finished; awaiting finish of 6 more threads
INFO:gensim.models.base_any2vec:worker thread finished; awaiting finish of 5 more threads
INFO:gensim.models.base_any2vec:worker thread finished; awaiting finish of 4 more threads

但是它永远不会完成剩余的线程。 这不是我第一次遇到这个问题,即使使用较小的火车语料库也是如此。通常,我会重新启动整个过程(词汇设置和模型训练),然后继续进行。

为了节省时间,我现在不想再计算词汇表,而是将先前成功计算出的词汇表放到位,而仅尝试再次训练模型。有没有办法只保存模型的vocab部分,然后将其加载以直接在训练语料库上训练模型?

1 个答案:

答案 0 :(得分:0)

就挂起原因而言,看来您通常在做正确的事情,但是train_corpus可能出了一些问题,您的构造尚未显示。

仔细检查其实现,然后编辑您的问题以显示其类型/初始化的更多详细信息。查看日志以查看是否有证据表明任何线程遇到错误,使它们处于未按要求进行报告的状态。

您可以.save()模型的Doc2Vec的各个部分,例如model.wv.save(wv_path) –但是没有简单的方法可以从这些子部分重建模型。 (有可能,但是需要仔细检查对象的所需状态,从检查源开始,并且容易出错。)

而且更相关的是,您可以随时.save()完整的Doc2Vec模型-这可能是满足您需求的更好方法。也就是说,您可以在.save()之后或在调用build_vocab()等之后.train()进行此操作。

如果实际上您当前的挂起在某个笔记本中,您可以在其中中断挂起的操作,并在新的单元格中执行新代码,则可以仅从此处保存模型,调试train_corpus,然后重新执行加载和重新训练–只要语料库大小/词汇匹配build_vocab()中学习到的内容。

但是,最后,这样一部分受过训练的.save()将受到已经进行的几乎完全的训练的影响。因此,最终结果将不仅仅反映您的配置参数,还包括大量的临时培训。

如果您想在重新加载保存的Doc2Vec模型之后“清除”部分训练的挥之不去的效果,我相信以下方法可以做到:

model.trainables.reset_weights(model.hs, model.negative, model.wv, model.docvecs)