协同过滤算法实验

         本次呢,简单介绍一下协同过滤算法,并且给出简单的电影推荐实验作为举例说明。利用Spark MLlib中的协同过滤算法完成针对特定用户的电影推荐功能。这一部分需要实现实现输入用户id,输出为其推荐的电影。

一、协同过滤

       所谓协同过滤,就是简单来说是利用某兴趣相投、拥有共同经验之群体的喜好来推荐使用者感兴趣的资讯,个人透过合作的机制给予资讯相当程度的回应并记录下来以达到过滤的目的进而帮助别人选择信息。对于实现针对用户个性的推荐功能这一需求,非常合适。

二、电影推荐

        首先来看我们的结果:

 

 

        需要用到的数据集下载链接在文章的最后。

大概是这个样子:

movies和ratings两个数据集

数据之间以 :: 隔开

movies的每一列分别表示

movie_id , movie_name , movie_type

 ratings的每一列分别表示:

movie_id , user_id , score , timestamp(时间戳)

 代码如下:

object SparkPi {
  case class Rating(userId: Int, movieId: Int, rating: Float, timestamp: Long)
  def parseRating(str: String): Rating = {
    val fields = str.split("::")
    assert(fields.size == 4)
    Rating(fields(0).toInt, fields(1).toInt, fields(2).toFloat, fields(3).toLong)
  }
  def main(args: Array[String]): Unit = {
    val sc=SparkSession.builder()
      .master("local")
      .appName("movie")
      .getOrCreate()
    val ratingRDD=sc.sparkContext.textFile("/ratings.dat")
    val ratings=sc.createDataFrame(ratingRDD.map(parseRating))
    val Array(training, test) = ratings.randomSplit(Array(0.8, 0.2))
    //训练模型
    val alsExplicit = new ALS()
      .setMaxIter(5)            
      .setRegParam(0.01)         
      .setUserCol("userId")
      .setItemCol("movieId")
      .setRatingCol("rating")    
    val alsImplicit = new ALS()
      .setMaxIter(5)           
      .setRegParam(0.01)   
      .setImplicitPrefs(true)
      .setUserCol("userId")
      .setItemCol("movieId")
      .setRatingCol("rating")    
    val modelExplicit = alsExplicit.fit(training)
    val modelImplicit = alsImplicit.fit(training)
    val predictionsExplicit = modelExplicit.transform(test).na.drop()
    val predictionsImplicit = modelImplicit.transform(test).na.drop()
    //计算模型误差
    val evaluator = new RegressionEvaluator()
      .setMetricName("rmse")
      .setLabelCol("rating")
      .setPredictionCol("prediction")
    val rmseExplicit = evaluator.evaluate(predictionsExplicit)
    val rmseImplicit = evaluator.evaluate(predictionsImplicit)
    println(s"Explicit:模型均方根误差 : $rmseExplicit")
    println(s"Implicit:模型均方根误差 : $rmseImplicit")
    println("请输入用户id:")
    val userId:Int=StdIn.readInt()
    val movieDF=ratings.where(s"userId= $userId")
    println(s"为id为 $userId 的用户推荐如下10部电影:")
    movieDF.limit(10).show()
    val df=movieDF.limit(10)
    //将数据存到数据库中
    val prop=new Properties()
    prop.put("user","root")
    prop.put("password","Wyk@123456")
    prop.put("driver","com.mysql.jdbc.Driver")
df.write.mode("Overwrite").jdbc("jdbc:mysql://localhost:3306/movie","movie.advice",prop)
  }
}

 下面是有关的数据集MovieLens | GroupLensicon-default.png?t=LA92https://grouplens.org/datasets/movielens/