基於Spark ALS演算法的個性化推薦
今天來使用spark中的ALS演算法做一個小推薦。需要資料的話可以點選檢視,在文末點選閱讀原文即可獲取。
其實在R中還有一個包可以做推薦,那就是recommenderlab。如果資料量不大的時候可以使用recommenderlab包,之前也用該包做過(點選即可檢視)。如果資料量較大還是推薦使用spark來進行計算。
在spark中包含了許多機器學習演算法,其中就有一個推薦演算法,即ALS。
ALS演算法也就是協同過濾演算法,它是基於矩陣分解的協同過濾,何為矩陣分解?就是把一個評分矩陣A分解為兩個矩陣B,C。B*C=A。為什麼要進行分解?那是因為矩陣A是一個稀疏矩陣,分解之後的B,C矩陣相對能稠密一點。使用該演算法可以很方便的做一個推薦系統,核心程式碼只有三行。
一.讀取資料
moviedata<-read.table("u.data",header = FALSE,sep = "\t")
#這四列資料分別表示:使用者id,電影id,評分,時間戳
head(moviedata)#
V1 V2 V3 V4
1 196 242 3 881250949
2 186 302 3 891717742
3 22 377 1 878887116
4 244 51 2 880606923
5 166 346 1 886397596
6 298 474 4 884182806
# 刪除第四列
moviedata<-moviedata[,-4]
#重新命名列
colnames(moviedata)<-c("userid","itemid","rating")
連線到spark
library(sparklyr)
library(dplyr)
sc <- spark_connect(master = "local")
二. 推薦
前面那些都是準備工作,現在就來實現推薦部分,真的只需三行程式碼。
#1 儲存到spark中
moviedataSpark<-copy_to(sc,moviedata,overwrite = TRUE )
#2 建立模型
moviedata_model<-ml_als_factorization(moviedataSpark,rating_col="rating" ,
user_col="userid",item_col="itemid")
summary(moviedata_model)#此句是檢視模型屬性#每個使用者推薦2個
#3 生成推薦結果
movie_recommend<-ml_recommend(moviedata_model,type = c("items"),n=2)
> movie_recommend
# Source: table<sparklyr_tmp_9fd405a6463> [?? x 4]# Database: spark_connection
userid recommendations itemid rating
<int> <list> <int> <dbl>
1 12 <list [2]> 1450 5.32
2 12 <list [2]> 113 5.17
3 13 <list [2]> 1643 5.59
4 13 <list [2]> 814 4.87
5 14 <list [2]> 1367 5.18
6 14 <list [2]> 1463 5.17
7 18 <list [2]> 1449 4.86
8 18 <list [2]> 1642 4.78
9 25 <list [2]> 1643 4.80
10 25 <list [2]> 1449 4.70
# ... with more rows
是不是三句程式碼就搞定了。沒騙人吧。從結果可以看到給使用者id為12的使用者推薦的是1450和113.在這裡ALS演算法其他引數給的都是預設值,可以通過不斷調整引數來優化我們的模型。
三.模型評估
模型生成之後需要對模型進行評估,我們可以使用RMSE方法進行模型計算評估,它的計算公式如下:
不過要在之前我們需要知道使用者對電影的預測評分,然後根據預測評分和實際評分來計算出RMSE結果。獲取預測評分可以使用transform方法,如果你想要更多的瞭解transform方法,可以開啟:http://spark.apache.org/docs/latest/ml-collaborative-filtering.html進行檢視官方文件說明。
#評分預測
#invoke用於呼叫java物件方法
movie_prediction<-moviedata_model$.jobj%>%invoke("transform",spark_dataframe(moviedataSpark))%>%collect()
> movie_prediction
#預測結果
# A tibble: 100,000 x 4
userid itemid rating prediction
<int> <int> <int> <dbl> 1 13 12 5 3.83
2 14 12 5 4.47
3 18 12 5 4.21
4 73 12 5 4.28
5 109 12 4 3.70
6 110 12 4 3.40
7 115 12 5 4.57
8 130 12 4 4.85
9 135 12 4 4.21
10 177 12 5 4.32
# ... with 99,990 more rows#模型評估
model_RMSE<-sqrt(mean((movie_prediction$rating-movie_prediction$prediction)^2))
在計算模型時,引數給的都是預設值,此時model_RMSE=0.7725977。該值越小,說明該模型越好。
現在修改引數,當把引數調整為:reg_param=0.05,max_iter = 20L,alpha=2
model_RMSE等於0.7123907.比預設時的值小了0.06,就這樣通過不斷優化調整引數來使得模型最優。
轉載請註明:
作者:王亨
公眾號:跟著菜鳥一起學R語言
原文連結:http://blog.csdn.net/wzgl__wh