在完成基于大数据平台的图书馆推荐系统后,最近把学习的中心放在机器学习上面。在接下来的几个月中,希望自己能弄明白常见机器学习算法的原理,并且能在spark平台上进行实践。

在我的机器学习学习和实践之路的一个本书是《Spark机器学习》,这本书虽然比较旧,但是写的还是比较好。书里讲了各种常见的机器学习算法,并且在spark平台上进行了实战。在学习到此书第四章--构建基于spark的推荐系统引擎时觉得ALS算法在待分析数据具备用户对物品的打分时是一个很好用的算法,所以做记录如下。

推荐系统的产生主要是因为在公司的一些日常业务需求中需要通过用户的一些购买、借阅、点评等记录来准确预测用户下一阶段的类消费倾向以产生更大的经济效益等。在进入大数据时代的今天,数据量巨大,对于企业而言如何构建一个高效的推荐系统来对用户进行个性化一直是一个在研究和改进的问题。推荐系统的系统的核心在于推荐算法,常见的推荐算法有见链接--推荐算法综述,华科大一硕士论文。

ALS中文名作交替最小二乘法,在机器学习中,ALS特指使用最小二乘法求解的一个协同过滤算法,是协同过滤中的一种。ALS算法是2008年以来,用的比较多的协同过滤算法。它已经集成到Spark的Mllib库中,使用起来比较方便。从协同过滤的分类来说,ALS算法属于User-Item CF,也叫做混合CF,因为它同时考虑了User和Item两个方面,即即可基于用户进行推荐又可基于物品进行推荐。

一般而言用户只会购买物品集中的极少数部分产品,并对其进行打分。考虑下面这样一个包含用户的打分矩阵(列为用户u1-u6,行为物品I1-I8),我们可以看到这个用户的评分矩阵是十分稀疏的,有很多用户的购买的记录是空的,而且在现实业务中,用户的评分矩阵会更加的稀疏。如何通过这样一个稀疏矩阵,对用户进行协同推荐用户可能很喜欢的物品对于推荐系统而言是一种很大的考验。

用户评分矩阵
  I1 I2 I3 I4 I5 I6 I7 I8
u1         5   2  
u2   4   3       1
u3     1     5    
u4 7     2        
u5   7       1   1
u6     5   4   2  

在spark MLlib 机器学习库中目前推荐模型只包含基于矩阵分解(matrix factorization)的实现。具体的分解思路,找出两个低维的矩阵,使得它们的乘积是原始矩阵。因此这也是一种降维技术。假设我们的用户和物品分别是U和I,那对应的“用户-物品”矩阵的维度为U×I,类似图一所示:

图一

而言找到和“用户-物品“矩阵近似的k维(低阶)矩阵,最终还是要求出如下两个矩阵:一个用于表示用户U×k维矩阵,以及一个表征物品的I×k维矩阵。这两个矩阵也称为因子矩阵,他们的矩阵乘积便是原始评级数据的一个近似值。值得注意的是,原始评级矩阵通常很稀疏,但因子矩阵却是稠密的,如图二所示:

图二

ALS是求解矩阵分解问题的一种最优化方法,它功能强大,效果理想而且被证明相对容易实现。这使得它很适合如Spark这样的平台。

ALS的实现原理是迭代式求解一系列最小二乘回归问题。在每次迭代时,固定用户因子矩阵或者是物品因子矩阵中的一个,然后用固定的这个矩阵以及评级数据来更新另一个矩阵。之后,被更新的矩阵被固定住,再更新另外一个矩阵。如此迭代,知道模型收敛(或者是迭代了预设好的次数)。

书中的利用ALS模式实现推荐的代码实例及注释

