協同過濾推薦系統的R實現


 

本節將會學習到:

  1. 協同過濾推薦系統

  2. 協同過濾推薦系統的R實現

  3. 推薦系統的可視化

  4. 不同推薦系統的離線實驗算法比較及可視化

前言

     本節我們來探討和學習下推薦系統的相關內容。 隨着大數據時代的到來,我們越來越感受到數據無處不在。 我們已經處於一個數據過載的環境,無論是電商網站眼花繚亂的物品,還是紛繁復雜的社交網絡,以往通過熟人推薦或者有限選擇的舊模式已經無法滿足自身的需求。 如是乎推薦系統,或稱協同過濾推薦(Collaborative Filtering recommendation ) 如火如荼發展起來。 
    推薦系統的任務就是聯系用戶和信息,一方面幫助用戶發現對自己有價值的信息,另一方面讓信息能夠展現在對它感興趣的用戶面前,從而實現信息消費者和信息生產者的雙贏。 無論是針對推薦系統中的數據稀疏及冷啟動問題,還是在大數據條件下是實現,推薦系統已經形成自己專門的研究體系。 本文只是個人最近處於入門的學習中的一些總結,無論從知識體系,還是問題的理解深度都還有很大差距,但是作為自我學習的記錄和分享,還是決定寫出來,接受各位的拍磚

推薦系統概述

     想象下對於一個擁有數量龐大圖書的圖書館,想從中盡快的挑選到自己滿意的某一本書,我們應該怎么做?可能我們主要有以下4種做法:首先可能是從過往的經驗中尋找。 從自己熟悉的某個欄目,或者之前看過類似的書籍附近的欄目中尋找、、二是詢問自己的“熟人”或看過類似書籍的人。 從他們那里獲得想要找的書在哪里找到、第三應該是找到圖書館目錄表,從不同分類目錄中尋找、當然最后一種應該是先從圖書館搜索引擎中輸入書籍信息,找到書的位置。 其實這也是解決信息過載(圖書數量巨大)問題主要的方法:基於物品或用戶的協同過濾推薦、、分類目錄和搜索引擎方法。 當然這些解決方案分別催生了互聯網領域的幾大著名公司——亞馬遜、、雅虎和谷歌。 但分類目錄及搜索引擎對於用戶無法准確描述自己需求時(無法描述具體希望看某一本書時),往往無能為力。 而推薦系統能夠在用戶沒有明確目的的時候幫助他們發現感興趣的新內容。 
評價推薦系統的實驗方法主要有3種:離線實驗(offline experiment)、、用戶調查(user study)和在線實驗(online experiment)。  
    離線實驗主要針對已有數據集,按一定規則分成訓練集和測試集,通過預測准確度、評價效果、用戶調查即通過傳統的調查問卷方式獲得用戶基本信息及對推薦結果的主觀感受、評價模型好壞、驚喜度、新穎性、,可額外獲得客戶滿意度、覆蓋率、在線實驗主要用於在離線及用戶調查結果良好,將推薦系統上線做AB測試,評價算法的性能。 主要評價指標如點擊率、信任度、實時性、健壯性及商業目標的達成、。 
推薦系統的形式主要有2種:Top-N推薦和推薦評分(或0-1評分)。 這也是我們日常在瀏覽網頁或電影、、歌曲中最常見的推薦形式。 
    協調過濾算法又主要有:基於鄰域算法(包含基於用戶的協同過濾(item-based CF)及基於物品的協同過濾(user-based CF))、 隱語義模型及基於圖的隨機游走算法、。 而應用於商業最多的屬基於鄰域的算法。 開源的推薦系統非常多,基本上全都是用C++/Java實現,即有輕量級的適用於做研究的SVDFeature、LibMF、Oryx、LibFM、,也有重量級的適用於工業系統的Mahout、EasyRecd、。 基於Python的主要有Crab(Python)和Python-recsys(Python),基於R的主要有Recommenderlab(R)。 詳情可參考[推薦系統開源軟件列表匯總和點評]<http://blog.csdn.net/cserchen/article/details/14231153#tc_qz_original=691102124>。 
    至於如何選擇合適的推薦模型,下面這張圖我個人覺得是非常實用的,推薦參考[選擇合適的推薦系統模型]<http://blog.jobbole.com/86959/>。 
關於推進系統的數據也非常多,目前本人只看了入門級書籍:《推薦系統實踐》和《集體智慧編程》(均用Python編程),可在知乎中自行搜索。 作為一名R愛好者,個人認為先搞清楚R在推薦系統中的使用是基礎,因此下面將通過recommenderlab包,介紹推薦系統的相關內容
   協同過濾推薦系統的R實現

數據構成

 set.seed ( 1234 )
library ( "recommenderlab" )
m <- matrix ( sample ( c ( as.numeric ( 0 : 5 ) , NA ) , 50 ,     replace = TRUE , prob = c ( rep ( .4 / 6 , 6 ) , .6 ) ) , ncol = 10 , dimnames = list ( user = paste ( "u" , 1 : 5 , sep = '' ) , item = paste ( "i" , 1 : 10 , sep = '' ) ) )
r <- as ( m , "realRatingMatrix" ) m ; r
 ##     item
## user i1 i2 i3 i4 i5 i6 i7 i8 i9 i10
##   u1 NA  2  3  5 NA  5 NA  4 NA  NA
##   u2  2 NA NA NA NA NA NA NA  2   3
##   u3  2 NA NA NA NA  1 NA NA NA  NA
##   u4  2  2  1 NA NA  5 NA  0  2  NA
##   u5  5 NA NA NA NA NA NA  5 NA   4
 ## 5 x 10 rating matrix of class 'realRatingMatrix' with 19 ratings.
     運用recommenderlab包實現協同過濾推薦,其數據類型采用S4類構造,使用抽象的raringMatrix為評分數據提供接口。 先自行構建一個包含缺失值的矩陣,行為u1-u5個用戶,列為i1-i10的物品。 需通過as()函數轉為raringMatrix類型。 raringMatrix采用了很多類似矩陣對象的操作,如dim(),dimnames(),rowCounts(),colMeans(),rowMeans(),colSums(),rowMeans()、、也增加了一些特別的操作方法,如sample(),用於從用戶(即,行)中抽樣,image()可以生成像素圖

數據轉換

 head ( as ( r , "data.frame" ) )
 ##    user item rating
## 5    u1   i2      2
## 7    u1   i3      3
## 9    u1   i4      5
## 10   u1   i6      5
## 13   u1   i8      4
## 1    u2   i1      2
 n <- normalize ( r )
image ( r , main = "Raw rating" )

協同過濾推薦系統的R實現

 image ( n , main = "normalized rating" )

協同過濾推薦系統的R實現

 #二元分類轉換
r_b <- binarize ( r , minRating = 4 )
b <- as ( r_b , "matrix" ) b
 ##    i1 i2 i3 i4 i5 i6 i7 i8 i9 i10
## u1  0  0  0  1  0  1  0  1  0   0
## u2  0  0  0  0  0  0  0  0  0   0
## u3  0  0  0  0  0  0  0  0  0   0
## u4  0  0  0  0  0  1  0  0  0   0
## u5  1  0  0  0  0  0  0  1  0   1

    數據也可轉換為數據框類型,或通過normalize()函數進行標准化處理,標准化的目的是為了去除用戶評分的偏差、、通過binarize()函數轉為binaryRatingMatrix類型,適用於是0-1的評分矩陣(贊/踩)

數據可視化

     為更好說明推薦系統的算法,我們采用非常出名的MovieLense數據集,其收集了網站MovieLens(movielens.umn.edu)從1997年9月19日到1998年4月22日的數據,包括943名用戶對1664部電影的評分。 getRatings()函數可獲取評價數據。 image()可查看數據分布
 data ( MovieLense )
r <- sample ( MovieLense , 943 , replace = F )
image ( MovieLense )

協同過濾推薦系統的R實現

 hist ( getRatings ( normalize ( MovieLense ) ) , breaks = 100 )

協同過濾推薦系統的R實現

 hist ( rowCounts ( r ) , breaks = 50 )

協同過濾推薦系統的R實現

創建推薦

查看推薦方法

     我們已經獲得了評分數據,現在來看看recommenderlab包可以實現哪些推薦算法呢!可以運用recommenderRegistry$get_entry_names()函數實現。 參數realRatingMatrix表示數據類型是推薦評分型(如1-5顆星評價),可具體查看算法說明。 對於realRatingMatrix有六種方法:IBCF(基於物品的推薦)、UBCF(基於用戶的推薦)、PCA(主成分分析)、 RANDOM(隨機推薦)、SVD(矩陣因子化)、POPULAR(基於流行度的推薦)
 recommenderRegistry $ get_entry_names ( )
 ##  [1] "AR_binaryRatingMatrix"      "IBCF_binaryRatingMatrix"   
##  [3] "IBCF_realRatingMatrix"      "PCA_realRatingMatrix"      
##  [5] "POPULAR_binaryRatingMatrix" "POPULAR_realRatingMatrix"  
##  [7] "RANDOM_realRatingMatrix"    "RANDOM_binaryRatingMatrix" 
##  [9] "SVD_realRatingMatrix"       "SVD_binaryRatingMatrix"    
## [11] "UBCF_binaryRatingMatrix"    "UBCF_realRatingMatrix"
 recommenderRegistry $ get_entries ( dataType = "realRatingMatrix" )

建立模型

     建立協同過濾推薦算法模型,主要運用Recommender(data=ratingMatrix,method,parameter=NULL)函數,getModel()可查看模型參數
 r_recom <- Recommender ( r , method = "IBCF" )
r_popul <- Recommender ( r , method = "POPULAR" )
#查看模型方法
names ( getModel ( r_recom ) )
 ##  [1] "description"          "sim"                  "k"                   
##  [4] "method"               "normalize"            "normalize_sim_matrix"
##  [7] "alpha"                "na_as_zero"           "minRating"           
## [10] "verbose"

模型預測

TOP-N預測

     對模型預測可運用predict()函數,在此分別以TOP-N預測及評分預測為例,預測第940-943位觀影者的評分情況。 n表示最終為TOP-N的列表推薦,參數type = "ratings"表示運用評分預測觀影者對電影評分,模型結果均需轉為list或矩陣表示
 pred <- predict ( r_popul , r [ 940 : 943 ] , n = 5 ) as ( pred , "list" )
#top-N為有序列表,抽取最優推薦子集
pred3 <- bestN ( pred , n = 3 )
as ( pred3 , "list" )

協同過濾推薦系統的R實現

 #評分預測
rate <- predict ( r_popul , r [ 940 : 943 ] , type = "ratings" )
as ( rate , "matrix" ) [ , 1 : 5 ]

協同過濾推薦系統的R實現

預測模型評價

評分預測模型評價

     建立推薦系統模型后,非常關心的是對預測模型的評價。 可通過evaluationScheme()將數據按一定規則分為訓練集和測試集(參數method = "split",),或進行k-fold交叉驗證(如method = "cross",k=4),given參數表示用來進行模型評價的items的數量。 分別運用UBCF及IBCF算法,進行預測評價。 
    getData(e,"train")表示獲取訓練集數據,predict(r1,getData(e,"known"),type = "ratings")表示對“已知”訓練集數據進行預測。 計算預測模型的准確度可通過calcPredictionAccuracy()函數實現,參數“unknown”表示對“未知”test集進行比較。 結果發現兩種方法的均方根誤差(RMSE)基本一致
 e <- evaluationScheme ( r [ 1 : 800 ] , method = "split" , train = 0.9 , given = 15 , goodRating = 5 )、、 e
 ## Evaluation scheme with 15 items given
## Method: 'split' with 1 run(s).
## Training set proportion: 0.900
## Good ratings: >=5.000000
## Data set: 800 x 1664 rating matrix of class 'realRatingMatrix' with 83043 ratings.
 r1 <- Recommender ( getData ( e , "train" ) , "UBCF" ) ;
p1 <- predict ( r1 , getData ( e , "known" ) , type = "ratings" ) ;
r2 <- Recommender ( getData ( e , "train" ) , "IBCF" ) ;
p2 <- predict ( r2 , getData ( e , "known" ) , type = "ratings" ) ;
 ##計算預測模型的准確度
c1 <- calcPredictionAccuracy ( p1 , getData ( e , "unknown" ) )
c2 <- calcPredictionAccuracy ( p2 , getData ( e , "unknown" ) )
error <- rbind ( c1 , c2 ) rownames ( error ) <- c ( "UBCF" , "IBCF" )
error
 ##          RMSE      MSE       MAE
## UBCF 1.053345 1.109537 0.8338755
## IBCF 1.172571 1.374924 0.8580037

TOP-N預測模型評價

     讓我們來評價TOP-1,TOP-3,TOP-5,TOP-10推薦准確性。 通過4-fold交叉驗證方法分割數據集,運用evaluate()進行TOP-N預測模型評價。 評價結果可通過ROC曲線及准確率-召回率曲線展示
 #4-fold交叉驗證
tops <- evaluationScheme ( r [ 1 : 800 ] , method = "cross" , k = 4 , given = 3 , goodRating = 5 )
tops
 ## Evaluation scheme with 3 items given
## Method: 'cross-validation' with 4 run(s).
## Good ratings: >=5.000000
## Data set: 800 x 1664 rating matrix of class 'realRatingMatrix' with 83043 ratings.
 results <- evaluate ( tops , method = "POPULAR" , type = "topNList" ,  n = c ( 1 , 3 , 5 , 10 ) )
 ## POPULAR run fold/sample [model time/prediction time]
##   1  [0.02sec/0.16sec] 
##   2  [0.02sec/0.17sec] 
##   3  [0sec/0.14sec] 
##   4  [0.02sec/0.16sec]
 #獲得混淆矩陣
getConfusionMatrix ( results ) [ [ 1 ] ]

協同過濾推薦系統的R實現

 avg ( results )

協同過濾推薦系統的R實現

 #ROC曲線
plot ( results , annotate = TRUE )

協同過濾推薦系統的R實現

 #准確率-召回率曲線
plot ( results , "prec/rec" , annotate = TRUE )

協同過濾推薦系統的R實現

推薦算法的比較

   除了對預測模型進行評價,還可以對不同推薦算法進行比較。 可首先構建一個推薦算法列表,通過ROC曲線、、准確率-召回率曲線或RMSE直方圖進行比較

TOP-N算法比較

 set.seed ( 2016 )
scheme <- evaluationScheme ( r , method = "split" , train = 0.9 , k = 1 , given = 10 , goodRating = 5 )
#構建推薦算法列表
algorithms <- list (   "random items" = list ( name = "RANDOM" , param = NULL ) ,   "popular items" = list ( name = "POPULAR" , param = list ( normalize = "Z-score" ) ) ,   "user-based CF" = list ( name = "UBCF" , param = list ( normalize = "Z-score" , method = "Cosine" , nn = 25 , minRating = 3 ) ) ,   "item-based CF" = list ( name = "IBCF" , param = list ( k = 50 ) ) ,   "SVD approximation" = list ( name = "SVD" , param = list ( approxRank = 50 ) ) )
#構建不同算法模型
results <- evaluate ( scheme , algorithms , n = c ( 1 , 3 , 5 , 10 , 15 , 20 ) )
#模型比較 #ROC曲線
plot ( results , annotate = c ( 1 , 3 ) , legend = "bottomright" )

協同過濾推薦系統的R實現

 #准確率-召回率曲線
plot ( results , "prec/rec" , annotate = c ( 2 , 3 , 4 ) , legend = "topleft" )
協同過濾推薦系統的R實現

預測評分算法比較

 results2 <- evaluate ( scheme , algorithms , type = "ratings" )
plot ( results2 , ylim = c ( 0 , 20 ) )

協同過濾推薦系統的R實現

應用新的推薦算法

     當然在recommenderlab包說明文檔中也有自定義新的推薦算法的舉例,通過編輯推薦算法的函數實現符合實際的推薦算法。 但要說明的是運用R進行協同過濾推薦並不是推薦系統應用的主流,主要原因在於算法調整不靈活,並且R主要依靠內存的單線程計算,並不太適用於過大規模的推薦應用

參考資料

轉自:http://www.0791quanquan.com/news_keji/topic_1953157/


免責聲明!

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



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