【发布时间】:2016-06-07 13:34:17
【问题描述】:
我正在查看DeepDist (link) 模块并考虑将其与Gensim 的Doc2Vec API 结合起来以在PySpark 上训练段落向量。该链接实际上提供了以下干净示例,说明如何为Gensim 的Word2Vec 模型执行此操作:
from deepdist import DeepDist
from gensim.models.word2vec import Word2Vec
from pyspark import SparkContext
sc = SparkContext()
corpus = sc.textFile('enwiki').map(lambda s: s.split())
def gradient(model, sentences): # executes on workers
syn0, syn1 = model.syn0.copy(), model.syn1.copy() # previous weights
model.train(sentences)
return {'syn0': model.syn0 - syn0, 'syn1': model.syn1 - syn1}
def descent(model, update): # executes on master
model.syn0 += update['syn0']
model.syn1 += update['syn1']
with DeepDist(Word2Vec(corpus.collect()) as dd:
dd.train(corpus, gradient, descent)
print dd.model.most_similar(positive=['woman', 'king'], negative=['man'])
据我了解,DeepDist 正在将梯度下降的工作分批分配给 worker,并在 master 处重新组合和更新。如果我将Word2Vec 替换为Doc2Vec,则应该有正在使用词向量进行训练的文档向量。
于是我查看了gensim.models.doc2vec(link)的源代码。 Doc2Vec模型实例中有以下字段:
model.syn0model.syn0_lockfmodel.docvecs.doctag_syn0model.docvecs.doctag_syn0_lockf
与gensim.models.word2vec(link)的源代码相比,Doc2Vec模型中缺少以下字段:
model.syn1model.syn1neg
我想我不会碰lockf 向量,因为它们似乎是在训练完成后新数据点进来时使用的。因此我的代码应该类似于
from deepdist import DeepDist
from gensim.models.doc2vec import Doc2Vec, LabeledSentence
from pyspark import SparkContext
sc = SparkContext()
# assume my dataset is in format 10-char-id followed by doc content
# 1 line per doc
corpus = sc.textFile('data_set').map(
lambda s: LabeledSentence(words=s[10:].split(),labels=s[:10])
)
def gradient(model, sentence): # executes on workers
syn0, doctag_syn0 = model.syn0.copy(), model.docvecs.doctag_syn0.copy() # previous weights
model.train(sentence)
return {'syn0': model.syn0 - syn0, 'doctag_syn0': model.docvecs.doctag_syn0 - doctag_syn0}
def descent(model, update): # executes on master
model.syn0 += update['syn0']
model.docvecs.doctag_syn0 += update['doctag_syn0']
with DeepDist(Doc2Vec(corpus.collect()) as dd:
dd.train(corpus, gradient, descent)
print dd.model.most_similar(positive=['woman', 'king'], negative=['man'])
我在这里遗漏了什么重要的东西吗?例如:
- 我应该关心
model.syn1吗?它们到底是什么意思? -
model.*_lockf是训练后的锁定矩阵,我说对了吗? - 我可以使用
lambda s: LabeledSentence(words=s[10:].split(),labels=s[:10]来解析我的数据集,假设我将每个文档放在一行中,并以 0 填充的 10 位 id 为前缀吗?
非常感谢任何建议/贡献。我将写一篇博文来总结结果,在这里提到贡献者,可能会帮助其他人在扩展的分布式系统上训练 Doc2Vec 模型,而无需花费大量开发时间来尝试解决我现在正在解决的问题。
谢谢
2018 年 6 月 13 日更新
我很抱歉,因为我没有实现这一点。但是现在有更好的选择,DeepDist 已经有一段时间没有维护了。请阅读下面的评论。
如果您现在坚持尝试我的想法,请注意您的风险自负。另外,如果有人知道DeepDist 仍然有效,请在 cmets 中报告。这将有助于其他读者。
【问题讨论】:
-
那篇博文是你写的吗? :) 我真的很期待你的发现
-
你实现了吗?我也有兴趣在 pyspark 中训练 doc2vec。
-
对于正在阅读本文的人:我没有实现这个,直到我认为它不会起作用时为时已晚。 DeepDist 在后端使用 Flask 应用程序与 Spark Web 界面进行交互。由于它不再维护,Spark 的更新很可能已经破坏了它。如果您正在寻找 Spark 中的 Doc2Vec 培训,请选择 Deeplearning4J(deeplearning4j.org/doc2vec#)
标签: apache-spark pyspark gensim word2vec