Spark入门:协同过滤算法

协同过滤是一种基于一组兴趣相同的用户或项目进行的推荐,它根据邻居用户(与目标用户兴趣相似的用户)的偏好信息产生对目标用户的推荐列表。

关于协同过滤的一个经典的例子就是看电影。如果你不知道哪一部电影是自己喜欢的或者评分比较高的,那么通常的做法就是问问周围的朋友,看看最近有什么好的电影推荐。而在问的时候,肯定都习惯于问跟自己口味差不多的朋友,这就是协同过滤的核心思想。因此,协同过滤是在海量数据中挖掘出小部分与你品味类似的用户,在协同过滤中,这些用户成为邻居,然后根据他们喜欢的东西组织成一个排序的目录推荐给你(如下图所示)。

下面代码读取spark的示例文件,文件中每一行包括一个用户id、商品id和评分。我们使用默认的ALS.train()方法来构建推荐模型并评估模型的均方差。

importorg.apache.spark.SparkConfimportorg.apache.spark.SparkContextimportorg.apache.spark.mllib.recommendation.ALSimportorg.apache.spark.mllib.recommendation.MatrixFactorizationModelimportorg.apache.spark.mllib.recommendation.Rating2.读取数据:首先,读取文本文件,把数据转化成rating类型,即[Int,Int,Double]的RDD;

scala>valdata=sc.textFile("../data/mllib/als/test.data")data:org.apache.spark.rdd.RDD[String]=../data/mllib/als/test.dataMapPartitionsRDD[1]attextFileat:21scala>valratings=data.map(_.split(',')match{caseArray(user,item,rate)=>Rating(user.toInt,item.toInt,rate.toDouble)})ratings:org.apache.spark.rdd.RDD[org.apache.spark.mllib.recommendation.Rating]=MapPartitionsRDD[2]atmapat:26可以把数据打印出来看一下:

scala>ratings.foreach{x=>println(x)}Rating(1,1,5.0)Rating(3,2,5.0)Rating(1,2,1.0)Rating(3,3,1.0)Rating(1,3,5.0)Rating(3,4,5.0)Rating(1,4,1.0)Rating(4,1,1.0)Rating(2,1,5.0)Rating(4,2,5.0)Rating(2,2,1.0)Rating(4,3,1.0)Rating(2,3,5.0)Rating(4,4,5.0)Rating(2,4,1.0)Rating(3,1,1.0)其中Rating中的第一个int是user编号,第二个int是item编号,最后的double是user对item的评分。

划分训练集和测试集,比例分别是0.8和0.2。

scala>valsplits=ratings.randomSplit(Array(0.8,0.2))splits:Array[org.apache.spark.rdd.RDD[org.apache.spark.mllib.recommendation.Rating]]=Array(MapPartitionsRDD[5]atrandomSplitat:30,MapPartitionsRDD[6]atrandomSplitat:30)scala>valtraining=splits(0)training:org.apache.spark.rdd.RDD[org.apache.spark.mllib.recommendation.Rating]=MapPartitionsRDD[5]atrandomSplitat:30scala>valtest=splits(1)test:org.apache.spark.rdd.RDD[org.apache.spark.mllib.recommendation.Rating]=MapPartitionsRDD[6]atrandomSplitat:30指定参数值,然后使用ALS训练数据建立推荐模型:

scala>valrank=10rank:Int=10scala>valnumIterations=10numIterations:Int=10scala>valmodel=ALS.train(training,rank,numIterations,0.01)model:org.apache.spark.mllib.recommendation.MatrixFactorizationModel=org.apache.spark.mllib.recommendation.MatrixFactorizationModel@1f14d4a在MLlib中的实现有如下的参数:

可以调整这些参数,不断优化结果,使均方差变小。比如:iterations越多,lambda较小,均方差会较小,推荐结果较优。上面的例子中调用了ALS.train(ratings,rank,numIterations,0.01),我们还可以设置其他参数,调用方式如下:

valmodel=newALS().setRank(params.rank).setIterations(params.numIterations).setLambda(params.lambda).setImplicitPrefs(params.implicitPrefs).setUserBlocks(params.numUserBlocks).setProductBlocks(params.numProductBlocks).run(training)4.利用模型进行预测从test训练集中获得只包含用户和商品的数据集:

scala>valtestUsersProducts=test.map{caseRating(user,product,rate)=>|(user,product)|}usersProducts:org.apache.spark.rdd.RDD[(Int,Int)]=MapPartitionsRDD[3868]atmapat:34使用训练好的推荐模型对用户商品进行预测评分,得到预测评分的数据集:

