将句子嵌入分布式Spark系统中的最有效方法是什么?

时间:2019-01-03 21:20:07

标签: apache-spark nlp bigdata

我有一个带有单词嵌入的文件(将单词嵌入定义为单词的向量表示形式),格式如下:

a | [0.23, 0.04, ..., -0.22]
aaron | [0.21, 0.08, ..., -0.41]
... | ...
zebra | [0.97, 0.01, ..., -0.34]

此文件约为2.5 GB。我也想将大量句子转换为向量,例如:

Yes sir, today is a great day.
Would you want to buy that blue shirt?
...
Is there anything else I can help you with?

我的句子嵌入策略目前很简单:

For each sentence:
  For each word:
    Obtain the vector representation of the word using the word embedding file.
  End
  Calculate the average of the word vectors of the sentence.
End

我认为,由于我想嵌入大量的句子,因此可以使用Spark来完成此任务;将单词嵌入作为文件存储在HDFS中,并使用Spark SQL从Hive表中查询句子,但是由于每个节点可能需要访问整个单词嵌入文件,这意味着在每个节点中收集整个单词嵌入RDD节点,使节点之间的通信非常昂贵。

任何人都对如何有效解决此问题有任何想法?如果问题尚不清楚,或者您认为我对Spark的工作方式有误解,也请告诉我。我仍在学习,非常感谢您的帮助!

先谢谢了。

2 个答案:

答案 0 :(得分:0)

首先,您word是一成不变的,并且您担心网络效率。我认为您可以将word设置为广播参数,因此word将存储在本地的每个节点中,而您只将整个word传送了一次(总共N次,N是执行者人数)。 然后,如果您同时嵌入word和句子,这意味着必须进行网络传输,则最好在最终聚合之前进行局部归约。

答案 1 :(得分:0)

您可以执行以下操作:

  1. 将您的词嵌入文件转换为Spark DataFrame,
    1. 看来您可以使用None pyspark api docs
  2. 更改DataFrame架构(my_embeddings = spark.read.csv(path="path/to/your_file.csv", sep="|"))以匹配以下内容:

    1. my_embeddings.schema
  3. 创建一个简单的占位符Spark ML StructType(List(StructField(word,StringType,true),StructField(vector,ArrayType(FloatType,true),true)))模型并保存到hdfs。 pyspark api docs
    1. 例如Word2Vec
  4. 使用上面在model_name.write().overwrite().save("your_hdfs_path_to/model_name")目录中创建的嵌入DataFrame覆盖小型Word2Vec模型数据。
    1. your_hdfs_path_to/model_name/data/
  5. my_embeddings.write.parquet("your_hdfs_path_to/model_name/data/", mode='overwrite') pyspark api docs加载Word2Vec模型
  6. 创建一个Spark DataFrame,其中每个句子都位于单独的行中。
  7. 使用Word2VecModel.load("your_hdfs_path_to/model_name") pyspark api docs
  8. 标记句子
  9. 使用该模型转换包含标记化句子的Spark DataFrame。输出列将包含单个向量,该向量的大小与词嵌入向量的大小相同,该向量将是句子中所有词向量的平均值。
    1. Word2VecModel使用文档中所有单词的平均值将每个文档转换为向量docs。在您的情况下,“每个文档”将是您的每个句子。 pyspark api docs

一起(猜测某些参数,并使用pySpark):

RegexTokenizer