協同過濾的R語言實現及改進

歡迎你們前往騰訊雲+社區,獲取更多騰訊海量技術實踐乾貨哦~git

協同過濾算法是推薦系統最經常使用的算法之一,本文將介紹一種方法來使它能夠在大型數據集上快速訓練。

協同過濾算法(CF)是構建推薦系統時最經常使用的技術之一。它能夠基於收集到的其餘用戶的偏好信息(協同)來自動地預測當前用戶的興趣點。協同過濾算法主要分爲兩種:基於記憶(memory-based)的協同過濾算法和基於模型(model-based)的協同過濾算法。通常來講,將二者融合能夠得到預測準確度上的提高。github

在本文中,咱們將關注基於記憶的協同過濾算法並詳細討論其推導和集成的細節。咱們將展現咱們最近在改進經典協同過濾算法上的一些工做,使其能夠在大規模數據集上實施並達到縮短訓練時間的效果。咱們的算法是用R語言實現的,可是它也能夠被移植到其餘語言上。算法

基於記憶的協同算法又能夠分爲下面兩種:編程

  • 基於用戶的協同過濾:若是想要預測用戶U對物品I的評價,能夠藉助其餘和U類似的用戶的評價來進行預測。這麼作的緣由是咱們認爲相同品味的用戶會對同一事物作出類似的評價。
  • 基於物品的協同過濾:若是想要預測用戶U對物品I的評價,能夠藉助該用戶對和物品I類似的物品的評價進行預測。這麼作的緣由是咱們認爲同一用戶對類似事物作出的評價應當是接近的。

下面讓咱們從一個例子出發來觀察基於用戶的協同過濾是如何實現的。下面給出了計算評價ru,i的公式,ru,i 即用戶u對物品i的評分。咱們把和用戶u類似的用戶(用戶之間的類似度信息經過一個矩陣維護,sim爲類似度計算函數)的評價彙總在一塊兒,從公式能夠看出,用戶間的類似度越大,其中一個用戶對另外一個用戶評價的預測結果影響程度就越大。w爲計算最終評分所需的歸一化權重因子。數據結構

clipboard.png

clipboard.png

爲了驗證當前推薦系統的性能,咱們須要在測試集上進行預測。爲了更高的效率,計算會藉助矩陣乘法完成,而不是經過循環的方式完成。下面的圖片展現了矩陣計算的過程:框架

clipboard.png
從左到右依次爲 用戶對物品的評分矩陣 用戶類似度矩陣 預測結果矩陣編程語言

上圖展現了預測用戶U2對物品I3評分時的計算過程。爲了計算預測結果,咱們須要知道其餘用戶對I3的評分(第一個矩陣中藍色高亮的一行)以及其餘用戶與U2的類似度(第二個矩陣中藍色高亮的一列;注意這裏我經過設置類似度矩陣對角線的元素爲零來避免數據泄露)。到此,咱們能夠寫出用戶U2對物品I3評分的計算公式:分佈式

clipboard.png

計算結果將被存儲在第三個矩陣的藍色單元當中。不過這裏尚未進行歸一化,爲了獲得最終的預測結果,咱們還須要計算歸一化因子w,計算公式已經在上面給出。函數

基於記憶的協同過濾的主要優勢與它的可擴展性和性能密不可分。舉例來講,若是這裏有500,000個用戶,那麼咱們須要計算全部用戶對之間的類似度(最壞的狀況須要計算1200億個值)。顯然這須要大量的內存和處理時間,下面咱們將嘗試用R語言(固然你也可使用別的編程語言 : ) )對協同過濾算法進行一些改進從而解決這一問題。性能

咱們將用R推薦系統中最經常使用的包之一——recommenderlab與咱們的實現進行比較。這個比較是在4核i7,16G內存的小型電腦上完成的,使用的數據集是MovieLens 100k, MovieLens 1m, MovieLens 10m。後面,你會看到咱們的集成具備兩大優點:

  1. 它的速度有顯著的提高。
  2. 能夠支持在龐大的數據集上構建推薦系統,當 recommenderlab 報出內存溢出的錯誤時,咱們的實現仍然能夠正常工做。

執行效率的提高

評分矩陣一般是一個龐大(有大量的用戶和物品)的稀疏(每一個用戶每每只對少許的物品打分)矩陣。在R語言中,咱們能夠經過專門的數據結構來存儲稀疏矩陣,缺失值不會被重複存儲在內存當中。通常來講,有超過90%的值是缺失的,因此這種作法能夠節省下大量的內存。咱們的實現以及recommenderlab中都採用了矩陣的稀疏表示。

咱們實現的基於用戶的協同過濾主要包含如下步驟(基於物品的協同過濾也是如此):

  1. 導入評分矩陣
  2. 開發者決定是否對用戶評分進行標準化。這一步一般會提升準確率。這是由於標準化能夠移除用戶評分的偏置,舉例來講就是有些用戶老是會打高分或者老是打低分。
  3. 計算用戶之間的類似度。
  4. 使用KNN算法。(只保留k個最類似的用戶,即在用戶的評分預測計算中,類似度矩陣每列只保存最高的k個值)k值須要開發者手動指定。
  5. 計算預測值並進行反歸一化獲得最終的預測評分。

recommenderlab也使用了與上面相同的過程。可是咱們在這些過程當中引入了一些改進從而顯著地提高了算法執行效率。其中主要的兩個優化以下:

  1. 對大型稀疏矩陣的類似性計算進行了優化。具體方法能夠參考Recommender Systems: Matrix Operations for Fast Calculation of Similarities
  2. 類似度矩陣的k近鄰算法不是經過循環完成的,咱們採用了更優的實現。首先,咱們對類似度矩陣進行了分組(列拆分),而後在每組當中經過函數找到最高的k個值。這個函數已經在R'data.table'包中被實現。依此,咱們經過每組的信息獲得了類似度矩陣中每列最大的k個值。

