基於ALS算法的簡易在線推薦系統

    繼前期完成廣義線性模型的在線流式機器學習的代碼後,我們對spark的mllib中的推薦系統這一部分比較感興趣,因爲推薦系統這一部分在現實生活中也非常實用,尤其是基於地理位置的在線推薦系統目前非常火熱,很多商業軟件如大衆點評,淘點點等都希望能根據用戶以往的一些行爲和當前所處的地理位置給用戶做出最佳的推薦,給用戶帶來意想不到的驚喜。

    在推薦系統領域,目前市面上中文的參考書並不多,我們主要學習了目前就職於hulu公司的項亮編著的《推薦系統實戰》這本書,這本書詳細的介紹了推薦系統方面的一些典型算法和評估方法,並且結合作者的實際經驗給出了很多推薦系統的相關實例,是學習推薦系統不可多得的一本好書,我們也受益匪淺。

    在spark的例程中作者是根據movielens數據庫(採用spark自帶的小型movielens數據庫在spark的data/mllib/sample_movielens_data.txt中)通過ALS(alternating leastsquares)算法來做的推薦系統。參考鏈接

http://spark.apache.org/docs/latest/mllib-collaborative-filtering.html 

    最初我們也是用上面所說的1500個的數據集進行在線ALS算法的有效性,效果還不錯,後面我們採用中等規模的movielens數據集進行測試,取得比較好的效果,具體過程記錄如下。數據集的鏈接如下。

http://grouplens.org/datasets/movielens/

    這種ALS算法不像基於用戶或者基於物品的協同過濾算法一樣,通過計算相似度來進行評分預測和推薦,而是通過矩陣分解的方法來進行預測用戶對電影的評分。即如下圖所示。

    已知的用戶對電影的評分的數據如下圖所示。


    第一項表示用戶的ID號,第二項表示電影的ID號,第三項表示用戶對電影評分的分值。

    因此可以通過數據集中的數據構建用戶評分矩陣,但是往往用戶的評分不會填滿所有的矩陣,因此就需要通過矩陣分解的方法,將矩陣X分解爲A*B,也即儘量滿足X=AB這個等式。ALS算法中,通過首先隨機化矩陣A,然後通過目標函數求得B,再對B進行歸一化處理後,再去求A,不斷地迭代下去,直到A*B滿足一定的收斂條件爲止。

    在我們的在線推薦系統中,我們借用spark的ALS算法的訓練和預測函數,每次收到新的數據後,將其更新到訓練數據集中,然後更新ALS訓練得到的模型,然後對整個movielens數據集進行評分預測計算RMSE,來看RMSE的收斂情況來推斷算法的訓練效果。(注:由於水平有限,我們發現更改spark的ALS的訓練模型爲在線訓練模型比較困難,也即在接收到新的數據後,通過更低的算法複雜度的算法得到新的分解的矩陣,而不是重新計算分解的矩陣AB的數據值)

       流程圖如下圖所示。


    在編程的時候得注意第一步訓練ALS模型的時候,給ALS模型的初始化數據集是對movielens數據集中的1500個數據根據每個用戶的評分數據隨機提取20%的數據組合而成的。另外每個用戶隨機選取20%的數據組合在一起作爲測試數據集。剩下的60%的數據作爲流式學習的數據集。

   有一個初始化模型數據集的原因是因爲ALS算法是基於矩陣分解來做的,如果最開始的數據集的取值空間不夠大的話,在下圖中的測試結果中可以看到,最初的數據集在測試集上只能預測14670個點,其實測試集是有20000個數據集的,因此很多點我們的模型無法預測,不過沒有關係,隨着訓練數據的不斷增加,我們可以預測的數據逐漸趨近於20000個,並且預測的RMSE逐漸減小,達到了在線訓練的效果。


注:

    由於ALS算法複雜度較高,我們最初在1G內存的linux上跑,出現了一些bug,換到4G內存的機器才能進行簡易的ALS模型的計算,而且ALS模型的rank, lambda, iter這幾個參數都比較重要,我們選擇了比較小的參數,使模型訓練簡單,但是可以說明問題,如果增加參數,模型會更好,由於機器條件限制,難以測試更好的模型的效果。

    另外,編程的時候碰到好多數據結構不對,或者成員函數用法不對的問題,這裏給出一些相關的網站參考鏈接,以備不時之需。由於各種數據結構的繼承關係,編程中的所有的數據結構及其成員函數的用法在下面鏈接中都可以找到。

1、java的各種數據結構類型和成員函數的用法

http://docs.oracle.com/javase/7/docs/api/

2、spark各種數據結構類型和成員函數的用法

http://spark.apache.org/docs/latest/api/scala/index.html#org.apache.spark.rdd.RDD

3、scala各種數據結構類型和成員函數的用法

http://www.scala-lang.org/api/current/#package




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章