【问题标题】:SpaCy: how to load Google news word2vec vectors?SpaCy:如何加载 Google 新闻 word2vec 向量?
【发布时间】:2017-06-24 22:52:06
【问题描述】:

我尝试了几种加载谷歌新闻 word2vec 向量的方法 (https://code.google.com/archive/p/word2vec/):

en_nlp = spacy.load('en',vector=False)
en_nlp.vocab.load_vectors_from_bin_loc('GoogleNews-vectors-negative300.bin')

以上给出:

MemoryError: Error assigning 18446744072820359357 bytes

我也尝试过使用 .gz 压缩向量;或使用 gensim 加载并保存它们为新格式:

from gensim.models.word2vec import Word2Vec
model = Word2Vec.load_word2vec_format('GoogleNews-vectors-negative300.bin', binary=True)
model.save_word2vec_format('googlenews2.txt')

然后该文件在每一行包含单词及其单词向量。 我尝试加载它们:

en_nlp.vocab.load_vectors('googlenews2.txt')

但它返回“0”。

这样做的正确方法是什么?

更新:

我可以将自己创建的文件加载到 spacy 中。 我在每一行使用带有“string 0.0 0.0 ....”的 test.txt 文件。然后用 .bzip2 压缩这个 txt 到 test.txt.bz2。 然后我创建一个 spacy 兼容的二进制文件:

spacy.vocab.write_binary_vectors('test.txt.bz2', 'test.bin')

我可以加载到 spacy 中:

nlp.vocab.load_vectors_from_bin_loc('test.bin')

这行得通! 但是,当我对 googlenews2.txt 执行相同的过程时,我收到以下错误:

lib/python3.6/site-packages/spacy/cfile.pyx in spacy.cfile.CFile.read_into (spacy/cfile.cpp:1279)()

OSError: 

【问题讨论】:

    标签: python nlp word2vec spacy


    【解决方案1】:

    对于 spacy 1.x,将 Google 新闻向量加载到 gensim 中并转换为新格式(.txt 中的每一行都包含一个向量:string, vec):

    from gensim.models.word2vec import Word2Vec
    from gensim.models import KeyedVectors
    model = KeyedVectors.load_word2vec_format('GoogleNews-vectors-negative300.bin', binary=True)
    model.wv.save_word2vec_format('googlenews.txt')
    

    删除.txt的第一行:

    tail -n +2 googlenews.txt > googlenews.new && mv -f googlenews.new googlenews.txt
    

    将txt压缩为.bz2:

    bzip2 googlenews.txt
    

    创建兼容 SpaCy 的二进制文件:

    spacy.vocab.write_binary_vectors('googlenews.txt.bz2','googlenews.bin')
    

    将 googlenews.bin 移动到 python 环境的 /lib/python/site-packages/spacy/data/en_google-1.0.0/vocab/googlenews.bin。

    然后加载词向量:

    import spacy
    nlp = spacy.load('en',vectors='en_google')
    

    或稍后加载它们:

    nlp.vocab.load_vectors_from_bin_loc('googlenews.bin')
    

    【讨论】:

    • 确保将其命名为“vec.bin”,例如:/lib/python/site-packages/spacy/data/en_google-1.0.0/vocab/vec.bin
    • 实际上,它会加载,但我看不出原始手套和像这样创建的手套之间的矢量有任何区别。出了点问题(使用相同的代码)。
    • 稍后才加载它们确实做出了改变。
    • 此处使用的 spacy 方法在 spacy 2.0 中已弃用。见github.com/explosion/spaCy/issues/1046
    • 只是想插话说你不应该在以后的 spaCy 版本中使用这个答案中描述的方法,它不会起作用。请查看文档的init vectors 部分。 spacy.io/api/cli#init-vectors
    【解决方案2】:

    我知道这个问题已经得到解答,但我将提供一个更简单的解决方案。此解决方案会将谷歌新闻向量加载到一个空白的 spacy nlp 对象中。

    import gensim
    import spacy
    
    # Path to google news vectors
    google_news_path = "path\to\google\news\\GoogleNews-vectors-negative300.bin.gz"
    
    # Load google news vecs in gensim
    model = gensim.models.KeyedVectors.load_word2vec_format(gn_path, binary=True)
    
    # Init blank english spacy nlp object
    nlp = spacy.blank('en')
    
    # Loop through range of all indexes, get words associated with each index.
    # The words in the keys list will correspond to the order of the google embed matrix
    keys = []
    for idx in range(3000000):
        keys.append(model.index2word[idx])
    
    # Set the vectors for our nlp object to the google news vectors
    nlp.vocab.vectors = spacy.vocab.Vectors(data=model.syn0, keys=keys)
    
    >>> nlp.vocab.vectors.shape
    (3000000, 300)
    

    【讨论】:

    • 谢谢。我使用了keys=model.vocab.keys(),因为原始顺序对我来说并不重要。
    • 为什么要创建列表 keys ?我认为这是一种更简单的方法:model_spacy.vocab.vectors = spacy.vocab.Vectors(data=model_google.syn0, keys=model_google.index2word)
    【解决方案3】:

    我正在使用 spaCy v2.0.10。

    创建兼容 SpaCy 的二进制文件:

    spacy.vocab.write_binary_vectors('googlenews.txt.bz2','googlenews.bin')

    我想强调一下,已接受答案中的特定代码现在不起作用。我在运行代码时遇到了“AttributeError: ...”。

    这在 spaCy v2 中有所改变。 write_binary_vectors 在 v2 中被删除。来自spaCy documentations,目前的做法如下:

    $ python -m spacy init-model en /path/to/output -v /path/to/vectors.bin.tar.gz
    

    【讨论】:

    • 这对我不起作用。我得到“AssertionError:f”
    • 我相信这是由于位置参数“freqs_loc”link to documentation
    【解决方案4】:

    使用 gensim api 下载 google 的 word2vec 压缩模型要容易得多,它将存储在 /home/"your_username"/gensim-data/word2vec-google-news-300/ 中。加载向量并打球。我有 16GB 的 RAM,足以处理模型

    import gensim.downloader as api
    
    model = api.load("word2vec-google-news-300")  # download the model and return as object ready for use
    word_vectors = model.wv #load the vectors from the model
    

    【讨论】:

      猜你喜欢
      • 2021-03-16
      • 1970-01-01
      • 2020-12-09
      • 1970-01-01
      • 1970-01-01
      • 2018-07-19
      • 2021-02-15
      • 2020-10-30
      • 2017-07-05
      相关资源
      最近更新 更多