SparkMllib之CF协调过滤算法案例(基于用户的)

SparkMllib之CF协调过滤算法案例(基于用户的)

    • 一、SparkMLlib实现K-Means
    • 二、案例实现

一、SparkMLlib实现K-Means


协同过滤算法(Collaborative Filtering:CF)是很常用的一种算法,在很多电商网站上都有用到。CF算法包括基于用户的CF(User-based CF)和基于物品的CF(Item-based CF)。
1.基于用户(user)的CF原理如下:
2.分析各个用户对item的评价(通过浏览记录、购买记录等);
3.依据用户对item的评价计算得出所有用户之间的相似度;
4.选出与当前用户最相似的N个用户;
5.将这N个用户评价最高且当前用户又没有浏览过的item推荐给当前用户。
SparkMllib之CF协调过滤算法案例(基于用户的)_第1张图片

基于用户(user)的协同过滤举例:
1.首先我们根据网站的记录计算出一个用户与item的关联矩阵,如下:
SparkMllib之CF协调过滤算法案例(基于用户的)_第2张图片
2.图中,行是不同的用户,列是所有物品,(x, y)的值则是x用户对y物品的评分(喜好程度)。我们可以把每一行视为一个用户对物品偏好的向量,然后计算每两个用户之间的向量距离,这里我们用余弦相似度来算:
在这里插入图片描述
3.然后得出用户向量之间相似度如下,其中值越接近1表示这两个用户越相似:
SparkMllib之CF协调过滤算法案例(基于用户的)_第3张图片
4.最后,我们要为用户1推荐物品,则找出与用户1相似度最高的N名用户(设N=2)评价的物品,去掉用户1评价过的物品,则是推荐结果。

基于物品(Item)的CF原理如下:
1.基于物品的CF原理大同小异,只是主体在于物品:
2.分析各个用户对item的浏览记录。
3.依据浏览记录分析得出所有item之间的相似度;
4.对于当前用户评价高的item,找出与之相似度最高的N个item;
5.将这N个item推荐给用户。
SparkMllib之CF协调过滤算法案例(基于用户的)_第4张图片

二、案例实现


  1. 测试数据格式
    SparkMllib之CF协调过滤算法案例(基于用户的)_第5张图片

  2. 测试数据下载:测试数据下载

  3. 具体代码如下:

    package com.spark.ml
    
    import org.apache.log4j.{
           Level, Logger}
    import org.apache.spark.{
           SparkConf, SparkContext}
    import org.apache.spark.mllib.linalg.distributed.{
           CoordinateMatrix, MatrixEntry, RowMatrix}
    import org.apache.spark.rdd.RDD
    
    object UserBase {
           
      def main(args: Array[String]): Unit = {
           
        Logger.getLogger("org.apache.spark").setLevel(Level.ERROR)
        Logger.getLogger("org.eclipse.jetty.server").setLevel(Level.OFF)
    
        //读入数据
        val conf = new SparkConf().setAppName("UserBaseModel").setMaster("local[2]")
        val sc = new SparkContext(conf)
        val data = sc.textFile("testdatas/ratingdata.data")
    
        /*
        * MatrixEntry代表一个分布式矩阵中的每一行(Entry)
        * 这里的每一项都是一个(i: Long, j: Long, value: Double) 指示行列值的元组tuple。
        * 其中i是行坐标,j是列坐标,value是值。
        * 注意:坐标从零开始
        */
        //[1,2,3]
        val parseData: RDD[MatrixEntry] =
        data.map(_.split(",") match {
            case Array(user, item, rate) => MatrixEntry(user.toLong-1, item.toLong-1, rate.toDouble) })
    
        //CoordinateMatrix是Spark MLLib中专门保存user_item_rating这种数据样本的
        val ratings = new CoordinateMatrix(parseData)
    
        /* 由于CoordinateMatrix没有columnSimilarities方法,所以我们需要将其转换成RowMatrix矩阵,调用他的columnSimilarities计算其相似性
        * RowMatrix的方法columnSimilarities是计算,列与列的相似度,现在是user_item_rating,需要转置(transpose)成item_user_rating,这样才是用户的相似*/
        val matrix: RowMatrix = ratings.transpose().toRowMatrix()
        //计算用户的相似性,并输出
        val similarities = matrix.columnSimilarities()
        println("用户相似性矩阵")
        similarities.entries.collect().map(x => {
           
          println(x.i + "->" + x.j + "->" + x.value)
        })
    
        //得到用户1对所有物品的评分
        val ratingOfUser1 = ratings.entries.filter(_.i==0).map(x=>{
           (x.j,x.value)}).sortBy(_._1).collect().map(_._2).toList.toArray
        println("得到用户1对每种物品的评分")
        for(s <- ratingOfUser1) println(s)
    
        //用户1对所有物品的平均评分
        val avgRatingOfUser1 = ratingOfUser1.sum/ratingOfUser1.size
        println("用户1对所有物品的平均评分:" + avgRatingOfUser1)
    
        //其他用户对物品1的评分,drop(1)表示除去用户1的评分
        val otherRatingsToItem1=matrix.rows.collect()(0).toArray.drop(1)
        println("其他用户对物品1的评分")
        for(s <- otherRatingsToItem1) println(s)
    
        //得到用户1相对于其他用户的相似性(即:,降序排列:权重)value越大,表示相似度越高
        val weights =similarities.entries.filter(_.i==0).sortBy(_.value,false).map(_.value).collect()
        println("用户1相对于其他用户的相似性")
        for(s <- weights) println(s)
      }
    }
    

你可能感兴趣的:(Spark,算法,推荐算法,机器学习)