从gensim word2vec模型中删除旧“单词”的最佳方法是什么?

如何解决从gensim word2vec模型中删除旧“单词”的最佳方法是什么?

我有一个从项目-项目图构建的“语料库”,这意味着每个句子都是一个图行走路径,每个单词都是一个项目。我想在语料库上训练word2vec模型以获得项目的嵌入向量。该图每天都会更新,因此对word2vec模型的训练有所增加(使用Word2Vec.save()Word2Vec.load()),以不断更新商品的向量。

与单词不同,我的语料库中的项有其生命周期,并且每天都会添加新项。为了防止模型大小的持续增长,我需要删除达到其使用寿命的项目,同时保持模型的可训练性。我读过类似的问题 here,但此问题的答案与培训程度无关,而是基于KeyedVectors。我想出了下面的代码,但是我不确定它是否正确和正确:

from gensim.models import Word2Vec
import numpy as np

texts = [["a","b","c"],["a","h","b"]]
m = Word2Vec(texts,size=5,window=5,min_count=1,workers=1)

print(m.wv.index2word)
print(m.wv.vectors)

# drop old words
wordsToDrop = ["b","c"]
for w in wordsToDrop:
    i = m.wv.index2word.index(w)
    m.wv.index2word.pop(i)
    m.wv.vectors = np.delete(m.wv.vectors,i,axis=0)
    del m.wv.vocab[w]

print(m.wv.index2word)
print(m.wv.vectors)
m.save("m.model")
del m

# increased training
new = [["a","e","n"],["r","s"]]
m = Word2Vec.load("m.model")
m.build_vocab(new,update=True)
m.train(new,total_examples=m.corpus_count,epochs=2)
print(m.wv.index2word)
print(m.wv.vectors)

删除并增加训练后,m.wv.index2wordm.wv.vectors仍在元素方面相对应吗?上面的代码有副作用吗?如果我的方法不好,有人可以给我举个例子,说明如何正确删除旧的“单词”并使模型易于训练吗?

解决方法

一旦他们“切入”包含在内,就没有官方支持从Gensim Word2Vec模型中删除单词。

即使添加字词的能力也不是很好,因为该功能不是基于任何已证明/已发布的更新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)

对于下采样,您希望更新.sample_int的值,类似于可以在https://github.com/RaRe-Technologies/gensim/blob/3.8.3/gensim/models/word2vec.py#L1534的代码周围查看的逻辑。 (但是,现在看一下这段代码,我想可能是buggy,因为它只是用新字典中的频率信息来更新所有单词,因此可能会破坏通常对真正频繁单词的下采样,并且可能会错误地对仅在新更新中经常出现的单词进行降采样。)

如果与您的现有操作同步地正确更新了这些内部结构,则该模型可能处于一致状态,以进行进一步的培训。 (但请注意:这些结构在即将发布的gensim-4.0.0版本中发生了很大变化,因此在升级时,任何自定义篡改都需要更新。)

另一个效率注意事项:np.delete()操作将创建一个新数组,该数组将保留整个数组的大小,并在每次调用时复制旧值。因此,使用它从非常大的原始阵列中一次删除许多行可能需要大量冗余分配/复制/垃圾收集。最后,您也许可以调用一次,并列出所有要删除的索引。

但是实际上:更简单,更扎实的方法(可能还会产生更好的可连续比较的向量)将是在可能或发生大量更改的情况下使用所有当前数据进行重新训练。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?