本文将使用 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之推荐引擎(一)---电影推荐的更多相关文章

  1. SparkML之推荐引擎(二)---推荐模型评估

    本文内容和代码是接着上篇文章来写的,推荐先看一下哈~ 我们上一篇文章是写了电影推荐的实现,但是推荐内容是否合理呢,这就需要我们对模型进行评估 针对推荐模型,这里根据 均方差 和 K值平均准确率 来对模 ...

  2. [转] 基于 Apache Mahout 构建社会化推荐引擎

    来源:http://www.ibm.com/developerworks/cn/java/j-lo-mahout/index.html 推荐引擎简介 推荐引擎利用特殊的信息过滤(IF,Informat ...

  3. 基于 Apache Mahout 构建社会化推荐引擎

    基于 Apache Mahout 构建社会化推荐引擎 http://www.ibm.com/developerworks/cn/views/java/libraryview.jsp 推荐引擎利用特殊的 ...

  4. 基于Spark ALS构建商品推荐引擎

    基于Spark ALS构建商品推荐引擎   一般来讲,推荐引擎试图对用户与某类物品之间的联系建模,其想法是预测人们可能喜好的物品并通过探索物品之间的联系来辅助这个过程,让用户能更快速.更准确的获得所需 ...

  5. 简易推荐引擎的python实现

    代码地址如下:http://www.demodashi.com/demo/12913.html 主要思路 使用协同过滤的思路,从当前指定的用户过去的行为和其他用户的过去行为的相似度进行相似度评分,然后 ...

  6. 机器学习 101 Mahout 简介 建立一个推荐引擎 使用 Mahout 实现集群 使用 Mahout 实现内容分类 结束语 下载资源

      机器学习 101 Mahout 简介 建立一个推荐引擎 使用 Mahout 实现集群 使用 Mahout 实现内容分类 结束语 下载资源 相关主题   在信息时代,公司和个人的成功越来越依赖于迅速 ...

  7. SparkMLlib—协同过滤推荐算法,电影推荐系统,物品喜好推荐

    SparkMLlib-协同过滤推荐算法,电影推荐系统,物品喜好推荐 一.协同过滤 1.1 显示vs隐式反馈 1.2 实例介绍 1.2.1 数据说明 评分数据说明(ratings.data) 用户信息( ...

  8. 从源代码剖析Mahout推荐引擎

    转载自:http://blog.fens.me/mahout-recommend-engine/ Hadoop家族系列文章,主要介绍Hadoop家族产品,常用的项目包括Hadoop, Hive, Pi ...

  9. 基于Azure构建PredictionIO和Spark的推荐引擎服务

    基于Azure构建PredictionIO和Spark的推荐引擎服务 1. 在Azure构建Ubuntu 16.04虚拟机 假设前提条件您已有 Azure 帐号,登陆 Azure https://po ...

随机推荐

  1. Android Studio系列-签名打包

    本篇博客纪录使用Android Studio对项目进行签名打包,跟Eclipse大同小异,读者朋友注意其中到差别. 第一步 创建签名文件 第二步 填写签名参数 第三步 选择构建类型 第四步 查看生成第 ...

  2. linux 修改图片的尺寸

    # convert -sample 50.png .png #把512*512的图片修改为500*500的图片 # which convert /usr/bin/convert # rpm -qf / ...

  3. 【转】Python3使用Django2.x的settings文件详解

    # -*- coding:utf8 -*- import os # 项目路径 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__ ...

  4. 在Linux添加定时任务删除5天前的日志文件

    利用shell脚本自动清理,脚本如下 1.删除文件命令: find 对应目录 -mtime +天数 -name "文件名" -exec rm -rf {} \; 实例命令: fin ...

  5. 删除maven仓库中的LastUpdated文件

    转自:http://www.oschina.net/code/snippet_151849_49131 @echo off rem create by sunhao(sunhao.java@gmail ...

  6. Mysql 5.7 安装 解压缩版 忘记密码

    [参考]Mysql 命令大全 [参考]MySQL 5.7.19 忘记密码 重置密码 配置文件my.ini示例 服务启动后停止 log配置 [参考]MySQL5.7.19 服务挂掉 自动关闭 mysql ...

  7. DOTween-Ease缓动函数

    Ease.InQuad 不知道Quad代表什么意思  Ease.InQuart 有1/4的时间是没有缓动.  Ease.InQuint, 是1/5时间没有缓动.  Ease.InExpo 一直很平缓, ...

  8. CreateWindowEx failed (当前程序已使用了 Window 管理器对象的系统允许的所有句柄。)

    我在QT图形场景视图中通过QGraphicsProxyWidget添加代理Widget(实现添加基本的QT Widget,如按钮.复选框.日期时间控件等),当数量超过3500左右的时候,QT应用程序直 ...

  9. CSS外边距属性,深入理解margin

    margin See the Pen margin by wmui (@wmui) on CodePen. 该属性用于设置元素的外边距,外边距是透明的,默认值0.这是一个简写属性,属性值最多为4个,例 ...

  10. [原][openstack-pike][controller node][issue-2][glance] Could not parse rfc1738 URL from string 'mysql+pymysql=http://glance:glance@controller/glance'

    问题点 在手动上传镜像的时候:出现错误 Could not parse rfc1738 URL from string 'mysql+pymysql=http://glance:glance@cont ...