首页 > 解决方案 > Gensim 内置 model.load 函数和 Python Pickle.load 文件

问题描述

我试图使用 Gensim 对一些英语单词导入 GoogelNews 预训练模型(这里采样了 15 个,每行仅存储在一个 txt 文件中,并且没有更多的上下文作为语料库)。然后我可以使用“model.most_similar()”为他们获取相似的单词/短语。但实际上从 Python-Pickle 方法加载的文件不能直接用于 gensim-built-inmodel.load()model.most_similar()函数。

由于我无法从一开始就训练、保存和加载模型,我应该如何对 15 个英文单词(以及未来更多)进行聚类?

import gensim
from gensim.models import Word2Vec
from gensim.models.keyedvectors import KeyedVectors

GOOGLE_WORD2VEC_MODEL = '../GoogleNews-vectors-negative300.bin'

GOOGLE_ENGLISH_WORD_PATH = '../testwords.txt'

GOOGLE_WORD_FEATURE = '../word.google.vector'

model = gensim.models.KeyedVectors.load_word2vec_format(GOOGLE_WORD2VEC_MODEL, binary=True) 

word_vectors = {}

#load 15 words as a test to word_vectors

with open(GOOGLE_ENGLISH_WORD_PATH) as f:
    lines = f.readlines()
    for line in lines:
        line = line.strip('\n')
        if line:                
            word = line
            print(line)
            word_vectors[word]=None
try:
    import cPickle
except :
    import _pickle as cPickle

def save_model(clf,modelpath): 
    with open(modelpath, 'wb') as f: 
        cPickle.dump(clf, f) 

def load_model(modelpath): 
    try: 
        with open(modelpath, 'rb') as f: 
            rf = cPickle.load(f) 
            return rf 
    except Exception as e:        
        return None 

for word in word_vectors:
    try:
        v= model[word]
        word_vectors[word] = v
    except:
        pass

save_model(word_vectors,GOOGLE_WORD_FEATURE)

words_set = load_model(GOOGLE_WORD_FEATURE)

words_set.most_similar("knit", topn=3)
---------------error message--------
AttributeError                            Traceback (most recent call last)
<ipython-input-8-86c15e366696> in <module>
----> 1 words_set.most_similar("knit", topn=3)

AttributeError: 'dict' object has no attribute 'most_similar'
---------------error message--------

标签: gensimword2vec

解决方案


您已定义word_vectors为 Python dict

word_vectors = {}

然后你的save_model()函数只是保存那个 raw dict,你load_model()加载同样的 raw dict

此类字典对象实现该most_similar()方法,该方法特定KeyedVectorsgensim.

因此,您必须将数据保留在类似KeyedVectors对象中才能使用most_similar().

幸运的是,您有几个选择。

如果您碰巧只需要文件中的15 个单词GoogleNews(或前 15,000 个等),则可以使用可选limit参数仅读取那么多向量:

from gensim.models import KeyedVectors
model = KeyedVectors.load_word2vec_format(GOOGLE_WORD2VEC_MODEL, limit=15, binary=True)

或者,如果您确实需要选择单词的任意子集,并将它们组合成一个新KeyedVectors实例,您可以重新使用其中的一个类gensim而不是 plain dict,然后以稍微不同的方式添加您的向量:

# instead of a {} dict
word_vectors = KeyedVectors(model.vector_size)  # re-use size from loaded model

...然后稍后在您word要添加的每个循环中...

# instead of `word_vectors[word] = _SOMETHING_`
word_vectors.add(word, model[word])

然后你就会有word_vectors一个实际的KeyedVectors对象。虽然您可以通过普通的 Python-pickle 保存它,但此时您不妨使用KeyedVectors内置的save()load()- 它们在大型向量集上可能更有效(通过将大型原始向量集保存为应保留的单独文件与主文件一起)。例如:

word_vectors.save(GOOGLE_WORD_FEATURE)

...

words_set = KeyedVectors.load(GOOGLE_WORD_FEATURE)

words_set.most_similar("knit", topn=3)  # should work

推荐阅读