為什么spark中只有ALS


WRMF is like the classic rock of implicit matrix factorization. It may not be the trendiest, but it will never go out of style

                                                                                                                                                                  --
Ethan Rosenthal

前言

spark平台推出至今已經地帶到2.1的版本了,很多地方都有了重要的更新,加入了很多新的東西。但是在協同過濾這一塊卻一直以來都只有ALS一種算法。同樣是大規模計算平台,Hadoop中的機器學習算法庫Mahout就集成了多種推薦算法,不但有user-cf和item-cf這種經典算法,還有KNN、SVD,Slope one這些,可謂隨意挑選,簡繁由君。我們知道得是,推薦系統這個應用本身並沒有過時,那么spark如此堅定 地只維護一個算法,肯定是有他的理由的,讓我們來捋一捋。

ALS算法

ALS的意思是交替最小二乘法(Alternating Least Squares),它只是是一種優化算法的名字,被用在求解spark中所提供的推薦系統模型的最優解。spark中協同過濾的文檔中一開始就說了,這是一個基於模型的協同過濾(model-based CF),其實它是一種近幾年推薦系統界大火的隱語義模型中的一種。隱語義模型又叫潛在因素模型,它試圖通過數量相對少的未被觀察到的底層原因,來解釋大量用戶和產品之間可觀察到的交互。操作起來就是通過降維的方法來補全用戶-物品矩陣,對矩陣中沒有出現的值進行估計。基於這種思想的早期推薦系統常用的一種方法是SVD(奇異值分解)。該方法在矩陣分解之前需要先把評分矩陣R缺失值補全,補全之后稀疏矩陣R表示成稠密矩陣R',然后將R’分解成如下形式:
R' = UTSV
然后再選取U中的K列和V中的S行作為隱特征的個數,達到降維的目的。K的選取通常用啟發式策略。

這種方法有兩個缺點,第一是補全成稠密矩陣之后需要耗費巨大的存儲空間,在實際中,用戶對物品的行為信息何止千萬,對這樣的稠密矩陣的存儲是不現實的;第二,SVD的計算復雜度很高,更不用說這樣的大規模稠密矩陣了。所以關於SVD的研究很多都是在小數據集上進行的。

隱語義模型也是基於矩陣分解的,但是和SVD不同,它是把原始矩陣分解成兩個矩陣相乘而不是三個。
A = XYT
現在的問題就變成了確定X和Y ,我們把X叫做用戶因子矩陣,Y叫做物品因子矩陣。通常上式不能達到精確相等的程度,我們要做的就是要最小化他們之間的差距,從而又變成了一個最優化問題。求解最優化問題我們很容易就想到了隨機梯度下降,其中有一種方法就是這樣,通過優化如下損失函數來找到X和Y中合適的參數:
 
其中puk就是X矩陣中u行k列的參數,度量了用戶u和第k個隱類的關系;q ik是Y矩陣中i行k列的參數,度量了物品i和第k個隱類的關系。這種方式也是一種很流行的方法,有很多對它的相關擴展,比如加上偏置項的LFM

然而ALS用的是另一種求解方法,它先用隨機初始化的方式固定一個矩陣,例如Y
 
然后通過最小化等式兩邊差的平方來更新另一個矩陣X,這就是“最小二乘”的由來。得到X之后,又可以固定X用相同的方法求Y,如此交替進行,直到最后收斂或者達到用戶指定的迭代次數為止,是為“交替”是也。   從上式可以看出,X的第i行是A的第i行和Y的函數,因此可以很容易地分開計算X的每一行,這就為並行就算提供了很大的便捷,也正是如此,Spark這種面向大規模計算的平台選擇了這個算法。在3這篇文章中,作者用了embarrassingly parallel來形容這個算法,意思是高度易並行化的——它的每個子任務之間沒有什么依賴關系。

在現實中,不可能每個用戶都和所有的物品都有行為關系,事實上,有交互關系的用戶-物品對只占很小的一部分,換句話說,用戶-物品關系列表是非常稀疏的。和SVD這種矩陣分解不同,ALS所用的矩陣分解技術在分解之前不用把系數矩陣填充成稠密矩陣之后再分解,這不但大大減少了存儲空間,而且spark可以利用這種稀疏性用簡單的線性代數計算求解。這幾點使得本算法在大規模數據上計算非常快,解釋了為什么spark mllib目前只有ALS一種推薦算法。

顯性反饋和隱性反饋

我們知道,在推薦系統中用戶和物品的交互數據分為顯性反饋和隱性反饋數據的。在ALS中這兩種情況也是被考慮了進來的,分別可以訓練如下兩種模型:
     
     
     
             
  1. val model1 = ALS.train(ratings, rank, numIterations, lambda)//顯性反饋模型
  2. val model2 = ALS.trainImplicit(ratings, rank, numIterations, lambda, alpha)//隱性反饋模型
參數:
rating:由用戶-物品矩陣構成的訓練集
rank:隱藏因子的個數
numIterations: 迭代次數
lambda:正則項的懲罰系數
alpha: 置信參數

從上面可以看到,隱式模型多了一個置信參數,這就涉及到ALS中對於隱式反饋模型的處理方式了——有的文章稱為“加權的正則化矩陣分解”,它的損失函數如下:
 
我們知道,在隱反饋模型中是沒有評分的,所以在式子中 r ui p ui 所取代,pui是偏好的表示,僅僅表示用戶和物品之間有沒有交互,而不表示評分高低或者喜好程度。比如用戶和物品之間有交互就讓pui等於1,沒有就等於0。函數中還有一個 c ui 的項,它用來表示用戶偏愛某個商品的置信程度,比如交互次數多的權重就會增加。如果我們用 d ui 來表示交互次數的話,那么就可以把置信程度表示成如下公式:
這里的alpha就是上面提到的置信參數,也是這個模型的超參數之一,需要用交叉驗證來得到。



用spark的ALS模型進行推薦

1.為指定用戶進行topN推薦
     
     
     
             
  1. model.recommendProducts(userID, N)
2.為 用戶-物品 對進行預測評分,顯式和隱式反饋都可以,是根據兩個因子矩陣對應行列相乘得到的數值,可以用來評估系統。既可以傳入一對參數,也可以傳入以(user,item)對類型的RDD對象作為參數,如下
     
     
     
             
  1. model.predict(user, item)
  2. model.predict(RDD[int, int])
3.根據物品推薦相似的物品
這其實不算是一種模型內置的推薦方式,但是ALS可以為我們計算出物品因子矩陣和用戶因子矩陣:
    
    
    
            
  1. model.productFeatures
  2. model.userFeatures
這是一種降維,讓我們可以用更少的維度表示,同時也意味着如果我們要算物品相似度或者用戶相似度可以用更少的特征進行計算。進而得到“和這個物品相似的物品”這種類型的推薦。

參考資料

1.《spark機器學習》
2.《spark高級數據分析


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM