參考資料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) } }