zoukankan      html  css  js  c++  java
  • Spark学习笔记——构建基于Spark的推荐引擎

    推荐模型

    推荐模型的种类分为:

    1.基于内容的过滤:基于内容的过滤利用物品的内容或是属性信息以及某些相似度定义,来求出与该物品类似的物品。

    2.协同过滤:协同过滤是一种借助众包智慧的途径。它利用大量已有的用户偏好来估计用户对其未接触过的物品的喜好程度。其内在思想是相似度的定义。

    在基于用户的方法的中,如果两个用户表现出相似的偏好(即对相同物品的偏好大体相同),那就认为他们的兴趣类似。

    同样也可以借助基于物品的方法来做推荐。这种方法通常根据现有用户对物品的偏好或是评级情况,来计算物品之间的某种相似度。

    3.矩阵分解:

    3.1. 显式矩阵分解

    例如我们可以得到多个用户对多部电影的评级的数据,这样我们就可以得到一个用户—电影评级的矩阵

    我们所得到的这个矩阵是稀疏的,假设得到的“用户—物品”矩阵的维度为U×I,我们需要对其进行降维,然后得到一个表示用户的U×k维矩阵和一个表示物品的k×I维矩阵

    要计算给定用户对某个物品的预计评级

    只需要从用户因子矩阵和物品因子矩阵分别选取相应的行(用户因子向量)与列(物品因子向量),然后计算两者的点积即可

    对于物品之间相似度的计算,可以用最近邻模型中用到的相似度衡量方法。不同的是,这里可以直接利用物品因子向量,将相似度计算转换为对两物品因子向量之间相似度的计算

    1.使用的是Spark-shell和Scala语言,同样需要把文件放在Hadoop文件系统中

    启动Spark-shell

    val rawData = sc.textFile("/user/common/ml-100k/u.data")
    rawData.first()
    
    #输出 res1: String = 196	242	3	881250949
    #该数据由用户ID、影片ID、星级和时间戳等字段依次组成
    

     提取出前三个字段

    val rawRatings = rawData.map(_.split("	").take(3))
    

     使用ALS模型进行训练

    import org.apache.spark.mllib.recommendation.ALS
    val ratings = rawRatings.map { case Array(user, movie, rating) => Rating(user.toInt, movie.toInt, rating.toDouble) }
    scala> ratings.first()
    #输出 res24: org.apache.spark.mllib.recommendation.Rating = Rating(196,242,3.0)
    

     

    val model = ALS.train(ratings, 50, 10, 0.01)
    

     结果,每个用户和每部电影都会有对应的因子数组(分别含943个和1682个因子)

    scala> model.userFeatures
    res26: org.apache.spark.rdd.RDD[(Int, Array[Double])] = users MapPartitionsRDD[454] at mapValues at ALS.scala:269
    
    scala> model.userFeatures.count
    res27: Long = 943
    
    scala> model.productFeatures.count
    res28: Long = 1682
    

    1. 从MovieLens 100k数据集生成电影推荐

     MLlib的推荐模型基于矩阵分解,因此可用模型所求得的因子矩阵来计算用户对物品的预计评级

    scala> val predictedRating = model.predict(789, 123)
    predictedRating: Double = 2.4585387904925593
    

    predict 函数同样可以以 (user, item) ID对类型的RDD对象为输入,这时它将为每一对都生成相应的预测得分。我们可以借助这个函数来同时为多个用户和物品进行预测。 

    为某个用户生成前K个推荐物品 , 可借助 MatrixFactorizationModel 所提供的recommendProducts 函数来实现。该函数需两个输入参数: user 和 num 。其中 user 是用户ID,而 num 是要推荐的物品个数。

    val userId = 789
    val K = 10
    val topKRecs = model.recommendProducts(userId, K)
    println(topKRecs.mkString("
    "))
    
    scala> println(topKRecs.mkString("
    "))
    Rating(789,179,5.5976762921826575)
    Rating(789,1022,5.431324881530808)
    Rating(789,182,5.4204134645044615)
    Rating(789,942,5.340233945688523)
    Rating(789,188,5.254370757962667)
    Rating(789,183,5.208694711418427)
    Rating(789,428,5.1758907376213825)
    Rating(789,198,5.150276931639322)
    Rating(789,59,5.123932678029936)
    Rating(789,715,5.103514906503706)
    

     2. 检验推荐内容

    读入电影数据,导入为Map[Int, String] 类型,即从电影ID到标题的映射

    val movies = sc.textFile("/user/common/ml-100k/u.item")
    val titles = movies.map(line => line.split("\|").take(2)).map(array=> (array(0).toInt,array(1))).collectAsMap()
    

     查看123对应的电影的名称

    scala> titles(123)
    res30: String = Frighteners, The (1996)
    
    val moviesForUser = ratings.keyBy(_.user).lookup(789)
    println(moviesForUser.size)    #这个用户对33部电影做过评级
    #获取评级最高的前10部电影
    scala> moviesForUser.sortBy(-_.rating).take(10).map(rating => (titles(rating.product),rating.rating)).foreach(println)
    (Godfather, The (1972),5.0)
    (Trainspotting (1996),5.0)
    (Dead Man Walking (1995),5.0)
    (Star Wars (1977),5.0)
    (Swingers (1996),5.0)
    (Leaving Las Vegas (1995),5.0)
    (Bound (1996),5.0)
    (Fargo (1996),5.0)
    (Last Supper, The (1995),5.0)
    (Private Parts (1997),4.0)
    
    scala> topKRecs.map(rating => (titles(rating.product), rating.rating)).foreach(println)
    (Clockwork Orange, A (1971),5.5976762921826575)
    (Fast, Cheap & Out of Control (1997),5.431324881530808)
    (GoodFellas (1990),5.4204134645044615)
    (What's Love Got to Do with It (1993),5.340233945688523)
    (Full Metal Jacket (1987),5.254370757962667)
    (Alien (1979),5.208694711418427)
    (Harold and Maude (1971),5.1758907376213825)
    (Nikita (La Femme Nikita) (1990),5.150276931639322)
    (Three Colors: Red (1994),5.123932678029936)
    (To Die For (1995),5.103514906503706)
    
  • 相关阅读:
    EasyPlayer-Android播放器是如何实现播放器退到后台后,再回到前台时,播放画面的无缝衔接?
    EasyPlayer网页全终端播放器之Android版的分屏策略及如何设置2分屏
    海康大华安防网络摄像头Onvif、RTSP网络无插件直播流媒体服务解决方案EasyNVR表单重复提交的优化方案
    Onvif/RTSP海康大华网络安防摄像机网页无插件直播方案EasyNVR中直播页面和视频列表页面的区别介绍
    Onvif/RTSP海康大华网络安防摄像机网页无插件直播方案EasyNVR如何使用Excel将通道配置简单化?
    集RTMP, HLS, FLV, WebSocket 于一身的网页直播/点播播放器EasyPlayer.js引用videojs无法自动播放问题解决
    Onvif/RTSP海康大华网络安防摄像机网页无插件直播方案EasyNVR登陆用户名密码失效问题解决方案
    RTSP转RTSP、RTMP、HLS、FLV安防摄像头网页无插件直播流媒体服务器EasyNVR在IE浏览器下的 pointer-events- none前端兼容性调试
    Onvif/RTSP网络安防摄像机网页无插件直播方案EasyNVR接口调用返回出现“Unauthorized”解决方案
    安防监控流媒体服务器对接宇视摄像机配置OCX插件安装时出现Failed to register ocx, error code 14001错误问题分析
  • 原文地址:https://www.cnblogs.com/tonglin0325/p/6786377.html
Copyright © 2011-2022 走看看