【机器学习笔记一】协同过滤算法 - ALS

参考资料html

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

【2】http://blog.csdn.net/u011239443/article/details/51752904apache

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

【4】基于矩阵分解的协同过滤算法 https://wenku.baidu.com/view/617482a8f8c75fbfc77db2aa.html函数

【5】机器学习的正则化 http://www.cnblogs.com/jianxinzhou/p/4083921.html学习

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

 

一、协同过滤算法概念.net

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

  1)、基于用户的推荐:认为相似的用户应具有相似的爱好code

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

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

  1)、基于用户的推荐,没法准确找到物品热点,所以常常只反馈经常使用物品;

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

二、类似度计算

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

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

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

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

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

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

 

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

1)可逆矩阵

对于矩阵,有矩阵,有

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

2)特征值

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

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

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

3)特征分解

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

4)奇异值分解

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

,同时用前r大的奇异值来近似描述矩阵,由于奇异值递减的很是快,一般前1%~10%奇异值可以占到所有奇异值之和的99%,这也是协同过滤算法的数据基础。

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

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

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

算法流程以下:

一、先固定矩阵U为全零

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

三、固定v向量,转而求u,一样使偏导数全为0,有公式,获得全部的u向量

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

四、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)

  }
}
相关文章
相关标签/搜索