1 回答

TA贡献1807条经验 获得超9个赞
Word2Vec
一旦单词被“切入”包含范围,就没有官方支持从 Gensim 模型中删除单词。
即使添加单词的能力也没有很好的基础,因为该功能并不基于任何经过验证/已发布的模型更新方法Word2Vec
,并且通过学习选择掩盖了更新批次如何影响模型的困难权衡-速率或批次是否完全代表现有词汇。最安全的做法是定期从头开始重新训练模型,使用包含所有相关单词的足够示例的完整语料库。
因此,我的主要建议是定期用经过所有仍然相关数据训练的新模型替换您的模型。这将确保它不再在过时的术语上浪费模型状态,并且所有仍然有效的术语都接受了同等的交错训练。
经过这样的重置后,词向量将无法与之前“模型时代”的词向量相比较。(同一个词,即使它的有形含义没有改变,也可能处于任意不同的位置 - 但与其他向量的相对关系应该保持良好或更好。)但是,同样的比较漂移任何一组小批量更新也会发生这种情况,这些更新不会平等地“接触”每个现有单词,只是以某种无法量化的速度。
OTOH,如果您认为需要保持这种增量更新,即使知道注意事项,您也可以修补模型结构以保留旧模型中尽可能多的合理内容并继续训练。
到目前为止,您的代码是一个合理的开始,缺少正确功能的一些重要注意事项:
由于删除较早的单词会更改较晚的单词的索引位置,因此您需要更新
vocab[word].index
每个幸存单词的值,以匹配新的index2word
排序。例如,完成所有删除后,您可以执行以下操作:
for i, word in enumerate(m.wv.index2word): m.wv.vocab[word].index = i
因为在您的(默认负采样)
Word2Vec
模型中,还有另一个与模型输出层相关的每个单词权重数组,它也应该同步更新,以便每个单词检查正确的输出值。粗略地说,每当您从 中删除一行时m.wv.vectors
,您都应该从 中删除同一行m.traininables.syn1neg
。因为幸存的词汇具有不同的相对词频,负采样和下采样(由参数控制
sample
)函数都应该处理不同的预先计算的结构来帮助他们的选择。对于负采样使用的累积分布表,这非常简单:
m.make_cum_table(m.wv)
如果这些内部结构与您现有的操作同步正确更新,则模型可能处于一致的状态以进行进一步的训练。(但请注意:这些结构在即将发布的版本中发生了很大变化gensim-4.0.0
,因此在升级时任何自定义篡改都需要更新。)
另一项效率说明:np.delete()
每次调用该操作时,该操作都会创建一个新数组,即幸存数组的完整大小,并复制旧值。因此,使用它从非常大的原始数组中一次删除多行可能需要大量冗余分配/复制/垃圾收集。您也许可以在最后调用它一次,并列出要删除的所有索引。
但实际上:更简单、更有根据的方法,也可能产生明显更好的连续可比向量,是在可能的情况下或发生大量变化时使用所有当前数据进行重新训练。
添加回答
举报