【问题标题】:Cannot load Doc2vec object using gensim无法使用 gensim 加载 Doc2vec 对象
【发布时间】:2020-09-07 07:41:47
【问题描述】:

我正在尝试使用 gensim 加载预训练的 Doc2vec 模型,并使用它将段落映射到向量。我指的是https://github.com/jhlau/doc2vec,我下载的预训练模型是英文维基百科DBOW,也在同一个链接中。但是,当我在维基百科上加载 Doc2vec 模型并使用以下代码推断向量时:

import gensim.models as g
import codecs

model="wiki_sg/word2vec.bin"
test_docs="test_docs.txt"
output_file="test_vectors.txt"

#inference hyper-parameters
start_alpha=0.01
infer_epoch=1000

#load model
test_docs = [x.strip().split() for x in codecs.open(test_docs, "r", "utf-8").readlines()]
m = g.Doc2Vec.load(model)

#infer test vectors
output = open(output_file, "w")
for d in test_docs:
    output.write(" ".join([str(x) for x in m.infer_vector(d, alpha=start_alpha, steps=infer_epoch)]) + "\n")
output.flush()
output.close()

我收到一个错误:

/Users/zhangji/Desktop/CSE547/Project/NLP/venv/lib/python2.7/site-packages/smart_open/smart_open_lib.py:402: UserWarning: This function is deprecated, use smart_open.open instead. See the migration notes for details: https://github.com/RaRe-Technologies/smart_open/blob/master/README.rst#migrating-to-the-new-open-function
  'See the migration notes for details: %s' % _MIGRATION_NOTES_URL
Traceback (most recent call last):
  File "/Users/zhangji/Desktop/CSE547/Project/NLP/AbstractMapping.py", line 19, in <module>
    output.write(" ".join([str(x) for x in m.infer_vector(d, alpha=start_alpha, steps=infer_epoch)]) + "\n")
AttributeError: 'Word2Vec' object has no attribute 'infer_vector'

我知道关于堆栈溢出的 infer_vector 问题有几个线程,但它们都没有解决我的问题。我使用

下载了gensim包
pip install git+https://github.com/jhlau/gensim

另外,我查看了gensim包中的源码后发现,当我使用Doc2vec.load()时,Doc2vec类本身并没有真正的load()函数,但由于它是一个Word2vec 的子类,它调用 Word2vec 中 load() 的超方法,然后将模型变成 Word2vec 对象。但是,infer_vector() 函数是 Doc2vec 独有的,在 Word2vec 中不存在,这就是它导致错误的原因。我还尝试将模型 m 转换为 Doc2vec,但出现此错误:

>>> g.Doc2Vec(m)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/zhangji/Library/Python/2.7/lib/python/site-packages/gensim/models/doc2vec.py", line 599, in __init__
    self.build_vocab(documents, trim_rule=trim_rule)
  File "/Users/zhangji/Library/Python/2.7/lib/python/site-packages/gensim/models/word2vec.py", line 513, in build_vocab
    self.scan_vocab(sentences, trim_rule=trim_rule)  # initial survey
  File "/Users/zhangji/Library/Python/2.7/lib/python/site-packages/gensim/models/doc2vec.py", line 635, in scan_vocab
    for document_no, document in enumerate(documents):
  File "/Users/zhangji/Library/Python/2.7/lib/python/site-packages/gensim/models/word2vec.py", line 1367, in __getitem__
    return vstack([self.syn0[self.vocab[word].index] for word in words])
TypeError: 'int' object is not iterable

事实上,我现在想要使用 gensim 的只是使用在学术文章上效果很好的预训练模型将段落转换为向量。由于某些原因,我不想自己训练模型。如果有人可以帮助我解决问题,我将不胜感激。

顺便说一句,我用的是python2.7,当前gensim版本是0.12.4。

谢谢!

【问题讨论】:

    标签: python gensim word2vec doc2vec


    【解决方案1】:

    我会避免使用 https://github.com/jhlau/doc2vec 的 4 年历史的非标准 gensim 分支,或任何仅加载此类代码的 4 年历史的已保存模型。

    那里的 Wikipedia DBOW 模型也非常小,只有 1.4GB。 Wikipedia 甚至在 4 年前就有超过 400 万篇文章,一个 300 维的 Doc2Vec 模型被训练为拥有 400 万篇文章的 doc-vectors 的大小至少为 4000000 articles * 300 dimensions * 4 bytes/dimension = 4.8GB,甚至不包括其他部分的模型。 (因此,该下载显然不是相关论文中提到的 4.3M 文档、300 维模型——而是以其他不清楚的方式截断的内容。)

    当前的 gensim 版本是 3.8.3,几周前发布。

    使用当前代码和当前 Wikipedia 转储构建您自己的 Doc2Vec 模型可能需要一些修补,以及一夜或更长时间的运行时间 - 但随后您将使用现代支持的代码,使用现代模型可以更好地理解过去 4 年中使用的单词。 (而且,如果您在您感兴趣的确切文档类型(例如学术文章)的语料库上训练了一个模型,那么词汇、词义和匹配到您自己的文本预处理以用于以后推断的文档将一切都会更好。)

    有一个 Jupyter 笔记本示例,它从 Wikipedia 构建了一个 Doc2Vec 模型,该模型在 gensim 源代码树中的功能或非常接近功能:

    https://github.com/RaRe-Technologies/gensim/blob/develop/docs/notebooks/doc2vec-wikipedia.ipynb

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-12
      • 2018-07-21
      • 2016-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多