我在gensim中有一个大型的预训练Word2Vec模型,我希望在我的Keras模型中使用预训练的单词向量作为嵌入层。
问题是嵌入大小是巨大的,我不需要大多数单词向量(因为我知道哪些单词可以作为输入发生)。所以我想摆脱它们来减少嵌入层的大小。
有没有办法只保留所需的单词向量(包括相应的索引!),基于单词的白名单?
感谢this answer(我已经改变了一些代码以使其更好)。您可以使用此代码来解决您的问题。
我们在restricted_word_set
中有我们所有的小组词(它可以是列表或集),w2v
是我们的模型,所以这里是函数:
import numpy as np
def restrict_w2v(w2v, restricted_word_set):
new_vectors = []
new_vocab = {}
new_index2entity = []
new_vectors_norm = []
for i in range(len(w2v.vocab)):
word = w2v.index2entity[i]
vec = w2v.vectors[i]
vocab = w2v.vocab[word]
vec_norm = w2v.vectors_norm[i]
if word in restricted_word_set:
vocab.index = len(new_index2entity)
new_index2entity.append(word)
new_vocab[word] = vocab
new_vectors.append(vec)
new_vectors_norm.append(vec_norm)
w2v.vocab = new_vocab
w2v.vectors = np.array(new_vectors)
w2v.index2entity = np.array(new_index2entity)
w2v.index2word = np.array(new_index2entity)
w2v.vectors_norm = np.array(new_vectors_norm)
警告:当您第一次创建模型
vectors_norm == None
时,如果在那里使用此功能,您将收到错误。vectors_norm
将在第一次使用后获得numpy.ndarray
类型的值。所以在使用函数之前尝试像most_similar("cat")
这样的vectors_norm
不等于None
。
它重写了与基于Word2VecKeyedVectors的单词相关的所有变量。
用法:
w2v = KeyedVectors.load_word2vec_format("GoogleNews-vectors-negative300.bin.gz", binary=True)
w2v.most_similar("beer")
[('beers',0.8409687876701355), ('lager',0.7733745574951172), ('啤酒',0.71753990650177), ('drink',0.668931245803833), ('lagers',0.6570086479187012), ('Yuengling_Lager',0.655455470085144), ('microbrew',0.6534324884414673), ('Brooklyn_Lager',0.6501551866531372), ('suds',0.6497018337249756), ('brewed_beer',0.6490240097045898)]
restricted_word_set = {"beer", "wine", "computer", "python", "bash", "lagers"}
restrict_w2v(w2v, restricted_word_set)
w2v.most_similar("beer")
[('lagers',0.6570085287094116), ('wine',0.6217695474624634), ('bash',0.20583480596542358), ('computer',0.06677375733852386), ('python',0.005948573350906372]]
它也可以用来删除一些单词。
没有内置功能可以完成,但它不需要太多代码,并且可以在现有的gensim
代码上建模。一些可能的替代策略:
.save_word2vec_format(..., binary=False)
。这种格式几乎是不言自明的;编写自己的代码以从该文件中删除不在白名单中的所有行(确保更新entry-count的前导行声明)。 load_word2vec_format()
和save_word2vec_format()
的现有源代码可能具有指导意义。然后,您将拥有一个子集文件。build_vocab()
步骤。现在,你有未经训练的模型,有随机向量,但只有正确的词汇。抓住模型的wv
属性 - 一个具有正确词汇量的KeyedVectors
实例。然后分别加载超大的矢量集,对于正确大小的KeyedVectors
中的每个字,复制来自较大集合的实际矢量。然后保存正确大小的子集。intersect_word2vec_format()
上的(可能是破碎的 - 自己的-nsnsim-3.4)方法。它或多或少地试图做上面(2)中描述的内容:使用具有所需词汇的内存模型,仅合并来自磁盘上另一个word2vec格式的重叠单词。它既可以工作,也可以为您想要做的事情提供模板。