als方法recommendproductsforusers怎样协同过滤 als掉推过的数据

基于SparkMLlib平台和基于模型的协同过滤算法的电影推荐系统(二)代码实现
上接基于Spark MLlib平台和基于模型的协同过滤算法的电影推荐(一)
1. 设置不打印一堆INFO信息(减少打印量 保证Shell页面清晰干净)
sc.setLogLevel(&WARN&)
2. 导入相关recommendation包中相关类,加载数据,并解析到RDD【Rating】对象
①导入相关recommendation包,其中recommendation._的含义是导入recommendation包中全部类
scala& import org.apache.spark.mllib.recommendation._
import org.apache.spark.mllib.recommendation._
②加载数据;匹配模式;user product rating的类型是Int Int Double,需要转换;
scala& val data = sc.textFile(&/root/cccc.txt&).map(_.split(&,&) match {case Array (user,product,rating) =& Rating (user.toInt,product.toInt,rating.toDouble)})
data: org.apache.spark.rdd.RDD[org.apache.spark.mllib.recommendation.Rating] = MapPartitionsRDD[29] at map at :24
或者:val data = sc.textFile(&/root/cccc.txt&).map(_.split(&,&);Rating(f(0).toInt,f(1).toInt,f(2).toDouble) //这句运行有错。
/**如果不用模式匹配 还可以用if判断(本身case就是if的另一种形式)**/
【附加:.first可以查看数据的第一行;.count可以统计数据的行数
scala& data.first
res24: org.apache.spark.mllib.recommendation.Rating = Rating(1,1,5.0)
scala& data.count
res25: Long = 16
二:设置参数,建立ALS模型
利用自带的函数:
ALS.train(data,rank,iterations,lambda)
各参数意义:
ALS.train(数据,维度,迭代次数,正则化参数)
细释:k:维度(这里用rank表示),rank一般选在8到20之间
iterations:迭代次数
lambda:正则化参数,防止过拟合,【经验之谈】&一般是以3倍数往上增 0.01 0.03 0.1 0.3 1 3.........
/**建立ALS模型使用模型推荐的参数即可,设置rank为10,迭代次数为20,alpha为0.01**/
val rank = 10;val iterations=20 ;val lambda =0.01;
val model = ALS.train(data,rank,iterations,lambda)
val model = ALS.train(data,8,10,0.01)
执行后看到MatrixFactorizationModel!!
scala& val model = ALS.train(data,rank,iterations,alpha)
model: org.apache.spark.mllib.recommendation.MatrixFactorizationModel = org.apache.spark.mllib.recommendation.MatrixFactorizationModel@
那!!怎么去观察MatrixFactorizationModel这种黑盒子里的内部结构?(参考倒数第一个模块)
那!!Rating是几乘几的矩阵呢?(参考倒数第二个模块)
三:进行预测
四:把预测的结果和原始评分整合
val usersProducts = data.map{case Rating(user,product,rating) =&(user,product)}
val ratingAndPredictions = data.map{case Rating(user,product,rating) =& ((user,product),rating)}.join(model.predict(usersProducts).map{case Rating(user,product,rating)=&((user,product),rating)})
参考其结构帮助理解:
scala& usersProducts.collect
res27: Array[(Int, Int)] = Array((1,1), (1,2), (1,3), (1,4), (2,1), (2,2), (2,3), (2,4), (3,1), (3,2), (3,3), (3,4), (4,1), (4,2), (4,3), (4,4))
输出格式为((用户,项目),(实际评分,预测评分))
scala& ratingAndPredictions.collect
res28: Array[((Int, Int), (Double, Double))] = Array(((1,4),(1.0,0.9626)), ((3,1),(1.0,0.7607)), ((2,3),(5.0,4.205)), ((1,2),(1.0,0.9626)), ((2,1),(5.0,4.205)), ((4,4),(5.0,4.755)), ((1,1),(5.0,4.205)), ((4,2),(5.0,4.755)), ((2,2),(1.0,0.9626)), ((4,1),(1.0,0.7607)), ((2,4),(1.0,0.9626)), ((3,2),(5.0,4.755)), ((3,4),(5.0,4.755)), ((3,3),(1.0,0.7607)), ((4,3),(1.0,0.7607)), ((1,3),(5.0,4.205)))
今天课上思路(与昨天的相同):
scala& val usersProducts = data.map{case Rating(user,product,rating) =&(user,product)}
usersProducts: org.apache.spark.rdd.RDD[(Int, Int)] = MapPartitionsRDD[210] at map at :26
二元组的key也是一个元组
scala& model.predict(usersProducts).map(x =& ((x.user,x.product),x.rating))
res6: org.apache.spark.rdd.RDD[((Int, Int), Double)] = MapPartitionsRDD[219] at map at :31
键是二元组,值也是二元组
scala& model.predict(usersProducts).map(x =& ((x.user,x.product),x.rating)).join(data.map(x =& ((x.user,x.product),x.rating)))
res7: org.apache.spark.rdd.RDD[((Int, Int), (Double, Double))] = MapPartitionsRDD[232] at join at :31
把第一行取出来看一下,输出格式为((用户,项目),(预测评分,实际评分))
scala& model.predict(usersProducts).map(x =& ((x.user,x.product),x.rating)).join(data.map(x =& ((x.user,x.product),x.rating))).take(1)
res8: Array[((Int, Int), (Double, Double))] = Array(((1,1),(4.835,5.0)))
打印一个用户的实际值和预测值并做差,打印所有用户的实际值和预测值并做差
scala& res8(0)._2
res11: (Double, Double) = (4.835,5.0)
【倒数第二个模块】
Rating是几乘几的矩阵??
是4*4的矩阵(矩阵=用户*项目)
验证如下:
scala& data.map(x =& x.user)
res1: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[210] at map at :27
scala& data.map(x =& x.user).distinct.count
res3: Long = 4
scala& data.map(x =& x.product).distinct.count
res4: Long = 4
【倒数第一个模块】
怎么去观察MatrixFactorizationModel这种黑盒子里的内部结构?
scala& model.
asInstanceOf
isInstanceOf
productFeatures
recommendProducts
recommendProductsForUsers
recommendUsers
recommendUsersForProducts
userFeatures
打印用户特征第一行
scala& model.userFeatures take 1
res1: Array[(Int, Array[Double])] = Array((3,Array(-0.06049, -0.386, 0..1, -0..423)))
打印项目特征第一行
scala& model.productFeatures take 1
res2: Array[(Int, Array[Double])] = Array((3,Array(-2.7627, -1.2627, -0.8, 1.2607, -1.6875, -2.174, 0.8683)))
如果要知道用户3对项目3的评分:做内积
scala& val user3 = res1
user3: Array[(Int, Array[Double])] = Array((3,Array(-0.06049, -0.386, 0..1, -0..423)))
scala& val product3 = res2
product3: Array[(Int, Array[Double])] = Array((3,Array(-2.7627, -1.2627, -0.8, 1.2607, -1.6875, -2.174, 0.8683)))
现在就是简单的scala的处理了
//先把第一个值取出来;这个值里面是二元组,._2 取二元组里的第二个值
scala& val user3 = res1(0)._2
user3: Array[Double] = Array(-0.06049, -0.386, 0..1, -0..423)
scala& val product3 = res2(0)._2
product3: Array[Double] = Array(-2.7627, -1.2627, -0.8, 1.2607, -1.6875, -2.174, 0.8683)
通过zip把这两个二元组整合起来
scala& user3 zip product3 map(x =& x._1+x._2) sum
warning: there were 1 feature warning(s); re-run with -feature for details
res4: Double = -3.6827
???res12.rating查看: 11264|回复: 10
使用Spark MLlib给豆瓣用户推荐电影
主题帖子积分
本帖最后由 breaking 于
15:38 编辑
问题导读:
1.常用的推荐算法有哪些?2.推荐系统是什么样的流程?3.从这个推荐系统我们能学到什么?
推荐算法就是利用用户的一些行为,通过一些数学算法,推测出用户可能喜欢的东西。
随着电子商务规模的不断扩大,商品数量和种类不断增长,用户对于检索和推荐提出了更高的要求。由于不同用户在兴趣爱好、关注领域、个人经历等方面的不同,以满足不同用户的不同推荐需求为目的、不同人可以获得不同推荐为重要特征的个性化推荐系统应运而生。
推荐系统成为一个相对独立的研究方向一般被认为始自1994年明尼苏达大学GroupLens研究组推出的GroupLens系统。该系统有两大重要贡献:一是首次提出了基于协同过滤(Collaborative Filtering)来完成推荐任务的思想,二是为推荐问题建立了一个形式化的模型。基于该模型的协同过滤推荐引领了之后推荐系统在今后十几年的发展方向。目前,推荐算法已经已经被广泛集成到了很多商业应用系统中,比较著名的有Netflix在线视频推荐系统、Amazon网络购物商城等。实际上,大多数的电子商务平台尤其是网络购物平台,都不同程度地集成了推荐算法,如淘宝、京东商城等。Amazon发布的数据显示,亚马逊网络书城的推荐算法为亚马逊每年贡献近三十个百分点的创收。
常用的推荐算法基于人口统计学的推荐(Demographic-Based Recommendation):该方法所基于的基本假设是“一个用户有可能会喜欢与其相似的用户所喜欢的物品”。当我们需要对一个User进行个性化推荐时,利用User Profile计算其它用户与其之间的相似度,然后挑选出与其最相似的前K个用户,之后利用这些用户的购买和打分信息进行推荐。基于内容的推荐(Content-Based Recommendation):Content-Based方法所基于的基本假设是“一个用户可能会喜欢和他曾经喜欢过的物品相似的物品”。基于协同过滤的推荐(Collaborative Filtering-Based Recommendation)是指收集用户过去的行为以获得其对产品的显式或隐式信息,即根据用户对
物品或者信息的偏好,发现物品或者内容本身的相关性、或用户的相关性,然后再基于这些关联性进行推荐。基于协同过滤的推荐可以分基于用户的推荐(User-based Recommendation),基于物品的推荐(Item-based Recommendation),基于模型的推荐(Model-based Recommendation)等子类。
以上内容copy自参考文档1
ALS算法LS是alternating least squares的缩写 , 意为交替最小二乘法。该方法常用于基于矩阵分解的推荐系统中。例如:将用户(user)对商品(item)的评分矩阵分解为两个矩阵:一个是用户对商品隐含特征的偏好矩阵,另一个是商品所包含的隐含特征的矩阵。在这个矩阵分解的过程中,评分缺失项得到了填充,也就是说我们可以基于这个填充的评分来给用户最商品推荐了。
由于评分数据中有大量的缺失项,传统的矩阵分解SVD(奇异值分解)不方便处理这个问题,而ALS能够很好的解决这个问题。对于R(m×n)的矩阵,ALS旨在找到两个低维矩阵X(m×k)和矩阵Y(n×k),来近似逼近R(m×n),即:R~=XYR~=XY ,其中 ,X∈Rm×dX∈Rm×d,Y∈Rd×nY∈Rd×n,d 表示降维后的维度,一般 d&&r,r表示矩阵 R 的秩,r&&min(m,n)r&&min(m,n)。为了找到低维矩阵X,Y最大程度地逼近矩分矩阵R,最小化下面的平方误差损失函数。
L(X,Y)=∑u,i(rui−xTuyi)2L(X,Y)=∑u,i(rui−xuTyi)2
为防止过拟合给公式 (1) 加上正则项,公式改下为:L(X,Y)=∑u,i(rui−xTuyi)2+λ(|xu|2+ |yi|2)......(2)L(X,Y)=∑u,i(rui−xuTyi)2+λ(|xu|2+ |yi|2)......(2)
其中xu∈Rd,yi∈Rdxu∈Rd,yi∈Rd,1⩽uݕu⩽m,1⩽iݕi⩽n,λλ是正则项的系数。
MLlib 的实现算法中有以下一些参数:
用于并行化计算的分块个数 (-1为自动分配)
模型中隐藏因子的个数,也就是上面的r
iterations
迭代的次数,推荐值:10-20
惩罚函数的因数,是ALS的正则化参数,推荐值:0.01
implicitPrefs
决定了是用显性反馈ALS的版本还是用适用隐性反馈数据集的版本
是一个针对于隐性反馈 ALS 版本的参数,这个参数决定了偏好行为强度的基准
隐性反馈 vs 显性反馈
基于矩阵分解的协同过滤的标准方法一般将用户商品矩阵中的元素作为用户对商品的显性偏好。 在许多的现实生活中的很多场景中,我们常常只能接触到隐性的反馈(例如游览,点击,购买,喜欢,分享等等)在 MLlib 中所用到的处理这种数据的方法来源于文献: 。 本质上,这个方法将数据作为二元偏好值和偏好强度的一个结合,而不是对评分矩阵直接进行建模。因此,评价就不是与用户对商品的显性评分而是和所观察到的用户偏好强度关联了起来。然后,这个模型将尝试找到隐语义因子来预估一个用户对一个商品的偏好。以上的介绍带着浓重的学术气息,需要阅读更多的背景知识才能了解这些算法的奥秘。Spark MLlib为我们提供了很好的协同算法的封装。 当前MLlib支持基于模型的协同过滤算法,其中user和product对应上面的user和item,user和product之间有一些隐藏因子。MLlib使用来学习/得到这些潜在因子。下面我们就以实现一个豆瓣电影推荐系统为例看看如何使用Spark实现此类推荐系统。以此类推,你也可以尝试实现豆瓣图书,豆瓣音乐,京东电器商品推荐系统。
豆瓣数据集一般学习Spark MLlib ALS会使用数据集。这个数据集保存了用户对电影的评分。
但是这个数据集对于国内用户来说有点不接地气,事实上国内有一些网站可以提供这样的数据集,比如豆瓣,它的人气还是挺高的。
但是豆瓣并没有提供这样一个公开的数据集,所以我用抓取了一些数据做测试。
数据集分为两个文件:hot_movies.csv: 这个文件包含了热门电影的列表,一种166个热门电影。格式为 [size=0.85em]&movieID&,&评分&,&电影名&,如
[XML] 纯文本查看 复制代码.2,小王子
.3,垫底辣妹
.2,海绵宝宝
.4,突然变异
.7,烈日迷踪
.6,侦探:为了原点
user_movies.csv: 这个文件包含用户对热门电影的评价,格式为[size=0.85em]&userID&:&movieID&:&评分&
[XML] 纯文本查看 复制代码adamwzw,
baka_mono,
blueandgreen,
可以看到,用户名并不完全是整数类型的,但是MLlib ALS算法要求user,product都是整型的,所以我们在编程的时候需要处理一下。
有些用户只填写了评价,并没有打分,文件中将这样的数据记为-1。在ALS算法中,把它转换成3.0,也就是及格60分。虽然可能和用户的实际情况不相符,但是为了简化运算,我在这里做了简化处理。
用户的评分收集了大约100万条,实际用户大约22万。这个矩阵还是相当的稀疏。注意这个数据集完全基于豆瓣公开的网页,不涉及任何个人的隐私。
模型实现本系统使用Scala实现。
首先读入这两个文件,得到相应的弹性分布数据集RDD (第7行和第8行)。
[Scala] 纯文本查看 复制代码object DoubanRecommender {
def main(args: Array[String]): Unit = {
val sc = new SparkContext(new SparkConf().setAppName(&DoubanRecommender&))
//val base = &/opt/douban/&
val base = if (args.length & 0) args(0) else &/opt/douban/&
val rawUserMoviesData = sc.textFile(base + &user_movies.csv&)
val rawHotMoviesData = sc.textFile(base + &hot_movies.csv&)
//准备数据
preparation(rawUserMoviesData, rawHotMoviesData)
println(&准备完数据&)
model(sc, rawUserMoviesData, rawHotMoviesData)
第10行调用preparation方法,这个方法主要用来检查分析数据,得到数据集的一些基本的统计信息,还没有到协同算法那一步。
[Scala] 纯文本查看 复制代码def preparation( rawUserMoviesData: RDD[String],
rawHotMoviesData: RDD[String]) = {
val userIDStats = rawUserMoviesData.map(_.split(',')(0).trim).distinct().zipWithUniqueId().map(_._2.toDouble).stats()
val itemIDStats = rawUserMoviesData.map(_.split(',')(1).trim.toDouble).distinct().stats()
println(userIDStats)
println(itemIDStats)
val moviesAndName = buildMovies(rawHotMoviesData)
val (movieID, movieName) = moviesAndName.head
println(movieID + & -& & + movieName)
第5行和第6行打印RDD的statCounter的值,主要是最大值,最小值等。
第9行输出热门电影的第一个值。
输出结果如下:
[XML] 纯文本查看 复制代码(count: 223239, mean: 663, stdev: , max: 000, min: 0.000000)
(count: 165, mean: 394, stdev: 813, max: 000, min: 000)
6866928 -& 进击的巨人真人版:前篇
方法buildMovies读取rawHotMoviesData,因为rawHotMoviesData的每一行是一条类似.2,小王子的字符串,需要按照,分割,得到第一个值和第三个值:
[Scala] 纯文本查看 复制代码def buildMovies(rawHotMoviesData: RDD[String]): Map[Int, String] =
rawHotMoviesData.flatMap { line =&
val tokens = line.split(',')
if (tokens(0).isEmpty) {
Some((tokens(0).toInt, tokens(2)))
}.collectAsMap()
我们使用这个Map可以根据电影的ID得到电影实际的名字。下面就重点看看如何使用算法建立模型的:
[Scala] 纯文本查看 复制代码def model(sc: SparkContext,
rawUserMoviesData: RDD[String],
rawHotMoviesData: RDD[String]): Unit = {
val moviesAndName = buildMovies(rawHotMoviesData)
val bMoviesAndName = sc.broadcast(moviesAndName)
val data = buildRatings(rawUserMoviesData)
val userIdToInt: RDD[(String, Long)] =
data.map(_.userID).distinct().zipWithUniqueId()
val reverseUserIDMapping: RDD[(Long, String)] =
userIdToInt map { case (l, r) =& (r, l) }
val userIDMap: Map[String, Int] =
userIdToInt.collectAsMap().map { case (n, l) =& (n, l.toInt) }
val bUserIDMap = sc.broadcast(userIDMap)
val ratings: RDD[Rating] = data.map { r =& Rating(bUserIDMap.value.get(r.userID).get, r.movieID, r.rating)}.cache()
//使用协同过滤算法建模
//val model = ALS.trainImplicit(ratings, 10, 10, 0.01, 1.0)
val model = ALS.train(ratings, 50, 10, 0.0001)
ratings.unpersist()
println(&输出第一个userFeature&)
println(model.userFeatures.mapValues(_.mkString(&, &)).first())
for (userID &- Array(100,,000)) {
checkRecommenderResult(userID, rawUserMoviesData, bMoviesAndName, reverseUserIDMapping, model)
unpersist(model)
第4行到第12行是准备辅助数据,第13行准备好ALS算法所需的数据RDD[Rating]。
第16行设置一些参数训练数据。这些参数可以根据下一节的评估算法挑选一个较好的参数集合作为最终的模型参数。
第21行是挑选几个用户,查看这些用户看过的电影,以及这个模型推荐给他们的电影。
[Scala] 纯文本查看 复制代码def checkRecommenderResult(userID: Int, rawUserMoviesData: RDD[String], bMoviesAndName: Broadcast[Map[Int, String]], reverseUserIDMapping: RDD[(Long, String)], model: MatrixFactorizationModel): Unit = {
val userName = reverseUserIDMapping.lookup(userID).head
val recommendations = model.recommendProducts(userID, 5)
//给此用户的推荐的电影ID集合
val recommendedMovieIDs = recommendations.map(_.product).toSet
//得到用户点播的电影ID集合
val rawMoviesForUser = rawUserMoviesData.map(_.split(',')).
filter { case Array(user, _, _) =& user.trim == userName }
val existingUserMovieIDs = rawMoviesForUser.map { case Array(_, movieID, _) =& movieID.toInt }.
collect().toSet
println(&用户& + userName + &点播过的电影名&)
//点播的电影名
bMoviesAndName.value.filter { case (id, name) =& existingUserMovieIDs.contains(id) }.values.foreach(println)
println(&推荐给用户& + userName + &的电影名&)
//推荐的电影名
bMoviesAndName.value.filter { case (id, name) =& recommendedMovieIDs.contains(id) }.values.foreach(println)
比如用户yimiao曾经点评过以下的电影:
.jpg (12.65 KB, 下载次数: 9)
15:26 上传
.jpg (12.39 KB, 下载次数: 8)
15:26 上传
然后这个模型为他推荐
.jpg (13.98 KB, 下载次数: 8)
15:27 上传
.jpg (8.49 KB, 下载次数: 9)
15:27 上传
2303845.jpg (12.9 KB, 下载次数: 9)
15:27 上传
.jpg (9.17 KB, 下载次数: 8)
15:28 上传
.jpg (9.19 KB, 下载次数: 8)
15:28 上传
基本都属于喜剧动作,爱情类的,看起来还不错。
评价当然,我们不能凭着自己的感觉评价模型的好坏,尽管我们直觉告诉我们,这个结果看不错。我们需要量化的指标来评价模型的优劣。
我们可以通过计算均方差(Mean Squared Error, MSE)来衡量模型的好坏。数理统计中均方误差是指参数估计值与参数真值之差平方的期望值,记为MSE。MSE是衡量“平均误差”的一种较方便的方法,MSE可以评价数据的变化程度,MSE的值越小,说明预测模型描述实验数据具有更好的精确度。
我们可以调整rank,numIterations,lambda,alpha这些参数,不断优化结果,使均方差变小。比如:iterations越多,lambda较小,均方差会较小,推荐结果较优。
[Scala] 纯文本查看 复制代码def evaluate( sc: SparkContext,
rawUserMoviesData: RDD[String],
rawHotMoviesData: RDD[String]): Unit = {
val moviesAndName = buildMovies(rawHotMoviesData)
val bMoviesAndName = sc.broadcast(moviesAndName)
val data = buildRatings(rawUserMoviesData)
val userIdToInt: RDD[(String, Long)] =
data.map(_.userID).distinct().zipWithUniqueId()
val userIDMap: Map[String, Int] =
userIdToInt.collectAsMap().map { case (n, l) =& (n, l.toInt) }
val bUserIDMap = sc.broadcast(userIDMap)
val ratings: RDD[Rating] = data.map { r =&
Rating(bUserIDMap.value.get(r.userID).get, r.movieID, r.rating)
val numIterations = 10
&- Array(10,
lambda &- Array(1.0, 0.01,0.0001)) {
val model = ALS.train(ratings, rank, numIterations, lambda)
// Evaluate the model on rating data
val usersMovies = ratings.map { case Rating(user, movie, rate) =&
(user, movie)
val predictions =
model.predict(usersMovies).map { case Rating(user, movie, rate) =&
((user, movie), rate)
val ratesAndPreds = ratings.map { case Rating(user, movie, rate) =&
((user, movie), rate)
}.join(predictions)
val MSE = ratesAndPreds.map { case ((user, movie), (r1, r2)) =&
val err = (r1 - r2)
println(s&(rank:$rank, lambda: $lambda, Explicit ) Mean Squared Error = & + MSE)
&- Array(10,
lambda &- Array(1.0, 0.01,0.0001);
&- Array(1.0, 40.0)) {
val model = ALS.trainImplicit(ratings, rank, numIterations, lambda, alpha)
// Evaluate the model on rating data
val usersMovies = ratings.map { case Rating(user, movie, rate) =&
(user, movie)
val predictions =
model.predict(usersMovies).map { case Rating(user, movie, rate) =&
((user, movie), rate)
val ratesAndPreds = ratings.map { case Rating(user, movie, rate) =&
((user, movie), rate)
}.join(predictions)
val MSE = ratesAndPreds.map { case ((user, movie), (r1, r2)) =&
val err = (r1 - r2)
println(s&(rank:$rank, lambda: $lambda,alpha:$alpha ,implicit
) Mean Squared Error = & + MSE)
第16行到第35行评估显性反馈的参数的结果,第36行到第56行评估隐性反馈的参数的结果。
评估的结果如下:
[XML] 纯文本查看 复制代码(rank:10, lambda: 1.0, Explicit ) Mean Squared Error = 1.7315
(rank:10, lambda: 0.01, Explicit ) Mean Squared Error = 0.9523
(rank:10, lambda: 1.0E-4, Explicit ) Mean Squared Error = 0.36791
(rank:50, lambda: 1.0, Explicit ) Mean Squared Error = 1.233
(rank:50, lambda: 0.01, Explicit ) Mean Squared Error = 0.121003
(rank:50, lambda: 1.0E-4, Explicit ) Mean Squared Error = 0.3741545
(rank:10, lambda: 1.0,alpha:1.0 ,implicit
) Mean Squared Error = 10.916
(rank:10, lambda: 1.0,alpha:40.0 ,implicit
) Mean Squared Error = 7.52
(rank:10, lambda: 0.01,alpha:1.0 ,implicit
) Mean Squared Error = 9.543
(rank:10, lambda: 0.01,alpha:40.0 ,implicit
) Mean Squared Error = 7.938
(rank:10, lambda: 1.0E-4,alpha:1.0 ,implicit
) Mean Squared Error = 9.575
(rank:10, lambda: 1.0E-4,alpha:40.0 ,implicit
) Mean Squared Error = 7.43
(rank:50, lambda: 1.0,alpha:1.0 ,implicit
) Mean Squared Error = 9.038
(rank:50, lambda: 1.0,alpha:40.0 ,implicit
) Mean Squared Error = 7.378
(rank:50, lambda: 0.01,alpha:1.0 ,implicit
) Mean Squared Error = 7.575
(rank:50, lambda: 0.01,alpha:40.0 ,implicit
) Mean Squared Error = 7.226
(rank:50, lambda: 1.0E-4,alpha:1.0 ,implicit
) Mean Squared Error = 7.698
(rank:50, lambda: 1.0E-4,alpha:40.0 ,implicit
) Mean Squared Error = 7.7645
可以看到rank为50, lambda为0.0001的显性反馈时的MSE最小。我们就已这组参数作为我们的推荐模型。
模型应用既然我们已经得到了一个很好的推荐模型,下一步就是使用它为所有的用户生成推荐集合。
[Scala] 纯文本查看 复制代码def recommend(sc: SparkContext,
rawUserMoviesData: RDD[String],
rawHotMoviesData: RDD[String],
base:String): Unit = {
val moviesAndName = buildMovies(rawHotMoviesData)
val bMoviesAndName = sc.broadcast(moviesAndName)
val data = buildRatings(rawUserMoviesData)
val userIdToInt: RDD[(String, Long)] =
data.map(_.userID).distinct().zipWithUniqueId()
val reverseUserIDMapping: RDD[(Long, String)] =
userIdToInt map { case (l, r) =& (r, l) }
val userIDMap: Map[String, Int] =
userIdToInt.collectAsMap().map { case (n, l) =& (n, l.toInt) }
val bUserIDMap = sc.broadcast(userIDMap)
val bReverseUserIDMap = sc.broadcast(reverseUserIDMapping.collectAsMap())
val ratings: RDD[Rating] = data.map { r =&
Rating(bUserIDMap.value.get(r.userID).get, r.movieID, r.rating)
//使用协同过滤算法建模
//val model = ALS.trainImplicit(ratings, 10, 10, 0.01, 1.0)
val model = ALS.train(ratings, 50, 10, 0.0001)
ratings.unpersist()
//model.save(sc, base+&model&)
//val sameModel = MatrixFactorizationModel.load(sc, base + &model&)
val allRecommendations = model.recommendProductsForUsers(5) map {
case (userID, recommendations) =& {
var recommendationStr = &&
for (r &- recommendations) {
recommendationStr += r.product + &:& + bMoviesAndName.value.getOrElse(r.product, &&) + &,&
if (recommendationStr.endsWith(&,&))
recommendationStr = recommendationStr.substring(0,recommendationStr.length-1)
(bReverseUserIDMap.value.get(userID).get,recommendationStr)
allRecommendations.saveAsTextFile(base + &result.csv&)
unpersist(model)
这里将推荐结果写入到文件中,更实际的情况是把它写入到HDFS中,或者将这个RDD写入到关系型数据库中如Mysql, Postgresql,或者NoSQL数据库中,如MongoDB, cassandra等。 这样我们就可以提供接口为指定的用户提供推荐的电影。查看本例生成的推荐结果,下面是其中的一个片段,第一个字段是用户名,后面是五个推荐的电影(电影ID:电影名字)
[XML] 纯文本查看 复制代码(god8knows,:流浪者年代记,:斗地主,:王牌特工:特工学院,:猛龙特囧,:极道大战争)
(53129:瑞奇和闪电,:斗地主,3445457:无境之兽,3608742:冲出康普顿,:这时对那时错)
(856265:烈日迷踪,3608742:冲出康普顿,:橘色,:这时对那时错,:极道大战争)
(xrzsdan,:王牌特工:特工学院,:妈妈的朋友,:最后的女巫猎人,:极道大战争,:流浪者年代记)
(HoldonBoxer,:躲藏,:这时对那时错,:白河夜船,:橘色,3608742:冲出康普顿)
(2724:斯坦福监狱实验,4,:新宿天鹅,:斗地主,:长寿商会)
(blankscreen,:王牌特工:特工学院,:妈妈的朋友,0年代的爱情,:瑞奇和闪电,:烈日迷踪)
(linyiqing,3608742:冲出康普顿,:极道大战争,:橘色,0年代的爱情,:斗地主)
(89465:抢劫,:福尔摩斯先生,:卫生间的圣母像,:维多利亚,:酷毙了)
(405378:王牌特工:特工学院,:烈日迷踪,:流浪者年代记,:极道大战争,:军犬麦克斯)
(19385:长寿商会,:斗地主,:有客到,:对风说爱你,:旅程终点)
(fanshuren,:躲藏,:斗地主,:烈日迷踪,:如此美好,:橘色)
(sweetxyy,:斗地主,:极道大战争,3608742:冲出康普顿,:思悼,:猛龙特囧)
通过前面的介绍,我们可以了解如何使用Spark MLlib的ALS算法为22万豆瓣用户实现一个可用的推荐系统,如何加载数据集和输出数据结果,以及如何对模型进行有效的评估。
你可以使用本文的算法实现其它的推荐系统,如图书,文章,商品等。
原文链接:
主题帖子积分
中级会员, 积分 297, 距离下一级还需 703 积分
中级会员, 积分 297, 距离下一级还需 703 积分
不错,很好的案例。
主题帖子积分
高级会员, 积分 1333, 距离下一级还需 3667 积分
高级会员, 积分 1333, 距离下一级还需 3667 积分
mark一下,以留备用
主题帖子积分
高级会员, 积分 1980, 距离下一级还需 3020 积分
高级会员, 积分 1980, 距离下一级还需 3020 积分
很不错。。。。
主题帖子积分
注册会员, 积分 170, 距离下一级还需 30 积分
注册会员, 积分 170, 距离下一级还需 30 积分
阔以,不错的资料
主题帖子积分
高级会员, 积分 1154, 距离下一级还需 3846 积分
高级会员, 积分 1154, 距离下一级还需 3846 积分
赞个。。。
主题帖子积分
主题帖子积分
marchine leaning 是很好的一个方向,看来要准备好好学习一下了
主题帖子积分
新手上路, 积分 44, 距离下一级还需 6 积分
新手上路, 积分 44, 距离下一级还需 6 积分
很好,实战啊,谢谢!
主题帖子积分
注册会员, 积分 121, 距离下一级还需 79 积分
注册会员, 积分 121, 距离下一级还需 79 积分
这个例子很不错啊。
积极上进,爱好学习
经常帮助其他会员答疑
站长推荐 /4
云计算hadoop视频大全(新增 yarn、flume|storm、hadoop一套视频
等待验证会员请验证邮箱
新手获取积分方法
技术类问答,解决学习openstack,hadoop生态系统中遇到的问题
Powered by

我要回帖

更多关于 recommend 缩写 的文章

 

随机推荐