// 加载观众影评数据集(观众ID,影片ID,评分)
val rawData = sc.textFile("dataSet/MLDataSet/u.data")
rawData.first()
val rawRating = rawData.map(_.split("\t").take(3))import  org.apache.spark.mllib.recommendation.ALSimport  org.apache.spark.mllib.recommendation.Rating
// 将rawRating由数组类型转换为rating(user,movie,rating)类型
//Rating(user,product,rating)
val rating = rawRating.map{case Array(user,movie,rating)=>Rating(user.toInt,movie.toInt,rating.toDouble)}
//训练模型,rank,iterations,lambda参数值分分别为50,10,0.1.
val model = ALS.train(rating,50,10,0.01)
// 基于用户的推荐
//预测出用户789对123电影的评分
val productRating = model.predict(789,123)
// 返回用户789的前10推荐电影
val userId = 789
val K = 10
val topKRecs = model.recommendProducts(userId,K)
print(topKRecs.mkString("\n"))
// 加载电影数据集(编号,电影名(上映年)....)
val movies = sc.textFile("dataSet/MLDataSet/u.item")
//只取(编号,电影名(上映年)),生成的是一个key->value
val titles = movies.map(line=>line.split("\\|").take(2)).map(array=>(array(0).toInt,array(1))).collectAsMap()
titles(123)
//查看用户789点评过的所有电影
val moviesForUser = rating.keyBy(_.user).lookup(789)
println(moviesForUser.size)
//查看观众点评数据集中评分最高的前10影片并电影编号相应转换成电影名
moviesForUser.sortBy(-_.rating).take(10).map(rating=>(titles(rating.product),rating.rating)).foreach(println)
//返回用户789的前10推荐电影并电影编号相应转换成电影名
topKRecs.map(rating=>(titles(rating.product),rating.rating)).foreach(println)moviesForUser.sortBy(-_.rating).take(10).map(rating=>(titles(rating.product),rating.rating)).foreach(println)//物品推荐
//导入jblas包创建向量
import org.jblas.DoubleMatrix
val aMatrix = new DoubleMatrix(Array(1.0,2.0,3.0))
//定义计算输入量为向量的余弦形式度公式
def consineSimilarity(vec1:DoubleMatrix,vec2:DoubleMatrix):Double={vec1.dot(vec2)/(vec1.norm2()*vec2.norm2())
}val itemId = 567
val itemFactor=model.productFeatures.lookup(itemId).head
val itemVector = new DoubleMatrix(itemFactor)
consineSimilarity(itemVector,itemVector)
//计算各个物品的相似度
val sims = model.productFeatures.map{case(id,factor)=>val factorVector=new DoubleMatrix(factor)val sim = consineSimilarity(factorVector,itemVector)(id,sim)}
val K = 10
//找到相似度排名前10的
val sortedSims = sims.top(K)(Ordering.by[(Int,Double),Double]{case(id,similarity)=>similarity})
println(sortedSims.take(10).mkString("\n"))println(titles(itemId))val sortedSims2 = sims.top(K+1)(Ordering.by[(Int,Double),Double]{case(id,similarary)=>similarary})
sortedSims2.slice(1,11).map{case (id,sim)=>(titles(id),sim)}.mkString("\n")
//取出user和product
val temp = rating.map{case Rating(user,product,rate)=>(user,product)}//推荐结果效果的评定
//MSE均方差
//对于某一特定用户
val actualRating = moviesForUser.take(1)(0)
val predictedRating = model.predict(789,actualRating.product)
val squaredError = math.pow(actualRating.rating-predictedRating,2.0)
//对于全部用户
val usersProducts = rating.map{case Rating(user,product,rating)=>(user,product)}
val predictions = model.predict(usersProducts).map{case Rating(user,product,rating)=>((user,product),rating)}
val ratingsAndPredictions = rating.map{case Rating(user,product,rating)=>((user,product),rating)}.join(predictions)
val MSE =ratingsAndPredictions.map{case((user,product),(actual,predicted))=>math.pow((actual-predicted),2)}.reduce(_+_)/ratingsAndPredictions.count
//均方根差
val RMSE = math.sqrt(MSE)//直接调用Mllib内置函数计算RMSE和MSE
import org.apache.spark.mllib.evaluation.RegressionMetrics
val  predictedAndTrue = ratingsAndPredictions.map{case((user,product),(predicted,actual))=>(predicted,actual)}
val regressionMetrics = new RegressionMetrics(predictedAndTrue)
println("MSE:"+regressionMetrics.meanSquaredError)
println("RMSE:"+regressionMetrics.rootMeanSquaredError)

其他代码连接 构建评分矩阵

