在多个工人的支持下,在gensim中批量训练word2vec



上下文

关于如何使用具有流式数据的CCD_ 2来训练CCD_。无论如何,这些问题并没有解决流不能使用多个工作线程的问题,因为线程之间没有可分割的数组。

因此,我想创建一个生成器,为gensim提供这样的功能。我的结果看起来像:

from gensim.models import Word2Vec as w2v
#The data is stored in a python-list and unsplitted.
#It's too much data to store it splitted, so I have to do the split while streaming.
data = ['this is document one', 'this is document two', ...]
#Now the generator-class
import threading
class dataGenerator:
"""
Generator for batch-tokenization.
"""
def __init__(self, data: list, batch_size:int = 40):
"""Initialize generator and pass data."""
self.data = data
self.batch_size = batch_size
self.lock = threading.Lock()

def __len__(self):
"""Get total number of batches."""
return int(np.ceil(len(self.data) / float(self.batch_size)))

def __iter__(self) -> list([]):
"""
Iterator-wrapper for generator-functionality (since generators cannot be used directly).
Allows for data-streaming.
"""
for idx in range(len(self)):
yield self[idx]

def __getitem__(self, idx):
#Make multithreading thread-safe
with self.lock:
# Returns current batch by slicing data.
return [arr.split(" ") for arr in self.data[idx * self.batch_size : (idx + 1) * self.batch_size]]

#And now do the training
model = w2v(
sentences=dataGenerator(data),
size=300,
window=5,
min_count=1,
workers=4
)

这导致错误

类型错误:不可更改类型:"list">

如果我只生成一个单独的拆分文档,dataGenerator(data)就会工作,我假设gensimsword2vec将生成器封装在一个额外的列表中。在这种情况下,__iter__看起来像:

def __iter__(self) -> list:
"""
Iterator-wrapper for generator-functionality (since generators cannot be used directly.
Allows for data-streaming.
"""
for text in self.data:
yield text.split(" ")

因此,我的批次也会被包装,导致类似[[['this', '...'], ['this', '...']], [[...], [...]]](=>列表列表的列表(的东西不能由gensim处理。




我的问题:

为了使用多个工人,我可以"流式"传递批次吗?如何相应地更改代码

我似乎太不耐烦了。我运行了上面写的流功能,它只处理一个文档而不是一批:

def __iter__(self) -> list:
"""
Iterator-wrapper for generator-functionality (since generators cannot be used directly.
Allows for data-streaming.
"""
for text in self.data:
yield text.split(" ")

启动w2v-功能后,大约花了十分钟时间,直到所有核心都正常工作。

构建词汇表似乎不支持多个核心,因此,只有一个核心用于此任务。大概是因为语料库的大小,所以花了这么长时间。在gensim构建vocab之后,所有核心都用于训练。

因此,如果你也在处理这个问题,也许一些耐心已经有帮助了:(

我只想重申一下@gojomo的评论是可行的:使用大型语料库和多个cpu,使用corpus_file参数而不是sentences来训练gensim word2vec的速度要快得多,如文档中所述:

  • corpus_file (str,可选(–LineSentence格式的语料库文件的路径。你可以用这个论点代替句子来提高成绩。只需要传递一个句子或corpus_file参数(或者不传递它们,在这种情况下,模型未初始化(

LineSentence格式基本上每行只有一句话,单词之间用空格分隔。纯文本、.bz2或gz。

最新更新