【機器學習筆記一】協同過濾算法 - 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)

  }
}
相關文章
相關標籤/搜索