ALS推荐算法学习总结相关推荐

  1. spark als推荐算法笔记

    转自: https://www.cnblogs.com/mstk/p/7208674.html --上面的测试集实际用的训练集 参考: https://blog.csdn.net/delltower/ ...

  2. 微博推荐算法学习(Weibo Recommend Algolrithm)

    原文:http://hijiangtao.github.io/2014/10/06/WeiboRecommendAlgorithm/ 基础及关联算法 作用:为微博推荐挖掘必要的基础资源.解决推荐时的通 ...

  3. R语言实现关联规则与推荐算法(学习笔记)

    R语言实现关联规则 笔者前言:以前在网上遇到很多很好的关联规则的案例,最近看到一个更好的,于是便学习一下,写个学习笔记. 推荐算法中 物品-物品用关联规则: 人物-物品用协同过滤: 人-人用社会网络分 ...

  4. 【推荐系统系列6】ALS推荐算法原理

    ALS算法原理 ALS算法是2008年以来,用的比较多的协同过滤算法.它已经集成到Spark的Mllib库中,使用起来比较方便. 从协同过滤的分类来说,ALS算法属于User-Item CF,也叫做混 ...

  5. 【推荐算法 学习与复现】-- 深度学习系列 -- NFM

    和前面的模型结构上都是大差不差的,但是FM归根结底还是个二阶特征交叉的模型,NFM在在Embedding层后添加 特征交叉池化层 用于对 Embedding向量两两计算元素积操作,并对交叉特征向量求和 ...

  6. 智能推荐算法学习总括

    智能推荐算法总的来说分为两种:基于内容的推荐算法和协同过滤推荐算法. 基于内容的推荐算法: 根据内容的相似度(静态的东西)进行推荐,内容不好提取的可以采取贴标签的形式来区分计算内容的相似程度.然后根据 ...

  7. 【推荐算法 学习与复现】-- 逻辑回归算法族 -- LR

    协同过滤仅仅使用有限的用户行为信息,逻辑回归算法模型大多引入用户行为.用户特征.物品特征和上下文特征等,从CF逐步过渡到综合不同特征的机器学习模型. (1)逻辑回归模型 将用户特征(年龄.性别等).用 ...

  8. 推荐算法学习笔记--DIN篇

    目录 模型简介 模型结构与分析 1.Embedding层 2.Pooling层与Concat层 3.MLP 4.Loss 模型搭建与训练 模型简介 DIN(Deep Interest Network) ...

  9. 推荐算法工程师学习路线及工作指南

    干货!推荐算法工程师学习路线及工作指南 以下文章来源于大数据与人工智能 ,作者gongyouliu 本文从我自己的学习成长经历.如何判断自己是否适合从事推荐算法.推荐算法工程师需要的知识储备.怎么找一 ...

  10. 想要成为推荐算法工程师,都要准备哪些东西

    作者在<推荐算法工程师的成长之道>这篇文章中讲到推荐算法工程师是一个好的职业选择,并且讲解了职业发展路径及定位.怎么成长等话题(还没看的可以看起来). 如果大家认可我讲的并且也愿意将来从事 ...

最新文章

  1. Wiki系统分析比较
  2. 动态规划最常见的习题 (最长公共子串、最长公共子序列、最短编辑距离)
  3. RISC-V应用创新大赛开放报名啦!
  4. c++string替换指定位置字符_Lua 字符串
  5. CCNA笔记之第十九节:RIP协议(大实验3)
  6. fscanf不读取_思考了一天,终于把matlab的fscanf中的sizeA搞清楚了
  7. C++|Qt工作笔记-Windows平台下的句柄与Qt中QWindow::winId()以及 QPlatformWindow::handle的区别与联系
  8. Linux进程睡眠状态disk sleep
  9. (转)OpenStack Kilo 版本中 Neutron 的新变化
  10. 光环PMP 三模模拟题
  11. html flash 背景,使FLASH背景变透明的方法介绍
  12. 计算机基础实践教程world,实验16+计算机基础实验报告.docx
  13. 大数据杀熟?苹果回应:定价权在开发者那
  14. iphone修改app名称_如何更改iPhone App名称100%!
  15. 人工智能AI编程基础(五)
  16. nftables和iptables的区别
  17. 【解惑】专科生在IT的发展之路
  18. 洛谷 P1941 飞扬的小鸟
  19. 【嵌入式10】stm32CubeMX+Keil使用HAL库点灯,并使用逻辑分析仪观察周期
  20. HITCSAPP大作业——程序人生

热门文章

  1. autojs开发的多功能工具箱,源码量大慢慢消化,功能非常多
  2. 女人如何获取安全感?
  3. java font 字体大小_Java字体大小从宽度
  4. 999. Available Captures for Rook
  5. android模拟器超级root,android模拟器root,avd root,emulator root教程
  6. GIS招聘 | 中煤航测遥感集团(大量测绘、地信、遥感岗位)
  7. Edge安装插件错误(download interrupted)解决办法
  8. 从步履蹒跚到举重若轻,阿里基础架构如何扛住全球最猛的流量洪峰?
  9. 回溯法中解空间树的组织
  10. 美国佛罗里达州立大学刘毅老师招收机器学习方向全奖博士生