博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【机器学习笔记一】协同过滤算法 - ALS
阅读量:7045 次
发布时间:2019-06-28

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

参考资料

【1】《Spark MLlib 机器学习实践》

【2】

【3】线性代数-同济大学

【4】基于矩阵分解的协同过滤算法

【5】机器学习的正则化

【6】正则化方法  http://blog.csdn.net/u012162613/article/details/44261657

 

1、协同过滤算法概念

协同过滤算法是一种基于群体用户或者物品的典型的推荐算法。考虑的推荐思路基于两类:

  1)、基于用户的推荐:认为类似的用户应具备类似的爱好

  2)、基于物品的推荐:认为用户会选择比较接近的物品

两类思路也存在相应的局限性:

  1)、基于用户的推荐,无法准确找到物品热点,因此经常只反馈常用物品;

  2)、基于物品的推荐,会导致返回相似物品,但用户往往不会购买已经选择过的类似商品;

2、相似度计算

假设存在用户和物品的评价矩阵如下:

1)、基于欧几里得距离的相似度计算

,以此公式可知用户1和用户2的相似度为:

2)、基于余弦角度的相似度计算

,以此公式可知用户1和用户2的相似度为:

备注:2)相当于把欧几里得中的坐标点转换为向量,求向量的夹角

 

3、ALS(交替最小二乘法)的一些数学知识备注

1)可逆矩阵

对于矩阵,有矩阵,有

备注:已知对矩阵A实施一次初等行变换,相当于在矩阵的坐标乘以一个矩阵;对矩阵A实施一次初等列变换相当于在矩阵的右边乘以一个矩阵。

2)特征值

有矩阵,可计算该矩阵存在特征值3和5,分别对应特征向量

特征值的几何意义在于该矩阵B乘以一个向量,相当于将这个向量在特征向量方向上做了一个特征值的拉升,其他都是旋转操作。

在上面的例子中,若给出向量(1,1)则被B左乘后拉升到了(3,3)。由于5这个特征值,特征向量是0,因此无法给出拉升的效果。

3)特征分解

对于可对角矩阵可以将矩阵分解称特征值和特征向量的乘积。即,其中

4)奇异值分解

对于大部分矩阵来说,特别是非方阵,无法进行特征分解,此时我们采用奇异值分解的方法。

,同时用前r大的奇异值来近似描述矩阵,因为奇异值递减的非常快,通常前1%~10%奇异值能够占到全部奇异值之和的99%,这也是协同过滤算法的数据基础。

4、ALS(交替最小二乘法)算法流程

在实际协同过滤算法中,并没有直接用奇异值分解,而是用ALS算法直接用低秩矩阵来逼近。

当采用X来逼近矩阵R时,有Frobenius损失函数:,并增加正则化项

算法流程如下:

1、先固定矩阵U为全零

2、对L(U,V)求V的偏导,使其偏导数全为0,,得出所有的v向量

3、固定v向量,转而求u,同样使偏导数全为0,有公式,得到所有的u向量

4、重复步骤2,3,直到损失函数达到目标值。

4、ALS(交替最小二乘法)在Spark上的例子

 

package com.fredric.spark.als;import org.apache.spark.mllib.recommendation.{Rating, ALS}import org.apache.spark.{SparkContext, SparkConf}/*- * 协同过滤算法(ALS) * 针对笔记《Spark-协同过滤算法-ALS》 * Fredric 2017 */object als {  def main(args:Array[String]): Unit ={    val conf = new SparkConf().setMaster("local").setAppName("als")    val sc   = new SparkContext(conf)    val Array = new Array[Rating](5)    //new Rating(user: Int, product: Int, rating: Double)    Array(0) = new Rating(1,1,0.4)    Array(1) = new Rating(1,4,0.5)    Array(2) = new Rating(2,2,0.7)    Array(3) = new Rating(2,3,0.8)    Array(4) = new Rating(3,1,0.9)    Array(4) = new Rating(3,3,0.9)    val data = sc.makeRDD(Array)    val rank          = 2  //隐语义因子的个数。    val numIterations = 5    val lambda        = 0.01  //是ALS的正则化参数。    val model         = ALS.train(data, rank, numIterations, lambda)    //为用户1推荐4款产品    val rs    = model.recommendProducts(1, 4)    /*        输入如下:由于用户1与用户3共同爱好了产品1,因此用户3偏好的产品3也被推荐        Rating(1,4,0.4814649456978035)        Rating(1,3,0.3956308705617122)        Rating(1,1,0.38517196440752066)        Rating(1,2,0.21108557718205034)*/    rs.foreach(println)  }}

 

转载于:https://www.cnblogs.com/Fredric-2013/p/8495896.html

你可能感兴趣的文章
自建框架-mf
查看>>
Unix删除文件的找回方法
查看>>
Find 75000万像素和诺基亚的不是一个概念
查看>>
mysql处理添加外键时 error 150 问题
查看>>
企业如何针对用户数据进行有效保护
查看>>
Tomcat启动时报 java.lang.OutOfMemoryError: Java heap space
查看>>
Active Directory 基础回顾 (三)FSMO迁徙方式小总结
查看>>
Shell Script不同运行方式的区别
查看>>
Linux系统基本网络配置之ifconfig命令
查看>>
看几大IT公司的JSON利器
查看>>
Cocos2d-x 物理场景简单搭建
查看>>
认识“JPG、TXT”格式的病毒
查看>>
redhat6.2配置本地yum源
查看>>
tomcat配置文件server.xml详解
查看>>
ipython的两种安装方式
查看>>
有流媒体功能的lnmp部署练习,强化练习
查看>>
android消息机制,异步和多线程
查看>>
Linux下抓包工具tcpdump以及分析包的工具wireshark
查看>>
设置新建maven项目的jdk版本
查看>>
用copy命令将两个文件绑定,上传asp马
查看>>