前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >算法推荐 — 协同过滤

算法推荐 — 协同过滤

作者头像
木野归郎
发布2020-06-15 14:48:00
8220
发布2020-06-15 14:48:00
举报
文章被收录于专栏:share ai happinessshare ai happiness

CF协同过滤算法

求解评分矩阵的一种典型方法是:ALS,在spark-mllib库中有实现好的api;

K可以视为:隐性偏好因子的维度数

K越大,隐含的偏好因子就越多,计算效果更好,但是运算量更大!

算法思想:

CF协同过滤算法推荐实战

数据加工

从各类数据中,计算出每个用户对它所接触过的物品的评分,整成如下格式:

用户id, 物品id, 评分

U001 p0001 8

U001 p0020 10

U001 p1010 6

U002 p0030 8

........

可以用一个case class描述上述数据

case class Rating(uid:String,itemid:String,rate:Float)

模型训练

调用spark-mllib中ALS算法

代码语言:javascript
复制
object ALSExample {

// 定义评分数据封装类
  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]) {
    Logger.getLogger("org").setLevel(Level.WARN)
val spark = SparkSession
      .builder
      .appName("ALSExample")
      .master("local[*]")
      .getOrCreate()
import spark.implicits._

// 加载评分数据,并解析为Rating对象
val ratings = spark.read.textFile("G:\\whale\\doit_recommend\\data\\als\\sample_movielens_ratings.txt")
      .map(parseRating)
      .toDF()

// 划分训练数据与测试数据集
val Array(training, test) = ratings.randomSplit(Array(0.8, 0.2))

// 基于训练数据构建ALS推荐模型
val als = new ALS()
      .setMaxIter(5)
      .setRegParam(0.01)
      .setUserCol("userId")
      .setItemCol("movieId")
      .setRatingCol("rating")

// 训练模型(求解方程组)
val model = als.fit(training)

// 基于RMSE对test数据集的预测结果进行模型评估
// 设置冷启动策略为drop,对于新注册用户避免产生空推荐矩阵
    model.setColdStartStrategy("drop")
// 针对测试数据集进行模型预测
val predictions: DataFrame = model.transform(test)

    predictions.printSchema()
    predictions.show(10,false)

// 构造一个评估模型,设置评估指标为RMSE
val evaluator = new RegressionEvaluator()
      .setMetricName("rmse")  // rmse 均方差
      .setLabelCol("rating")
      .setPredictionCol("prediction")

// 评估预测结果
val rmse = evaluator.evaluate(predictions)
    println(s"均方误差 = $rmse")

// 均方误差 = 1.827332995575392
//sys.exit(1)

// 为每个用户推荐top10个物品
val userRecs: DataFrame = model.recommendForAllUsers(10)

// 为每个物品推荐top10个用户
val movieRecs = model.recommendForAllItems(10)

// 抽取用户数据子集
val users = ratings.select(als.getUserCol).distinct().limit(3)
// 为子集用户推荐top10部电影
val userSubsetRecs = model.recommendForUserSubset(users, 10)

// 抽取电影子集
val movies = ratings.select(als.getItemCol).distinct().limit(3)
// 为子集电影推荐top10用户
val movieSubSetRecs = model.recommendForItemSubset(movies, 10)

// 打印各项推荐结果
/*userRecs.printSchema()
    userRecs.show(10,false)

    movieRecs.printSchema()
    movieRecs.show(10,false)

    userSubsetRecs.printSchema()
    userSubsetRecs.show(10,false)

    movieSubSetRecs.printSchema()
    movieSubSetRecs.show(10,false)*/

// 保存推荐结果
    userRecs.write.json("G:\\whale\\doit_recommend\\data\\rec_result")
    spark.stop()
  }
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-02-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 OnlyCoding 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档