- 一、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推荐给当前用户。
基于用户(user)的协同过滤举例:
1.首先我们根据网站的记录计算出一个用户与item的关联矩阵,如下:
2.图中,行是不同的用户,列是所有物品,(x, y)的值则是x用户对y物品的评分(喜好程度)。我们可以把每一行视为一个用户对物品偏好的向量,然后计算每两个用户之间的向量距离,这里我们用余弦相似度来算:
3.然后得出用户向量之间相似度如下,其中值越接近1表示这两个用户越相似:
4.最后,我们要为用户1推荐物品,则找出与用户1相似度最高的N名用户(设N=2)评价的物品,去掉用户1评价过的物品,则是推荐结果。
二、案例实现基于物品(Item)的CF原理如下:
1.基于物品的CF原理大同小异,只是主体在于物品:
2.分析各个用户对item的浏览记录。
3.依据浏览记录分析得出所有item之间的相似度;
4.对于当前用户评价高的item,找出与之相似度最高的N个item;
5.将这N个item推荐给用户。
-
测试数据格式
-
测试数据下载:测试数据下载
-
具体代码如下:
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") //[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) 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) } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)