scala>valpredictions=|model.predict(testUsersProducts).map{caseRating(user,product,rate)|=>((user,product),rate)|}predictions:org.apache.spark.rdd.RDD[((Int,Int),Double)]=MapPartitionsRDD[3877]atmapat:45将真实评分数据集与预测评分数据集进行合并。这里,Join操作类似于SQL的innerjoin操作,返回结果是前面和后面集合中配对成功的,过滤掉关联不上的。

scala>valratesAndPreds=test.map{caseRating(user,product,rate)=>|((user,product),rate)|}.join(predictions)ratesAndPreds:org.apache.spark.rdd.RDD[((Int,Int),(Double,Double))]=MapPartitionsRDD[3881]atjoinat:48我们把结果输出,对比一下真实结果与预测结果:

scala>ratesAndPreds.foreach(println)((3,1),(1.0,-0.22756397347958202))((4,2),(5.0,4.388061223429636))((4,1),(1.0,-0.1847678805249373))比如,第一条结果记录((3,1),(1.0,-0.22756397347958202))中,(3,1)分别表示3号用户和1号商品,而1.0是实际的估计分值,-0.22756397347958202是经过推荐的预测分值。

然后计算均方差,这里的r1就是真实结果,r2就是预测结果:

scala>valMSE=ratesAndPreds.map{case((user,product),(r1,r2))=>|valerr=(r1-r2)|err*err|}.mean()MSE:Double=1.0950191019929887打印出均方差值:

scala>println("MeanSquaredError="+MSE)MeanSquaredError=1.0950191019929887我们可以看到打分的均方差值为1.09左右。由于本例的数据量很少,预测的结果和实际相比有一定的差距。上面的例子只是对测试集进行了评分,我们还可以进一步的通过调用model.recommendProducts给特定的用户推荐商品以及model.recommendUsers来给特定商品推荐潜在用户。

厦门大学软件工程系副教授,2009年毕业于中国人民大学计算机系获工学博士学位。主要研究方向是网络数据管理,车载网络,大数据分析和管理。

THE END
1.相关商品推荐:基于协同过滤的推荐算法协同过滤推荐算法是一种根据用户之间的相互作用(例如购买、评分、喜好等)来推荐商品的算法。它可以分为基于用户的协同过滤和基于物品的协同过滤两种类型。 适用场景 协同过滤算法适用于很多领域,比如电商平台、社交网络、新闻推荐、音乐电影推荐等。通过分析用户的行为,协同过滤算法可以为用户提供个性化的推荐产品或内容,提...https://www.jianshu.com/p/396b7c403ee4
2.协同过滤算法深入解析:构建智能推荐系统的核心技术在这种背景下,推荐系统应运而生,成为帮助用户过滤信息,找到自己感兴趣内容的有效工具。协同过滤算法作为推荐系统中的一种核心技术,广泛应用于电商、社交媒体、音乐、电影等多个领域,极大地改善了用户体验。本文将对协同过滤算法进行深入解析,让我们一起探讨这一神奇的技术。https://developer.aliyun.com/article/1267365
1.传统推荐算法——协同过滤ItemCF 是基于物品相似度进行推荐的协同过滤算法。通过计算共现矩阵中物品列向量的相似度得到物品之间的相似矩阵,再找到用户的历史正反馈物品的相似物品进行进一步排序和推荐,ItemCF 的具体步骤如下: 基于历史数据,构建以用户(假设用户总数为m mm)为行坐标,物品(物品总数为n nn)为列坐标的m × n m \times nm×...https://blog.csdn.net/weixin_55210809/article/details/143807593
2.人工智能(AI)对于电商行业的变革和意义12430558的技术博客协同过滤算法通过分析用户和商品之间的关系来推荐商品。它分为基于用户的协同过滤和基于物品的协同过滤: 基于用户的协同过滤:推荐与目标用户相似的用户所喜欢的商品。 基于物品的协同过滤:推荐与目标商品类似的商品。 Python实现协同过滤 from sklearn.metrics.pairwise import cosine_similarity ...https://blog.51cto.com/u_12440558/12600080
3.算法推荐算法协同过滤腾讯云开发者社区以用户为基础的协同推荐算法随着用户数量的增多,计算的时间就会变长,所以在2001年Sarwar提出了基于项目的协同过滤推荐算法(Item-based Collaborative Filtering Algorithms)。以项目为基础的协同过滤方法有一个基本的假设“能够引起用户兴趣的项目,必定与其之前评分高的项目相似”,通过计算项目之间的相似性来代替用户之间的相...https://www.cloud.tencent.com/developer/article/1170685