繁体   English   中英

在 gensim 中批量训练 word2vec,支持多个工作人员

[英]Batch-train word2vec in gensim with support of multiple workers

语境

关于如何使用带有流数据的gensim训练Word2Vec存在几个问题。 无论如何,这些问题并没有解决流不能使用多个工作线程的问题,因为没有数组可以在线程之间拆分。

因此,我想创建一个为 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
            )

这会导致错误

类型错误:不可散列类型:“列表”

由于如果我只生成一个拆分文档, dataGenerator(data)就可以工作,我假设 gensims word2vec将生成器包装在一个额外的列表中。 在这种情况下, __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', '...']], [[...], [...]]] (=> list of list) 无法由 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功能后,大约需要十分钟,直到所有内核都正常工作。

似乎构建词汇表不支持多核,因此,只有一个用于此任务。 据推测,它花了这么长时间,因为 auf 语料库大小。 gensim 构建词汇后,所有核心都用于训练。

所以如果你也在这个问题上运行,也许一些耐心会有所帮助:)

只是想重申@gojomo 的评论是通往 go 的方式:使用大型语料库和多个 cpus,使用corpus_file参数而不是sentences训练 gensim word2vec要快得多,如文档中所述

  • corpus_file (str, optional) -- LineSentence格式的语料库文件的路径。 您可以使用此参数而不是句子来提高性能。 只有一个句子或 corpus_file arguments 需要传递(或者它们都不需要传递,在这种情况下,model 未初始化)。

LineSentence 格式基本上每行只有一个句子,单词以空格分隔。 纯文本、.bz2 或 gz。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM