【问题标题】:Field "item" does not exist using Spark MLlib pipeline for ALS使用 ALS 的 Spark MLlib 管道不存在字段“项目”
【发布时间】:2015-07-20 09:06:21
【问题描述】:

我正在使用 ALS 训练推荐系统(Spark 版本:1.3.1)。现在我想通过交叉验证使用Pipeline 进行模型选择。作为第一步,我尝试适应 the example code 并想出了这个:

val conf = new SparkConf().setAppName("ALS").setMaster("local")
val sc = new SparkContext(conf)
val sqlContext = new SQLContext(sc)
import sqlContext.implicits._

val ratings: RDD[org.apache.spark.mllib.recommendation.Rating] = // ...
val als = new ALS().setMaxIter(10).setRank(10).setRegParam(0.01)
val pipeline = new Pipeline().setStages(Array(als))
val model = pipeline.fit(ratings.toDF)

当我运行它时,最后一行失败并出现异常:

Exception in thread "main" java.lang.IllegalArgumentException: Field "item" does not exist.
at org.apache.spark.sql.types.StructType$$anonfun$apply$25.apply(dataTypes.scala:1032)
at org.apache.spark.sql.types.StructType$$anonfun$apply$25.apply(dataTypes.scala:1032)
at scala.collection.MapLike$class.getOrElse(MapLike.scala:128)
at scala.collection.AbstractMap.getOrElse(Map.scala:58)
at org.apache.spark.sql.types.StructType.apply(dataTypes.scala:1031)
at org.apache.spark.ml.recommendation.ALSParams$class.validateAndTransformSchema(ALS.scala:148)
at org.apache.spark.ml.recommendation.ALS.validateAndTransformSchema(ALS.scala:229)
at org.apache.spark.ml.recommendation.ALS.transformSchema(ALS.scala:304)
at org.apache.spark.ml.Pipeline$$anonfun$transformSchema$4.apply(Pipeline.scala:142)
at org.apache.spark.ml.Pipeline$$anonfun$transformSchema$4.apply(Pipeline.scala:142)
at scala.collection.IndexedSeqOptimized$class.foldl(IndexedSeqOptimized.scala:51)
at scala.collection.IndexedSeqOptimized$class.foldLeft(IndexedSeqOptimized.scala:60)
at scala.collection.mutable.ArrayOps$ofRef.foldLeft(ArrayOps.scala:108)
at org.apache.spark.ml.Pipeline.transformSchema(Pipeline.scala:142)
at org.apache.spark.ml.PipelineStage.transformSchema(Pipeline.scala:58)
at org.apache.spark.ml.Pipeline.fit(Pipeline.scala:100)
at org.apache.spark.ml.Pipeline.fit(Pipeline.scala:79)
at org.apache.spark.ml.Estimator.fit(Estimator.scala:44)
...

我不在代码中的任何地方使用字符串"item",所以我认为它是某种默认值。当我将.setItemCol("itemId") 添加到als 时,异常消息会相应更改。

"item"是什么意思?我怎样才能使管道工作?

【问题讨论】:

    标签: scala apache-spark apache-spark-mllib


    【解决方案1】:

    好的,解决方案其实很简单:使用org.apache.spark.ml.recommendation.ALS.Rating 而不是org.apache.spark.mllib.recommendation.Rating,这样就可以了。

    否则.setItemCol("product") 可以解决问题,因为org.apache.spark.mllib.recommendation.Rating 有一个名为“product”的字段,而org.apache.spark.ml.recommendation.ALS.Rating 调用相应的字段“item”。给定一个字符串,访问案例类的某个字段(反射?),这一定是有什么魔力。

    【讨论】:

    • 恕我直言,不应该映射到 org.apache.spark.ml.recommendation.ALS.Rating 类,因为您正在做双重工作。 code 在内部为您将DataFrame 映射到Rating RDD :)。所以你要从评级到数据框再回到评级。如您所见,tt 似乎使用 setUserColsetItemCol 是使用新 Spark ML API 的方式。
    猜你喜欢
    • 2018-07-19
    • 2017-11-03
    • 1970-01-01
    • 1970-01-01
    • 2016-11-08
    • 1970-01-01
    • 2016-08-11
    • 2015-02-01
    相关资源
    最近更新 更多