歡迎大家前往騰訊雲+社區,獲取更多騰訊海量技術實踐干貨哦~
協同過濾算法是推薦系統最常用的算法之一,本文將介紹一種方法來使它可以在大型數據集上快速訓練。
協同過濾算法(CF)是構建推薦系統時最常用的技術之一。它可以基於收集到的其他用戶的偏好信息(協同)來自動地預測當前用戶的興趣點。協同過濾算法主要分為兩種:基於記憶(memory-based)的協同過濾算法和基於模型(model-based)的協同過濾算法。一般來說,將兩者融合可以獲得預測准確度上的提升。
在本文中,我們將關注基於記憶的協同過濾算法並詳細討論其推導和集成的細節。我們將展示我們最近在改進經典協同過濾算法上的一些工作,使其可以在大規模數據集上實施並達到縮短訓練時間的效果。我們的算法是用R語言實現的,但是它也可以被移植到其他語言上。
基於記憶的協同算法又可以分為下面兩種:
- 基於用戶的協同過濾:如果想要預測用戶U對物品I的評價,可以借助其他和U相似的用戶的評價來進行預測。這么做的原因是我們認為相同品味的用戶會對同一事物做出相似的評價。
- 基於物品的協同過濾:如果想要預測用戶U對物品I的評價,可以借助該用戶對和物品I相似的物品的評價進行預測。這么做的原因是我們認為同一用戶對相似事物做出的評價應當是接近的。
下面讓我們從一個例子出發來觀察基於用戶的協同過濾是如何實現的。下面給出了計算評價ru,i的公式,ru,i 即用戶u對物品i的評分。我們把和用戶u相似的用戶(用戶之間的相似度信息通過一個矩陣維護,sim為相似度計算函數)的評價匯總在一起,從公式可以看出,用戶間的相似度越大,其中一個用戶對另一個用戶評價的預測結果影響程度就越大。w為計算最終評分所需的歸一化權重因子。


為了驗證當前推薦系統的性能,我們需要在測試集上進行預測。為了更高的效率,計算會借助矩陣乘法完成,而不是通過循環的方式完成。下面的圖片展示了矩陣計算的過程:

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

計算結果將被存儲在第三個矩陣的藍色單元當中。不過這里還沒有進行歸一化,為了得到最終的預測結果,我們還需要計算歸一化因子w,計算公式已經在上面給出。
基於記憶的協同過濾的主要優點與它的可擴展性和性能密不可分。舉例來說,如果這里有500,000個用戶,那么我們需要計算所有用戶對之間的相似度(最壞的情況需要計算1200億個值)。顯然這需要大量的內存和處理時間,下面我們將嘗試用R語言(當然你也可以使用別的編程語言 : ) )對協同過濾算法進行一些改進從而解決這一問題。
我們將用R推薦系統中最常用的包之一——recommenderlab與我們的實現進行比較。這個比較是在4核i7,16G內存的小型電腦上完成的,使用的數據集是 MovieLens 100k, MovieLens 1m, MovieLens 10m。后面,你會看到我們的集成具有兩大優勢:
- 它的速度有顯著的提升。
- 可以支持在龐大的數據集上構建推薦系統,當 recommenderlab 報出內存溢出的錯誤時,我們的實現仍然可以正常工作。
執行效率的提升
評分矩陣通常是一個龐大(有大量的用戶和物品)的稀疏(每個用戶往往只對少量的物品打分)矩陣。在R語言中,我們可以通過專門的數據結構來存儲稀疏矩陣,缺失值不會被重復存儲在內存當中。一般來說,有超過90%的值是缺失的,所以這種做法可以節省下大量的內存。我們的實現以及recommenderlab中都采用了矩陣的稀疏表示。
我們實現的基於用戶的協同過濾主要包含以下步驟(基於物品的協同過濾也是如此):
- 導入評分矩陣
- 開發者決定是否對用戶評分進行標准化。這一步通常會提高准確率。這是因為標准化可以移除用戶評分的偏置,舉例來說就是有些用戶總是會打高分或者總是打低分。
- 計算用戶之間的相似度。
- 使用KNN算法。(只保留k個最相似的用戶,即在用戶的評分預測計算中,相似度矩陣每列只保存最高的k個值)k值需要開發者手動指定。
- 計算預測值並進行反歸一化得到最終的預測評分。
recommenderlab也使用了與上面相同的過程。但是我們在這些過程中引入了一些改進從而顯著地提升了算法執行效率。其中主要的兩個優化如下:
- 對大型稀疏矩陣的相似性計算進行了優化。具體方法可以參考Recommender Systems: Matrix Operations for Fast Calculation of Similarities。
- 相似度矩陣的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個評分。
基於用戶的協同過濾

