更新 gensim Doc2Vec 模型的训练文档
Updating training documents for gensim Doc2Vec model
我有一个现有的 gensim Doc2Vec 模型,我正在尝试对训练集进行迭代更新,并通过扩展对模型进行更新。
我拿了新文件,像往常一样进行预处理:
stoplist = nltk.corpus.stopwords.words('english')
train_corpus= []
for i, document in enumerate(corpus_update['body'].values.tolist()):
train_corpus.append(gensim.models.doc2vec.TaggedDocument([word for word in gensim.utils.simple_preprocess(document) if word not in stoplist], [i]))
然后我加载原始模型,更新词汇表,并重新训练:
#### Original model
## model = gensim.models.doc2vec.Doc2Vec(dm=0, size=300, hs=1, min_count=10, dbow_words= 1, negative=5, workers=cores)
model = Doc2Vec.load('pvdbow_model_6_06_12_17.doc2vec')
model.build_vocab(train_corpus, update=True)
model.train(train_corpus, total_examples=model.corpus_count, epochs=model.iter)
然后我通过附加新数据更新训练集 Pandas 数据框,并重置索引。
corpus = corpus.append(corpus_update)
corpus = corpus.reset_index(drop=True)
但是,当我尝试将 infer_vector() 与 updated 模型一起使用时:
inferred_vector = model1.infer_vector(tokens)
sims = model.docvecs.most_similar([inferred_vector], topn=len(model.docvecs))
结果质量很差,表明模型和训练集数据帧的索引不再匹配。
当我将它与 未更新的 训练集数据框(再次使用更新的模型)进行比较时,结果很好 - 但是,显然我缺少新文档。
因为我希望能够在不完全重新训练模型的情况下对模型进行频繁更新,所以无论如何都需要更新吗?
Gensim Doc2Vec
还没有官方支持扩展词汇表(通过 build_vocab(..., update=True)
),因此这里的模型行为没有定义为做任何有用的事情。事实上,我认为任何现有的文档标签都将被完全丢弃并替换为最新语料库中的任何文档标签。 (此外,当尝试将 update_vocab()
与 Doc2Vec
一起使用时,还有未解决的内存故障进程崩溃的未解决报告,例如 this issue。)
即使这有效,如果继续在文本与初始训练集不同的模型上调用 train()
,也有许多模糊的平衡问题需要考虑。特别是,每个这样的训练会话都会使模型在新示例上变得更好,但会失去原始训练的价值,可能会使模型在某些情况下或整体上变差。
对于不断增长的语料库,最稳妥的策略是偶尔从头开始重新训练,将所有训练示例合并到一个语料库中。 my recent post to the gensim discussion list 中讨论了滚动更新模型的另一个可能过程的概述。
关于您的设置的一些其他评论:
同时使用 hierarchical-softmax (hs=1
) 和负采样(negative
> 0)会增加模型大小和训练时间,但相比之下可能不会提供任何优势只使用一种模式进行更多迭代(或其他调整)——因此很少有两种模式都处于活动状态
通过不指定 iter
,您使用的是默认继承自 Word2Vec 的“5”,而已发布的 Doc2Vec 作品通常使用 10-20 次或更多次迭代
许多人报告说 infer_vector
在其可选参数 steps
(默认值为 5
)的更高值下工作得更好,and/or 具有较小的 alpha
值(默认值为 0.1
)
我有一个现有的 gensim Doc2Vec 模型,我正在尝试对训练集进行迭代更新,并通过扩展对模型进行更新。
我拿了新文件,像往常一样进行预处理:
stoplist = nltk.corpus.stopwords.words('english')
train_corpus= []
for i, document in enumerate(corpus_update['body'].values.tolist()):
train_corpus.append(gensim.models.doc2vec.TaggedDocument([word for word in gensim.utils.simple_preprocess(document) if word not in stoplist], [i]))
然后我加载原始模型,更新词汇表,并重新训练:
#### Original model
## model = gensim.models.doc2vec.Doc2Vec(dm=0, size=300, hs=1, min_count=10, dbow_words= 1, negative=5, workers=cores)
model = Doc2Vec.load('pvdbow_model_6_06_12_17.doc2vec')
model.build_vocab(train_corpus, update=True)
model.train(train_corpus, total_examples=model.corpus_count, epochs=model.iter)
然后我通过附加新数据更新训练集 Pandas 数据框,并重置索引。
corpus = corpus.append(corpus_update)
corpus = corpus.reset_index(drop=True)
但是,当我尝试将 infer_vector() 与 updated 模型一起使用时:
inferred_vector = model1.infer_vector(tokens)
sims = model.docvecs.most_similar([inferred_vector], topn=len(model.docvecs))
结果质量很差,表明模型和训练集数据帧的索引不再匹配。
当我将它与 未更新的 训练集数据框(再次使用更新的模型)进行比较时,结果很好 - 但是,显然我缺少新文档。
因为我希望能够在不完全重新训练模型的情况下对模型进行频繁更新,所以无论如何都需要更新吗?
Gensim Doc2Vec
还没有官方支持扩展词汇表(通过 build_vocab(..., update=True)
),因此这里的模型行为没有定义为做任何有用的事情。事实上,我认为任何现有的文档标签都将被完全丢弃并替换为最新语料库中的任何文档标签。 (此外,当尝试将 update_vocab()
与 Doc2Vec
一起使用时,还有未解决的内存故障进程崩溃的未解决报告,例如 this issue。)
即使这有效,如果继续在文本与初始训练集不同的模型上调用 train()
,也有许多模糊的平衡问题需要考虑。特别是,每个这样的训练会话都会使模型在新示例上变得更好,但会失去原始训练的价值,可能会使模型在某些情况下或整体上变差。
对于不断增长的语料库,最稳妥的策略是偶尔从头开始重新训练,将所有训练示例合并到一个语料库中。 my recent post to the gensim discussion list 中讨论了滚动更新模型的另一个可能过程的概述。
关于您的设置的一些其他评论:
同时使用 hierarchical-softmax (
hs=1
) 和负采样(negative
> 0)会增加模型大小和训练时间,但相比之下可能不会提供任何优势只使用一种模式进行更多迭代(或其他调整)——因此很少有两种模式都处于活动状态通过不指定
iter
,您使用的是默认继承自 Word2Vec 的“5”,而已发布的 Doc2Vec 作品通常使用 10-20 次或更多次迭代许多人报告说
infer_vector
在其可选参数steps
(默认值为5
)的更高值下工作得更好,and/or 具有较小的alpha
值(默认值为0.1
)