SparkML之推荐引擎(一)---电影推荐
本文将使用 SparkML 来构建推荐引擎。
推荐引擎算法大致分为 基于内容的过滤、协同过滤、矩阵分解,本文将使用基于属于矩阵分解的 最小二乘法 算法来构建推荐引擎。
对于推荐引擎模块这里将分为两篇文章,第一篇文章主要是以实现推荐功能为主,第二篇文章主要是对模型进行评估
文章将按照以下章节来进行书写: 需求分析、获取数据、提取特征、训练模型、使用模型(推荐)
一、需求分析
假设我们是 MovieStream 团队,专门为用户提供在线电影和电视节目的内容服务。
现在我们有个需求::给用户推荐电影!
就这么简单,哈哈~
二、获取数据
可从 http://files.grouplens.org/datasets/movielens/ml-100k.zip 下载模拟的数据集。
对于推荐模型,主要用到了里面的三个文件:
u.user(用户属性文件)
u.item(电影元数据)
u.data(用户对电影的评级)
数据文件说明:
1、u.user(用户属性文件)
字段及格式说明:user id | age | gender | occupation(职业) | zip code
样例:
||M|technician|
||F|other|
||M|writer|
||M|technician|
||F|other|
2、u.item(电影信息数据)
字段及格式说明:
movie id | movie title | release date | video release date | IMDb URL | unknown | Action | Adventure | Animation | Children’s | Comedy | Crime | Documentary | Drama | Fantasy | Film-Noir | Horror | Musical | Mystery | Romance | Sci-Fi | Thriller | War | Western |
样例:
|Toy Story ()|-Jan-||http://us.imdb.com/M/title-exact?Toy%20Story%20(1995)|0|0|0|1|1|1|0|0|0|0|0|0|0|0|0|0|0|0|0
|GoldenEye ()|-Jan-||http://us.imdb.com/M/title-exact?GoldenEye%20(1995)|0|1|1|0|0|0|0|0|0|0|0|0|0|0|0|0|1|0|0
|Four Rooms ()|-Jan-||http://us.imdb.com/M/title-exact?Four%20Rooms%20(1995)|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|1|0|0
|Get Shorty ()|-Jan-||http://us.imdb.com/M/title-exact?Get%20Shorty%20(1995)|0|1|0|0|0|1|0|0|1|0|0|0|0|0|0|0|0|0|0
|Copycat ()|-Jan-||http://us.imdb.com/M/title-exact?Copycat%20(1995)|0|0|0|0|0|0|1|0|1|0|0|0|0|0|0|0|1|0|0
3、u.data(用户对电影的评分)
字段及格式说明:user_id item_id rating timestamp(注意:分隔符为 “\t”)
样例:
三、提取特征
/* 生成用户评分数据的RDD,格式为:用户 电影 评分 时间戳 */
val rawData: RDD[String] = sc.textFile("file:///E:/spark/ml-100k/u.data")
/* 去掉时间戳的字段,格式变为:用户 电影 评分; rawRating类型为Array */
val rawRatings = rawData.map(_.split("\\t").take())
/* 格式变为:Rating(用户 电影 评分),作为后续训练模型的参数 */
val ratings = rawRatings.map{case Array(user, movie, rating) =>{
//封装成Rating
Rating(user.toInt, movie.toInt, rating.toDouble)
}}
四、训练模型
最小二乘法的模型需要以下三个参数:
1、rank
对应ALS模型中的因子个数,也就是在低阶近似矩阵中的隐含特征个数。因子个数一般越多越好。但它也会接影响模型训练和保存时所需的内存开销,尤其是在用户和物品很多的时候。因此实践中该参数常作为训练效果与系统开销之间的调节参数。通常,其合理取值为10到200。
可以简单理解为:模型因子的列的数量
2、iterations
对应运行时的迭代次数。ALS能确保每次迭代都能降低评级矩阵的重建误差,但一般经少数次迭代后ALS模型便已能收敛为一个比较合理的好模型。这样,大部分情况下都没必要迭代太多次(10次左右一般就挺好)。
3、lambda
该参数控制模型的正则化过程,从而控制模型的过拟合情况。其值越高,正则化越严厉。该参数的赋值与实际数据的大小、特征和稀疏程度有关。和其他的机器学习模型一样,正则参数应该通过用非样本的测试数据进行交叉验证来调整。
这里将使用的 rank、iterations 和 lambda 参数的值分别为50、10和0.01
代码如下:
import org.apache.spark.mllib.recommendation.{Rating, ALS}
//这就得到了推荐的模型
val model = ALS.train(ratings, , , 0.01)
五、使用模型(推荐)
1、用户推荐
为 id 为 789 的用户推荐10个电影
//为指定的用户推荐 N 个商品
val userID =
val K =
val topKRecs: Array[Rating] = model.recommendProducts(userID, K)
println(topKRecs.mkString("\n"))
输出为:
Rating(,,5.931851273771102)
Rating(,,5.582301095666215)
Rating(,,5.516272981542168)
Rating(,,5.458065302395629)
Rating(,,5.449949837103569)
Rating(,,5.348768847643657)
Rating(,,5.30832117499004)
Rating(,,5.278933936827717)
Rating(,,5.250959077906759)
Rating(,,5.169863417126231)
2、物品推荐(作为了解)
物品推荐可以理解为:给定一个物品,推荐 K 个与该物品相似的物品
我们上面得到的推荐模型中没有提供物品推荐的方法,但是谋问题,我们自己可以根据余弦相似度来实现。
科普:余弦相似度是两个两个向量在n维空间里两者夹角的度数。它的值是两个向量的点积与各向量范数(或长度)的乘积的商。该值的取值范围是 -1 到 1 之间,1表示完全相似,0表示不相关,-1表示两者不仅不相关而且还完全不同。
ok,我们来写一个计算余弦相似度的函数,在写之前需要引入 jblas 线性代数库,该库中有一个 DoubleMatrix 类对象,向量和矩阵都用该对象来表示
import org.jblas.DoubleMatrix
/**
* 用于商品推荐
* 通过传入两个向量,返回这两个向量之间的余弦相似度
* @param vec1
* @param vec2
* @return
*/
def cosineSimilarity(vec1: DoubleMatrix, vec2: DoubleMatrix): Double = {
vec1.dot(vec2) / (vec1.norm2() * vec2.norm2())
}
开始根据物品推荐:
/**
* 基于商品进行推荐
*/
/*通过商品ID获得与该商品相似的商品*/
val itemId =
val itemFactor: Array[Double] = model.productFeatures.lookup(itemId).head
val itemVector: DoubleMatrix = new DoubleMatrix(itemFactor)
//获得每个商品与给出的商品的余弦相似度
val sims = model.productFeatures.map{case (id, factor) => {
val factorVector = new DoubleMatrix(factor)
val sim = cosineSimilarity(factorVector, itemVector)
(id, sim)
}}
//打印出前10的商品
val topItem: Array[(Int, Double)] = sims.sortBy(-_._2).take()
println("与567商品相似的商品:\n" + topItem.mkString("\n") + "\n")
输出为:
与567商品相似的商品:
(,1.0)
(,0.6932331537649621)
(,0.6898690594544726)
(,0.6897964975027041)
(,0.6891221044611473)
(,0.6864214133620066)
(,0.6812075443259535)
(,0.6754663844488256)
(,0.6702643811753909)
(,0.6594872765176396)
很正常,排名第一的最相似物品就是我们给定的物品。但是注意,因为模型的初始化是随机的,所以后面的商品可能跟你的不一样,这很正常哈~
SparkML之推荐引擎(一)---电影推荐的更多相关文章
- SparkML之推荐引擎(二)---推荐模型评估
本文内容和代码是接着上篇文章来写的,推荐先看一下哈~ 我们上一篇文章是写了电影推荐的实现,但是推荐内容是否合理呢,这就需要我们对模型进行评估 针对推荐模型,这里根据 均方差 和 K值平均准确率 来对模 ...
- [转] 基于 Apache Mahout 构建社会化推荐引擎
来源:http://www.ibm.com/developerworks/cn/java/j-lo-mahout/index.html 推荐引擎简介 推荐引擎利用特殊的信息过滤(IF,Informat ...
- 基于 Apache Mahout 构建社会化推荐引擎
基于 Apache Mahout 构建社会化推荐引擎 http://www.ibm.com/developerworks/cn/views/java/libraryview.jsp 推荐引擎利用特殊的 ...
- 基于Spark ALS构建商品推荐引擎
基于Spark ALS构建商品推荐引擎 一般来讲,推荐引擎试图对用户与某类物品之间的联系建模,其想法是预测人们可能喜好的物品并通过探索物品之间的联系来辅助这个过程,让用户能更快速.更准确的获得所需 ...
- 简易推荐引擎的python实现
代码地址如下:http://www.demodashi.com/demo/12913.html 主要思路 使用协同过滤的思路,从当前指定的用户过去的行为和其他用户的过去行为的相似度进行相似度评分,然后 ...
- 机器学习 101 Mahout 简介 建立一个推荐引擎 使用 Mahout 实现集群 使用 Mahout 实现内容分类 结束语 下载资源
机器学习 101 Mahout 简介 建立一个推荐引擎 使用 Mahout 实现集群 使用 Mahout 实现内容分类 结束语 下载资源 相关主题 在信息时代,公司和个人的成功越来越依赖于迅速 ...
- SparkMLlib—协同过滤推荐算法,电影推荐系统,物品喜好推荐
SparkMLlib-协同过滤推荐算法,电影推荐系统,物品喜好推荐 一.协同过滤 1.1 显示vs隐式反馈 1.2 实例介绍 1.2.1 数据说明 评分数据说明(ratings.data) 用户信息( ...
- 从源代码剖析Mahout推荐引擎
转载自:http://blog.fens.me/mahout-recommend-engine/ Hadoop家族系列文章,主要介绍Hadoop家族产品,常用的项目包括Hadoop, Hive, Pi ...
- 基于Azure构建PredictionIO和Spark的推荐引擎服务
基于Azure构建PredictionIO和Spark的推荐引擎服务 1. 在Azure构建Ubuntu 16.04虚拟机 假设前提条件您已有 Azure 帐号,登陆 Azure https://po ...
随机推荐
- Software Engineer Title Ladder
http://changelog.ca/log/2013/08/09/software_engineer_title_ladder Within the software engineering pr ...
- centos 7 下的 service部署
在centos 7下部署service一般涉及到jar包部署, service脚本. 数据存贮路径, log存贮路径 jar包部署 /usr/local/app/app1/app1.jar servi ...
- nginx转发成功报400 bad request,服务端未收到请求
nginx转发成功报400 bad request,服务端未收到请求 解决办法: upstream后面不要跟下划线 例如: upstream auth_service{ server 30.4.164 ...
- R语言:recommenderlab包的总结与应用案例
R语言:recommenderlab包的总结与应用案例 1. 推荐系统:recommenderlab包整体思路 recommenderlab包提供了一个可以用评分数据和0-1数据来发展和测试推荐算 ...
- .NET Core 2.1中的HttpClientFactory最佳实践
ASP.NET Core 2.1中出现一个新的HttpClientFactory功能, 它有助于解决开发人员在使用HttpClient实例从其应用程序发出外部Web请求时可能遇到的一些常见问题. 介绍 ...
- JDK 自带的观察者模式源码分析以及和自定义实现的取舍
前言 总的结论就是:不推荐使用JDK自带的观察者API,而是自定义实现,但是可以借鉴其好的思想. java.util.Observer 接口源码分析 该接口十分简单,是各个观察者需要实现的接口 pac ...
- SAP Brazil J1BTAX 为税收例外创建税收组(翻译)
很多人对如何维持巴西的税收仍有疑问.前段时间,一家有几个税务问题的公司联系我帮助他们,我发现多年来,由于他们的税务计算系统缺少配置,他们正在进行手动调整. 维持税收的第一条规则是: TAXBRJ = ...
- linux中,当执行rpm -e删除一个软件包时,都做了些什么事
问题描述: 今天在通过rpm进行删除软件包时,出现了问题,就引发了我对于rpm包执行删除动作时的一些行为做了思考,之前找了很多的文章,后来想如果有debug日志信息,那么不就都清楚了吗 通过打印rpm ...
- redis主从同步配置
主服务器无需操作,从服务器 SLAVEOF 主服务器IP 端口 即可. 断开主从,执行 SLAVEOF NO ONE 即可. 同事和我在内网配置了连内网测试的服务器可以执行,但是连对方的不行,开始以为 ...
- python2与python3中除法的区别
python2中的除法 >>>1/2 0 即一个整数(无小数部分的数)被另外一个整数除,计算结果的小数部分被截除了,只留下了整数部分 有时候,这个功能比较有用,譬如在做一些需要取位数 ...