我有一个现有的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()与更新的模型一起使用时:
inferred_vector = model1.infer_vector(tokens)
sims = model.docvecs.most_similar([inferred_vector], topn=len(model.docvecs))
结果质量差,表明模型和训练集数据帧的索引不再匹配。
当我将它与未更新的训练集数据框(再次使用更新的模型)进行比较时,结果很好 - 但显然我错过了新文档。
有没有更新,因为我希望能够在没有完全重新训练模型的情况下频繁更新模型?
答案 0 :(得分:2)
Gensim equals()
尚未获得扩展词汇量的官方支持(通过class Point {
public final int x;
public final int y;
public Point(int x, int y){
this.x = x;
this.y = y;
}
// !!! OVERRIDE hashCode() and equals() so you can use this properly in a HashMap !!!
@Override
public int hashCode() {
int hash = 7;
hash = 71 * hash + this.x;
hash = 71 * hash + this.y;
return hash;
}
@Override
public int equals(Object o) {
if (obj == null)
return false;
if (this == obj)
return true;
if (getClass() != o.getClass())
return false;
Point p = (Point) o;
return this.x == p.x && this.y == p.y;
}
}
),因此此处的模型行为未定义为执行任何有用的操作。事实上,我认为任何现有的doc-tags都将被完全丢弃并替换为最新语料库中的任何一个。 (此外,尝试将Doc2Vec
与build_vocab(..., update=True)
一起使用时,还有未解决的内存错误进程崩溃报告,例如this issue。
即使这样有效,但如果继续在具有与初始训练集不同的文本的模型上调用update_vocab()
,则需要考虑一些模糊的平衡问题。特别是,每个这样的训练课程都会推动模型在新的例子上更好,但是失去了原始训练的价值,可能会使模型在某些情况下或整体上更糟。
具有不断增长的语料库的最具防御性的政策是偶尔从头开始重新训练,所有训练样例合并为一个语料库。在my recent post to the gensim discussion list中讨论了滚动模型更新的可能过程的另一个概述。
关于您的设置的一些其他评论:
同时使用hierarchy-softmax(Doc2Vec
)和负抽样(train()
> 0})可以增加模型大小和培训时间,但与使用just相比可能无法提供任何优势一种模式具有更多迭代(或其他调整) - 所以两种模式都很活跃
未指定hs=1
,您使用' 5'的默认继承自Word2Vec,而已发布的Doc2Vec作品通常使用10-20或更多迭代
许多报告negative
的可选参数iter
(默认值仅为infer_vector
)和/或值较小的值更高,效果更好steps
(默认值为5
)