博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Machine Learning With Spark学习笔记(在10万电影数据上训练、使用推荐模型)
阅读量:5885 次
发布时间:2019-06-19

本文共 2637 字,大约阅读时间需要 8 分钟。

我们如今開始训练模型,还输入參数例如以下:

rank:ALS中因子的个数。通常来说越大越好,可是对内存占用率有直接影响,通常rank在10到200之间。

iterations:迭代次数,每次迭代都会降低ALS的重构误差。在几次迭代之后,ALS模型都会收敛得到一个不错的结果,所以大多情况下不须要太多的迭代(一般是10次)。
lambda:模型的正则化參数,控制着避免过度拟合。值越大,越正则化。

我们将使用50个因子,8次迭代,正则化參数0.01来训练模型:

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

说明:原书中使用的迭代參数是10。可是在本机上使用10次迭代參数会造成堆内存溢出,经过调试将它改成8。

它会返回一个MatrixFactorizationModel对象,包括了user和item的RDD,以(id。factor)对的形式,它们是userFeatures和productFeatures。

println(model.userFeatures.count)println(model.productFeatures.count)

这里写图片描写叙述

这里写图片描写叙述
MatrixFactorizationModel类有有一个很方便的方法predict,会针对某个用户和物品的组合预測分数。

val predictedRating = model.predict(789, 123)

这里选择的用户id为789。计算他对电影123可能的评分。结果例如以下:

这里写图片描写叙述
你得到的结果可能跟我这的不一样,由于ALS模型是随机初始化的。

predict方法会创建一个RDD(user,item),为某个用户进行个性化推荐,MatrixFactorizationModel提供了一个很方便的方法——recommendProducts。输入參数:user,num。user是用户id,num是将要推荐的个数。

如今为用户789推荐10部电影:

val userID = 789val K = 10val topKRecs = model.recommendProducts(userID, K);println(topKRecs.mkString("\n"))

结果例如以下:

这里写图片描写叙述
以下取到电影的名字:

val movies = sc.textFile("F:\\ScalaWorkSpace\\data\\ml-100k\\u.item")val titles = movies.map(line => line.split("\\|").take(2)).map(array => (array(0).toInt, array(1))).collectAsMap()println(titles(123))

结果例如以下:

这里写图片描写叙述
我们再来看看用户789对多少部电影进行了评分:

val moviesForUser = ratings.keyBy(_.user).lookup(789)println(moviesForUser.size)

结果例如以下:

这里写图片描写叙述
能够看到用户789对33部电影进行了评分。

接下来我们将要取得前10个评分最高的电影,使用Rating对象的rating字段。而且得到依据电影的id得打电影的名字:

moviesForUser.sortBy(-_.rating).take(10).map(rating => (titles(rating.product), rating.rating)).foreach(println)

结果例如以下:

这里写图片描写叙述
然后我们再来看看为这个用户推荐的是哪10部电影:

topKRecs.map(rating => (titles(rating.product), rating.rating)).foreach(println)

结果例如以下:

这里写图片描写叙述
找到类似电影

通过计算两个向量的夹角的余弦值来推断类似度,假设是1,那么说明全然一样,假设是0那么说明没有相关性,假设是-1则表明这两者是全然相反的。首先编写计算两个向量夹角余弦值的方法:

def cosineSimilarity(vec1: DoubleMatrix, vec2: DoubleMatrix): Double = {    vec1.dot(vec2) / (vec1.norm2() * vec2.norm2())  }

如今来检測下是否正确,选一个电影。看看它与它本身类似度是否是1:

val itemId = 567val itemFactor = model.productFeatures.lookup(itemId).headval itemVector = new DoubleMatrix(itemFactor)println(cosineSimilarity(itemVector, itemVector))

这里写图片描写叙述

能够看到得出的结果是1!

接下来我们计算其它电影与它的类似度:

val sims = model.productFeatures.map{ case (id, factor) =>       val factorVector = new DoubleMatrix(factor)      val sim = cosineSimilarity(factorVector, itemVector)      (id,sim)    }

然后取得前10个:

val sortedSims = sims.top(K)(Ordering.by[(Int, Double), Double]{      case(id, similarity) => similarity    })println(sortedSims.take(10).mkString("\n"))

结果例如以下:

这里写图片描写叙述
如今来看看电影名字:

val sortedSims2 = sims.top(K+1)(Ordering.by[(Int, Double), Double]{      case(id, similarity) => similarity    })println(sortedSims2.slice(1, 11).map{
case (id, sim) => (titles(id), sim)}.mkString("\n"))

结果例如以下:

这里写图片描写叙述

你可能感兴趣的文章
查看光纤卡的WWN号
查看>>
【百度地图API】如何在地图上添加标注?——另有:坐标拾取工具+打车费用接口介绍...
查看>>
机器学习之梯度下降法
查看>>
笔记本外接2-3个屏幕
查看>>
SDL2.0教程翻译·目录
查看>>
嵌入式 Linux进程含义知多少
查看>>
类加载器的双亲委派及打破双亲委派
查看>>
Docker入门教程(二)命令
查看>>
python中多线程与非线程的执行性能对比
查看>>
R3 Corda 1.0即将问世,创想本地硬件和云端存储混合的未来
查看>>
安全市场风云变幻 Sophos发力移动和云
查看>>
Android应用UI设计流程
查看>>
如何在 Swift 3 中用 SpriteKit 框架编写游戏 (Part 2)
查看>>
一个跨线程创建窗口的死锁案例
查看>>
学会观察,洞察消费者需求GP
查看>>
阿里云ECS的1M带宽能干嘛?
查看>>
在物联网时代如何打造安全的数据中心?
查看>>
评论:企业存储已经成为一潭死水
查看>>
安全威胁正推动对安全服务和事件响应支持的需求
查看>>
重新定义云数据库,中国数据库诞生40年即将迎来第三次变革
查看>>