Gensim Word2Vec从预训练模型中选择一组较小的单词向量

问题描述 投票:2回答:2

我在gensim中有一个大型的预训练Word2Vec模型,我希望在我的Keras模型中使用预训练的单词向量作为嵌入层。

问题是嵌入大小是巨大的,我不需要大多数单词向量(因为我知道哪些单词可以作为输入发生)。所以我想摆脱它们来减少嵌入层的大小。

有没有办法只保留所需的单词向量(包括相应的索引!),基于单词的白名单?

python keras word2vec gensim word-embedding
2个回答
2
投票

感谢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]]

它也可以用来删除一些单词。


0
投票

没有内置功能可以完成,但它不需要太多代码,并且可以在现有的gensim代码上建模。一些可能的替代策略:

  1. 加载完整的向量,然后以易于解析的格式保存 - 例如通过.save_word2vec_format(..., binary=False)。这种格式几乎是不言自明的;编写自己的代码以从该文件中删除不在白名单中的所有行(确保更新entry-count的前导行声明)。 load_word2vec_format()save_word2vec_format()的现有源代码可能具有指导意义。然后,您将拥有一个子集文件。
  2. 或者,假装你要使用你感兴趣的语料库(只有有趣的单词)训练一个新的Word2Vec模型。但是,只创建模型并执行build_vocab()步骤。现在,你有未经训练的模型,有随机向量,但只有正确的词汇。抓住模型的wv属性 - 一个具有正确词汇量的KeyedVectors实例。然后分别加载超大的矢量集,对于正确大小的KeyedVectors中的每个字,复制来自较大集合的实际矢量。然后保存正确大小的子集。
  3. 或者,看一下Word2Vec intersect_word2vec_format()上的(可能是破碎的 - 自己的-nsnsim-3.4)方法。它或多或少地试图做上面(2)中描述的内容:使用具有所需词汇的内存模型,仅合并来自磁盘上另一个word2vec格式的重叠单词。它既可以工作,也可以为您想要做的事情提供模板。
© www.soinside.com 2019 - 2024. All rights reserved.