我尝试使用来自https://nlp.stanford.edu/projects/glove/的预训练GloVe模型在PySpark中实现一个简单的Doc2Vec算法。
我有两个RDD:
表格(K:[V])中称为documents
的一对RDD,其中K是文档ID,[V]是该文档中所有单词的列表,例如
('testDoc1':'i am using spark')
('testDoc2':'testing spark')
一对称为words
的RDD,表示以K:V形式嵌入的单词,其中K是单词,V是表示单词的向量,例如
('i', [0.1, 0.1, 0.1])
('spark': [0.2, 0.2, 0.2])
('am', [0.3, 0.3, 0.3])
('testing', [0.5, 0.5, 0.5])
('using', [0.4, 0.4, 0.4])
迭代documents
中的单词以获得所有单词的平均向量和的正确方法是什么?在上面的示例中,最终结果如下所示:
('testDoc1':[0.25, 0.25, 0.25])
('testDoc2':[0.35, 0.35, 0.35])
答案 0 :(得分:2)
假设您有一个函数tokenize
,它将字符串转换为单词列表。然后,您可以flatMap
documents
获取[{1}}元组RDD
:
(word, document id)
然后加入flattened_docs = documents.flatMap(lambda x: [(word, x[0]) for word in tokenize(x[1])])
将为您提供words
个元组,此时您可以放弃这些字词:
(word, (document id, vector))
请注意,这是一个内部联接,因此您丢弃了没有嵌入的单词。由于您可能想要计算平均值中的这些单词,因此左连接可能更合适,然后您必须使用零向量(或您选择的任何向量)替换任何结果doc_vectors = flattened_docs.join(words).values
。/ p>
我们可以按文档ID分组以获得None
的rdd然后平均(我假设您有一个名为(document id, [list of vectors])
的函数。)
average
(请原谅我受Scala影响的Python。已经有一段时间了,因为我使用了pyspark而我还没有检查它是final_vectors = doc_vectors.groupByKey().mapValues(average)
还是flatMap
等等。)