gensim.models.docvecs.doctag_syn0norm的属性错误

问题描述

我正在用Python 3编写Gensim doc2vec模型的代码
这是我正在运行的代码段:

model1.docvecs.doctag_syn0norm =  (model1.docvecs.doctag_syn0 / sqrt((model1.docvecs.doctag_syn0 ** 2).sum(-1))[...,newaxis]).astype(REAL)[d_indices]

我遇到以下错误

AttributeError: can t set attribute

当我分别测试但没有指定赋值时,右侧的值正在计算。

我觉得这是一个问题,因为我无法将值设置为该类属性所需的值。

让我知道是否有任何解决方法,因为我不想更改gensim的源代码

Clone my repo并按照自述文件说明在模型运行文件夹中运行get_labels.py,以重现该错误

它位于cand_gen.py的第90行

完整的错误堆栈跟踪为:

Extracting candidate labels
models loaded
Data Gathered
cand_generation.py:71: DeprecationWarning: Call to deprecated `syn0` (Attribute will be removed in 4.0.0,use self.vectors instead).
  model1.wv.syn0norm = (model1.wv.syn0 / sqrt((model1.wv.syn0 ** 2).sum(-1))[...,newaxis]).astype(REAL)
cand_generation.py:71: DeprecationWarning: Call to deprecated `syn0norm` (Attribute will be removed in 4.0.0,use self.vectors_norm instead).
  model1.wv.syn0norm = (model1.wv.syn0 / sqrt((model1.wv.syn0 ** 2).sum(-1))[...,newaxis]).astype(REAL)
cand_generation.py:89: DeprecationWarning: Call to deprecated `doctag_syn0` (Attribute will be removed in 4.0.0,use docvecs.vectors_docs instead).
  model1.docvecs.doctag_syn0norm =  (model1.docvecs.doctag_syn0 / sqrt((model1.docvecs.doctag_syn0 ** 2).sum(-1))[...,newaxis]).astype(REAL)[d_indices]
Traceback (most recent call last):
  File "cand_generation.py",line 89,in <module>
    model1.docvecs.doctag_syn0norm =  (model1.docvecs.doctag_syn0 / sqrt((model1.docvecs.doctag_syn0 ** 2).sum(-1))[...,newaxis]).astype(REAL)[d_indices]
AttributeError: can t set attribute
Executing Unsupervised model
Traceback (most recent call last):
  File "unsupervised_labels.py",line 33,in <module>
    test_chunk_size = len(label_list[0])
IndexError: list index out of range
Executing Supervised Model
page Rank models loaded
Traceback (most recent call last):
  File "supervised_labels.py",line 49,in <module>
    test_chunk_size = len(label_list[0])
IndexError: list index out of range

解决方法

首先,通常来说,未定期更新的已有4年历史的存储库不一定会继续与不断更新的Gensim版本一起使用-Gensim的版本已从0.13.3版本更新到大约15个版本到3.8.3,因为该存储库最近一次更新。

使用这样一个古老的示例,您可能想要搜索有关您想做什么的较新示例,或者,如果您绝对需要使用该基础,请向其原始作者寻求建议。

更具体地说:您的代码正在尝试将模型的过时属性分配给最新的Gensim代码不再使用。但是,为了保持与读取旧值的代码的向后兼容性,最新代码包括属性访问器-无设置器。尝试设置没有settor方法的值会产生您所看到的错误。

为什么没有二传手? _norm内部数组始终由Gensim根据需要在内部进行计算(在进行批量相似操作之前,先通过.init_sims()方法进行计算)。并没有预料到会有人想要分配给它-实际上,这样做是不明智的。编写该代码也不是明智的-这样的代码应该触发Gensim自己的计算。

对您正在使用的可能工作的代码进行的最小更改将是分配给其他属性名称,然后再访问。那可以是您选择的任何属性名称。 (这只是 与以前对导致错误的Gensim有意义的名称的重叠。)这将保留不明智的外部计算/修改,并且如果后来通过更正常的方式触发Gensim自己的计算使用,将导致双内存使用。但是,如果与原始代码所做的工作接近,这就是最小的更改。 (克服这一错误后,出于类似的原因,可能还有其他错误与代码过时相关。)

一种更具兼容性的方法是修复您用于触发和重用Gensim自己的赋值计算的代码。这可能涉及:

  1. 呼叫model.docvecs.init_sims()而不是分配给model1.docvecs.doctag_syn0norm
  2. 更改.doctag_syn0norm的所有访问权限,以对同一内部属性使用新名称-如输出中的DeprecationWarning消息中突出显示的名称-.vectors_norm

祝你好运!