python - 在 gensim 中批量训练 word2vec,支持多个工作人员
问题描述
语境
Word2Vec
关于如何使用gensim
流数据进行训练存在几个问题。无论如何,这些问题并没有解决流不能使用多个工作线程的问题,因为没有数组可以在线程之间拆分。
因此,我想创建一个为 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)
如果我只生成一个拆分文档就可以了,我假设 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', '...']], [[...], [...]]]
(=> list of list of list) 无法由 gensim 处理。
我的问题:
我可以“流”通过批次以使用多个工人吗?如何相应地更改我的代码?
解决方案
只想重申
@gojomo的评论是要走的路:使用大型语料库和多个cpus,使用参数而不是训练gensim word2vec要快得多,如文档中所述:corpus_file
sentences
- corpus_file (str, optional) -- LineSentence格式的语料库文件的路径。您可以使用此参数而不是句子来提高性能。只需要传递一个句子或 corpus_file 参数(或者它们都不传递,在这种情况下,模型未初始化)。
LineSentence 格式基本上每行只有一个句子,单词以空格分隔。纯文本、.bz2 或 gz。
推荐阅读
- c# - SkiaSharp 将 SVG 转换为 PNG 会破坏图像
- angular - prerender.ts(7,62) 中的错误:错误 TS2307:找不到模块“./dist-prerender/main.bundle”
- batch-file - 批量循环将文本文件写入不同的文件夹
- mysql - MySQL全文搜索对具有相同值的所有结果进行评分
- json - 我如何处理 JSON 对象,而某些值甚至不是 nil(丢失或不存在)以便 swift
- perl - 有没有办法在 perl 中托管一个应该在 HTTPS 中的 webServer
- android - Included ConstraintLayout deosn't fix position when TextView has two lines
- google-apps-script - 如何在谷歌应用脚本自定义函数中获取“活动用户”的用户属性
- html - angular2-date-picker - 仅显示当前日期时间
- angular - 自定义对象的角度投标数组 - 来自 httpget 的属性的大写/小写问题名称