代码搜索不同类中的函数

时间:2016-03-08 03:25:03

标签: scala apache-spark

我正在尝试在Spark上实现ALS。我使用 ml 类而不是 mllib ,因为CSV文件在一列中包含String。 mllib 中的评级类不接受String作为参数。

我想使用来自 org.apache.spark.mllib.recommendation.MatrixFactorizationModel 类的预测函数,但在运行它时正在 org.apache.spark.rdd.RDD中搜索

这是我正在使用的代码。

import org.apache.spark.{SparkContext, SparkConf}
import org.apache.spark.ml.recommendation.ALS
import org.apache.spark.ml.recommendation.ALS.Rating
import org.apache.spark.mllib.recommendation.MatrixFactorizationModel
object LoadCsv{
def main(args: Array[String]): Unit = {

    val conf = new SparkConf().setAppName("Load CSV")
    val sc = new SparkContext(conf)
    println("READING FILE...............................");
    val data = sc.textFile("file.csv")

    val ratings = data.map(_.split(',') match { case Array(user, item, rate) =>
        Rating[String](user, item, rate.toFloat)
    })


    //val (userFactors, itemFactors) = ALS.train(ratings)
    //Build the recommendation model using ALS
    val rank = 10
    val numIterations = 10
    val model = ALS.train(ratings, rank, numIterations)

    // Evaluate the model on rating data
    val usersProducts = ratings.map { case Rating(user, product, rate) =>
      (user, product)
    }
    // GETTING ERROR OVER HERE.
    val predictions =
      model.predict(usersProducts).map { case Rating(user, product, rate) =>
        ((user, product), rate)
      }
    val ratesAndPreds = ratings.map { case Rating(user, product, rate) =>
      ((user, product), rate)
    }.join(predictions)
    val MSE = ratesAndPreds.map { case ((user, product), (r1, r2)) =>
      val err = (r1 - r2)
      err * err
    }.mean()
    println("Mean Squared Error = " + MSE)

    // Save and load model
    //model.save(sc, "/home/shishir/spark-Projects/op")
    //val sameModel = MatrixFactorizationModel.load(sc, "target/tmp/myCollaborativeFilter")
    // $example off$
  }

}

在运行代码时,我收到此错误:

LoadCsv.scala:34: value predict is not a member of (org.apache.spark.rdd.RDD[(String, Array[Float])], org.apache.spark.rdd.RDD[(String, Array[Float])])

[error] model.predict(usersProducts).map { case Rating(user, product, rate) =>

2 个答案:

答案 0 :(得分:1)

您的导入是"不正确",您使用的是:

import org.apache.spark.ml.recommendation.ALS
import org.apache.spark.ml.recommendation.ALS.Rating

当你应该使用它时:

import org.apache.spark.mllib.recommendation.ALS
import org.apache.spark.mllib.recommendation.Rating

您可以使用其他套餐,只是结果不会成为模型,但(如错误所示)和RDD。

你可以在线阅读为什么有两个ML包(我记得mllib包是旧的包并且包含一些设计缺陷,所以它们在ml重新实现,所以他们可以使用管道)

答案 1 :(得分:1)

看起来你正在混合MLLib和ML风格的方法。如果您的数据使用支持的ID类型(在这里看起来不是这样),您可以使用MLLib实现:

import org.apache.spark.mllib.recommendation.{ALS => OldALS}
import org.apache.spark.mllib.recommendation.{
  MatrixFactorizationModel => OldModel}
import org.apache.spark.mllib.recommendation.{Rating => OldRating}

val ratings: RDD[OldRating] = ???

val model: OldModel = OldALS()
  .setAlpha(0.01)
  .setIterations(numIterations)
  .setRank(rank)
  .run(ratings)

如果您的数据使用非标准ID并且您希望访问用户友好的API,最好使用DataFrames

val ratings: RDD[org.apache.spark.ml.recommendation.ALS.Rating[String]] = ???
val df = ratings.toDF

val als: org.apache.spark.ml.recommendation.ALS = new ALS()
  .setAlpha(0.01)
  .setMaxIter(numIterations)
  .setRank(rank)
val model: org.apache.spark.ml.recommendation.ALSModel = als.fit(df)

最后,您可以使用当前的方法,但是您必须直接操作用户因素和项目因素而不需要predict等帮助程序。