【问题标题】:Gensim built-in model.load function and Python Pickle.load fileGensim 内置 model.load 函数和 Python Pickle.load 文件
【发布时间】:2019-08-09 02:06:42
【问题描述】:

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

【问题讨论】:

    标签: gensim word2vec


    【解决方案1】:

    您已将 word_vectors 定义为 Python dict

    word_vectors = {}
    

    然后您的save_model() 函数只是保存原始dict,而您的load_model() 加载相同的原始dict

    此类字典对象实现most_similar() 方法,该方法特定于gensimKeyedVectors 接口(及相关类)。

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

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

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

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

    或者,如果您确实需要选择单词的任意子集,并将它们组合成一个新的KeyedVectors 实例,您可以重用gensim 中的一个类,而不是普通的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
    

    【讨论】:

    • 非常感谢你,gojomo!听从你的建议。
    • 另一个注意事项:.add() 操作本质上是在每次调用时重新创建一个大的后备 numpy 数组,复制所有现有向量以及添加的内容。从小处着手并保持小处,这没什么大不了的。但是,如果您使用大量的词向量,它可能会变得缓慢/低效。 (将 1 个向量添加到 100 万个集合中将分配一个新的 1,000,001 个数组,复制所有 100 万个旧的,添加 1 个新的。再添加 1 个,分配一个 1,000,002 个数组,复制超过 1,000,001 个向量,添加 1 个新的。等等。 ) 因此,如果将其用于更大的集合,.add() 在更少的批次或单个批次中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-24
    • 2010-10-22
    相关资源
    最近更新 更多