驗證

咱們經過如下步驟來說咱們的實現與recommenderlab進行比較:

  • 10折交叉驗證。每次訓練使用90%的數據來建立模型、計算類似度,10%的數據用來測試。任一用戶和物品都被劃分到了訓練集或者測試集當中。
  • 中心歸一化(Center Normalization),用戶評分的平均值將從他的實際評分中扣除。
  • 餘弦距離來計算類似度。
  • k:選取的近鄰樣本數爲100,300以及樣本總值。
  • rmse:算法的偏差(root-mean-square error,均方根偏差)
  • 執行時間 (exec time) :算法的執行時間,以秒爲單位。

在100k MovieLens 數據集上的比較

該數據集包括943個用戶和1682個電影(物品),100,000個評分。

基於用戶的協同過濾

clipboard.png

基於物品的協同過濾

clipboard.png

在1M MovieLens 數據集上的比較

該數據集包括6040個用戶和3706個電影(物品),100,000個評分。

基於用戶的協同過濾

clipboard.png

基於物品的協同過濾

clipboard.png

能夠看到咱們的實如今運行速度上更快,精準度也更高(達到了更低的rmse)。其中咱們最關注的方面——速度獲得了顯著的提高。

然而,速度只是經典實現中問題的一個方面。咱們在上面提到過,協同過濾的另外一個問題是空間佔用,即當矩陣過於龐大時咱們會面臨內存不足的問題。在下一節中,咱們將提出一個可行的方案來使傳統的協同過濾算法能夠被應用在龐大的數據集上。

在龐大的數據集上構建推薦算法

在下面的測試中,咱們使用MovieLens 10m的數據集。可是正如上面提到的,咱們測試的機器只有16GB的內存而且使用了十折的交叉驗證。'recommenderlab'的實如今創建用戶類似度矩陣的過程當中就由於內存不足而退出了。

在咱們的實現當中,咱們經過對矩陣進行切分解決了這一問題。即咱們不是一次性計算全部的預測值,而是一塊一塊完成的。下面給出基於用戶的協同過濾的實現過程(基於物品的協同過濾同理):

  1. 取出用戶評分矩陣的前N行。在下圖圖示中,咱們提取了I1:I4部分的切片。
  2. 取出M個用戶並計算他們與其餘用戶的類似度。在下圖圖示中,咱們提取了U1:U2部分的切片。
  3. 根據公式計算第一步獲得的矩陣和第二步獲得的矩陣的乘積。結果爲MxN的矩陣,矩陣的元素爲歸一化以前的預測結果。在圖示中,計算結果爲用戶U1:U2對物品I1:I4的評分。
  4. 重複以上三步計算不一樣的MxN單元只到結果矩陣被填滿。

clipboard.png

在10M MovieLens 數據集上的結果

該數據集包括69,878個用戶和10,677個電影(物品),10,000,054個評分。咱們經過如下步驟來檢驗咱們的算法:

  • 10折交叉驗證
  • 中心歸一化(Center Normalization)。
  • 餘弦距離來計算類似度。
  • k:選取的近鄰樣本數爲100,1000。
  • Chunk size:在算法當中每次取出的塊的行列大小。具體的取值取決於你的硬件條件。

比較的結果能夠從下面的表格找到,包含:

  • rmse:算法的偏差(root-mean-square error)
  • 執行時間:算法的執行時間,以分鐘爲單位。
  • num predictions:協同過濾可以預測的結果數。一般來講,協同過濾不是必定可以獲得預測結果的(比方說與之類似的用戶也都尚未給該商品打分)

基於物品的協同過濾

clipboard.png

基於用戶的協同過濾

clipboard.png

正如上圖展現的結果所示,咱們實現的算法完滿地完成了任務。如今咱們能夠在16Gb內存配置的機器上構建推薦系統了。基於用戶和基於物品的協同過濾分別耗費了10分鐘和200分鐘的時間,基於用戶的協同過濾花費了更多的時間是由於數據集中有了更多的用戶,這要求咱們計算更多的類似度。

經過如今的實現,當咱們須要爲一個或者多個用戶提供實時的推薦時,類似度的計算以及結果的預測將迅速不少,由於咱們能夠只選取少部分用戶進行操做。在MovieLens 10m的數據集上,基於用戶的協同過濾只須要一秒就能夠對一個用戶或者多個用戶生成預測,可是基於物品的協同過濾則須要30s左右,這是由於咱們須要更多的時間來計算類似度矩陣。這裏還能夠經過將類似度矩陣存儲爲模型,再也不進行即時的訓練從而達到線上預測效果的加速。這個算法實現的一個顯著優勢就是可擴展性,因爲咱們將原數據集切分爲了避免同塊進行計算,因此能夠進一步實現並行化。咱們接下來的工做之一就是在分佈式框架上實現並測試這一方法。

總結

在本文中,咱們提出了一種新的方法來改進基於記憶的傳統協同過濾實現。本文的代碼能夠從Github上獲取。

問答
如何從源安裝R語言包?
相關閱讀
用R解析Mahout用戶推薦協同過濾算法(UserCF)
近鄰推薦之基於用戶的協同過濾
協同過濾原理及Python實現

此文已由做者受權騰訊雲+社區發佈,原文連接:https://cloud.tencent.com/dev...
圖片描述

相關文章
相關標籤/搜索