带有字符串标签的 Spark ALS - 转换回字符串

Posted

技术标签:

【中文标题】带有字符串标签的 Spark ALS - 转换回字符串【英文标题】:Spark ALS with strings labels - Conversion back to string 【发布时间】:2017-03-07 20:08:01 【问题描述】:

我有这个代码:

val userIndexer: StringIndexer = new StringIndexer()
      .setInputCol("userKey")
      .setOutputCol("user")
val alsRatings = userIndexerModel.transform(ratings)
val matrixFactorizationModel = ALS.trainImplicit(alsRatings.rdd, rank = 10, iterations = 10)
val rec = matrixFactorizationModel.recommendProductsForUsers(20)

这会返回带有用户 ID 的推荐。我想找回我的用户密钥字符串。更有效的方法是什么?谢谢。

PD:我当然无法理解为什么 ALS 库开发人员不接受字符串标签。从外部处理转换(字符串到 int,然后是 int 到字符串)是非常痛苦和昂贵的。希望他们的积压中有问题或其他东西。

【问题讨论】:

例如IndexToString。 Python 中的相同 API:***.com/q/33636944/1560062 IndexToString 在你有另一个 Dataframe 时不起作用,它在应用 StringToIndex 的同一个数据帧中使用元数据。 如果你正确使用它就可以正常工作:) 检查例如setLabels 是的,但是 setLabels 意味着收集节点中的标签,因为它适用于数组,而不适用于 RRD 或数据集。如果标签数组真的很大,那可能无法扩展:/ 您知道StringIndexer 已经将所有标签存储在驱动程序内存中,对吧? 【参考方案1】:

我一般运行StringIndexer 收集驱动程序中的标签。和 将标签与索引并行化。而不是使用 StringIndexer 调用 Transform。我加入 DataFrame 以获得与 StringIndexer 相同的结果。

val swidConverter = new StringIndexer()
  .setInputCol("id")
  .setOutputCol("idIndex").fit(df)

val idDf = spark.sparkContext.parallelize(
            swidConverter.labels.zipWithIndex
        ).toDF("id", "idIndex").repartition(PARTITION_SIZE) // set the partition size depending on your data size.

// Joining the idDf(DataFrame) with the actual Data.
val indexedDF = df.join(idDf,idDf.col("id")===df.col("id")).select("idIndex","product_id","rating")

val als = new ALS()
  .setMaxIter(5)
  .setRegParam(0.01)
  .setUserCol("idIndex")
  .setItemCol("product_id")
  .setRatingCol("rating")

val model = als.fit(indexedDF)
val resultRaw = model.recommendForAllUsers(4)

// Joining the idDf(DataFrame) with the Result to get the original ID from the indexed Id.
val resultDf = resultRaw.join(idDf,resultRaw.col("idIndex")===idDf.col("idIndex")).select("id","recommendations")

【讨论】:

以上是关于带有字符串标签的 Spark ALS - 转换回字符串的主要内容,如果未能解决你的问题,请参考以下文章

将带有嵌套标签的 XML 读入 Spark RDD,并转换为 JSON

如何在我的 Spark 管道中集成 ALS 以实现非负矩阵分解?

如何在 Scala(Spark 2.0)中将带有字符串的 DataFrame 转换为带有 Vectors 的 DataFrame

Spark:测量 ALS 的性能

ALS推荐算法在Spark上的优化

Spark 的 ALS 中唯一项目的数量有啥限制?