从 gensim word2vec 调用 model.train() 时收到以下提示
INFO : EPOCH 0: training on 0 raw words (0 effective words) took 0.0s, 0 effective words/s
我在搜索答案时发现的唯一解决方案指向itarable与iterator差异,此时,我尝试了一切可以解决这个问题的方法我自己的,目前,我的代码如下所示:
class MyCorpus:
def __init__(self, corpus):
self.corpus = corpus.copy()
def __iter__(self):
for line in self.corpus:
x = re.sub("(<br ?/?>)|([,.'])|([^ A-Za-z']+)", '', line.lower())
yield utils.simple_preprocess(x)
sentences = MyCorpus(corpus)
w2v_model = Word2Vec(
sentences = sentences,
vector_size = w2v_size,
window = w2v_window,
min_count = w2v_min_freq,
workers = -1
)
corpus
变量是一个包含句子的列表,每个句子都是一个字符串。
我尝试了无数的“测试”来看看我的类是否确实是可迭代的,例如:
print(sum(1 for _ in sentences))
print(sum(1 for _ in sentences))
print(sum(1 for _ in sentences))
例如,它们都表明我的类是可迭代的,所以在这一点上,我认为问题一定是其他问题。
最佳答案
workers=-1
不是 Gensim 的 Word2Vec
模型支持的值;这本质上意味着您没有使用任何线程。
相反,您必须指定要使用的实际工作线程数。
当使用可迭代语料库时,最佳工作线程数量通常是 CPU 核心数量的某个数字,但如果你有 16 个以上核心,则不要高于 8-12,因为一些难以删除的因素Python 的全局解释器锁(“GIL”)和 Gensim 主读取器线程方法效率低下。
通常,如果您的可迭代对象在预处理中没有执行任何昂贵或重复的操作(例如任何基于正则表达式的标记化或在每个时期重复的标记化),您将获得更好的吞吐量。因此最好执行一次此类预处理,将生成的简单空格分隔标记写入新文件。然后,使用非常简单、无正则表达式、仅进行空格分割的标记化来读取该文件。
(如果性能成为大型数据集的主要问题,您还可以研究指定语料库的替代 corpus_file
方法。它需要一个文件,其中每个文本都在自己的行上,并且 token 已经只是以空格分隔。但它随后让每个工作线程读取自己的文件范围,GIL/读取器线程瓶颈要少得多,因此使用 workers
等于 CPU 核心计数对于吞吐量来说大致是最佳的。)
关于python - Gensim Word2Vec 令人疲惫不堪的可迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73968024/