基於物品的協同過濾

在1M MovieLens 數據集上的比較
該數據集包括6040個用戶和3706個電影(物品),100,000個評分。
基於用戶的協同過濾

基於物品的協同過濾

可以看到我們的實現在運行速度上更快,精准度也更高(達到了更低的rmse)。其中我們最關注的方面——速度得到了顯著的提升。
然而,速度只是經典實現中問題的一個方面。我們在上面提到過,協同過濾的另一個問題是空間占用,即當矩陣過於龐大時我們會面臨內存不足的問題。在下一節中,我們將提出一個可行的方案來使傳統的協同過濾算法可以被應用在龐大的數據集上。
在龐大的數據集上構建推薦算法
在下面的測試中,我們使用MovieLens 10m的數據集。但是正如上面提到的,我們測試的機器只有16GB的內存並且使用了十折的交叉驗證。'recommenderlab'的實現在建立用戶相似度矩陣的過程中就因為內存不足而退出了。
在我們的實現當中,我們通過對矩陣進行切分解決了這一問題。即我們不是一次性計算所有的預測值,而是一塊一塊完成的。下面給出基於用戶的協同過濾的實現過程(基於物品的協同過濾同理):
- 取出用戶評分矩陣的前N行。在下圖圖示中,我們提取了I1:I4部分的切片。
- 取出M個用戶並計算他們與其他用戶的相似度。在下圖圖示中,我們提取了U1:U2部分的切片。
- 根據公式計算第一步得到的矩陣和第二步得到的矩陣的乘積。結果為MxN的矩陣,矩陣的元素為歸一化之前的預測結果。在圖示中,計算結果為用戶U1:U2對物品I1:I4的評分。
- 重復以上三步計算不同的MxN單元只到結果矩陣被填滿。

在10M MovieLens 數據集上的結果
該數據集包括69,878個用戶和10,677個電影(物品),10,000,054個評分。我們通過以下步驟來檢驗我們的算法:
- 10折交叉驗證。
- 中心歸一化(Center Normalization)。
- 用余弦距離來計算相似度。
- k:選取的近鄰樣本數為100,1000。
- Chunk size:在算法當中每次取出的塊的行列大小。具體的取值取決於你的硬件條件。
比較的結果可以從下面的表格找到,包含:
- rmse:算法的誤差(root-mean-square error)
- 執行時間:算法的執行時間,以分鍾為單位。
- num predictions:協同過濾能夠預測的結果數。通常來說,協同過濾不是一定能夠得到預測結果的(比方說與之相似的用戶也都還沒有給該商品打分)
基於物品的協同過濾

基於用戶的協同過濾

正如上圖展示的結果所示,我們實現的算法完滿地完成了任務。現在我們可以在16Gb內存配置的機器上構建推薦系統了。基於用戶和基於物品的協同過濾分別耗費了10分鍾和200分鍾的時間,基於用戶的協同過濾花費了更多的時間是因為數據集中有了更多的用戶,這要求我們計算更多的相似度。
通過現在的實現,當我們需要為一個或者多個用戶提供實時的推薦時,相似度的計算以及結果的預測將迅速很多,因為我們可以只選取少部分用戶進行操作。在MovieLens 10m的數據集上,基於用戶的協同過濾只需要一秒就可以對一個用戶或者多個用戶生成預測,但是基於物品的協同過濾則需要30s左右,這是因為我們需要更多的時間來計算相似度矩陣。這里還可以通過將相似度矩陣存儲為模型,不再進行即時的訓練從而達到線上預測效果的加速。這個算法實現的一個顯著優點就是可擴展性,由於我們將原數據集切分為了不同塊進行計算,所以可以進一步實現並行化。我們接下來的工作之一就是在分布式框架上實現並測試這一方法。
總結
在本文中,我們提出了一種新的方法來改進基於記憶的傳統協同過濾實現。本文的代碼可以從Github上獲取。
問答
相關閱讀
此文已由作者授權騰訊雲+社區發布,原文鏈接:https://cloud.tencent.com/developer/article/1133912?fromSource=waitui