深入理解Spark ML:基於ALS矩陣分解的協同過濾演算法與原始碼分析
1. 引言
隨著網際網路的迅猛發展,為了滿足人們在繁多的資訊中獲取自己需要內容的需求,個性化推薦應用而生。協同過濾推薦是其中運用最為成功的技術之一。其中,基於使用者的最近鄰法根據相似使用者的評分來預測當前使用者的評分。然而,在使用者數量以及使用者評分不足的情況下,該方法存在冷啟動和資料稀疏的問題。為了解決這兩個問題,業界提出了提出了基於項的最近鄰法,利用項之間相似性穩定的特點可以離線計算相似性,降低了線上計算量,提高了推薦效率,但同樣存在冷啟動和資料稀疏問題。若使用 矩 陣 分 解 中 的 奇 異 值 分 解 ( Singular Value Decomposition,SVD) 減少評分矩陣的維數,之後應用最近鄰法預測評分,一定程度上解決了同義詞問題,但由於評分矩陣中大部分的評分是分解之前填充的,所以得到的特徵矩陣不能直接用於評分。業界還提出了一種基於矩陣分解和使用者近鄰模型的演算法,解決了資料稀疏的問題,但存在模型過擬合的問題。而協同過濾提出了一種支援不完整評分矩陣的矩陣分解方法,不用對評分矩陣進行估值填充,有很好的推薦精度。在 Netflix
在矩陣分解推薦演算法中,每項評分預測都需要整合現有評分集的資訊。隨著使用者數與專案數的增長,演算法的計算量也會隨著增長,單機模式的推薦演算法逐漸難以滿足演算法的計算以及推送的即時性需求,因此分散式推薦演算法成為推薦演算法中研究的一個新的方向。業界提出了分散式的矩陣分解演算法,為矩陣分解的平行計算提供了一種可行的解決方案,但其使用的MapReduce
框架在各計算節點的迭代計算中會產生過多的磁碟檔案讀寫操作,影響了演算法的執行效率。
本文旨在深入與Spark
平行計算框架結合,探索協同過濾演算法原理與在Spark
2. 基於ALS矩陣分解協同過濾演算法
如上述提及的,協同過濾提出了一種支援不完整評分矩陣的矩陣分解方法,不用對評分矩陣進行估值填充,有很好的推薦精度。Spark MLlib
中實現的基於ALS
矩陣分解協同過濾演算法。下面我們來介紹下ALS矩陣分解
2.1 矩陣分解模型
使用者對物品的打分行為可以表示成一個評分矩陣A(m*n)
,表示m個使用者對n各物品的打分情況。如下表所示:
U\V | v1 | v2 | v3 | v4 |
---|---|---|---|---|
u1 | 4 | 3 | ? | 5 |
u2 | ? | 5 | 4 | 5 |
u3 | ? | ? | 3 | 3 |
u4 | 5 | 5 | 3 | 3 |
u5 | 2 | 1 | 5 | ? |
其中,表示使用者對物品的打分。但是,使用者不會對所以物品打分,表中”?”表示使用者沒有打分的情況,所以這個矩陣A很多元素都是空的,我們稱其為“缺失值(missing value)”。協同過濾提出了一種支援不完整評分矩陣的矩陣分解方法,不用對評分矩陣進行估值填充。在推薦系統中,我們希望得到使用者對所有物品的打分情況,如果使用者沒有對一個物品打分,那麼就需要預測使用者是否會對該物品打分,以及會打多少分。這就是所謂的“矩陣補全(填空)”。
ALS 的核心假設是:打分矩陣A是近似低秩的,即一個的打分矩陣 可以用兩個小矩陣和的乘積來近似:
我們把打分理解成相似度,那麼“打分矩陣”就可以由“使用者喜好特徵矩陣”和“產品特徵矩陣”的乘積。
2.2 交替最小二乘法(ALS)
我們使用使用者喜好特徵矩陣中的第i個使用者的特徵向量,和產品特徵矩陣第j個產品的特徵向量來預測打分矩陣中的。我們可以得出一下的矩陣分解模型的損失函式為:
有了損失函式之後,下面就開始介紹優化方法。通常的優化方法分為兩種:交叉最小二乘法(alternative least squares)和隨機梯度下降法(stochastic gradient descent)。Spark使用的是交叉最小二乘法(ALS)來最優化損失函式。演算法的思想就是:我們先隨機生成然後固定它求解,再固定求解,這樣交替進行下去,直到取得最優解。因為每步迭代都會降低誤差,並且誤差是有下界的,所以 ALS 一定會收斂。但由於問題是非凸的,ALS 並不保證會收斂到全域性最優解。但在實際應用中,ALS 對初始點不是很敏感,是否全域性最優解造成的影響並不大。
演算法的執行步驟:
- 先隨機生成一個。一般可以取0值或者全域性均值。
固定,即認為是已知的常量,來求解:
由於上式中只有一個未知變數,因此C的最優化問題轉化為最小二乘問題,用最小二乘法求解的最優解:
固定,則:等式兩邊關於為求導得: