python實現推薦系統(一)

協同過濾分爲  memory-based 和 model based  函數

1. memory-based  利用用戶物品之間類似度進行推薦spa

一種是 item-item 即喜歡這個物品的用戶還喜歡..code

一種是 user-item 即與你有類似愛好的用戶還喜歡..blog

如今有個評分矩陣R,行表示用戶,列表示物品,R(i,j)表示用戶i對物品j的評分,R(:,j)表示全部用戶對物品j的評分列,R(i,:)表示用戶i對全部物品的評分行,用戶與物品沒有交互,評分天然爲0,能夠知道通常的矩陣R是稀疏的。ip

由user-item  計算每一個用戶的類似度,通常取(餘弦類似度),即 cos(R(i,:),R(k,:)),  利用在sklearn中的模塊很容易計算獲得用戶類似矩陣ci

from sklearn.metrics.pairwise import pairwise_distances
user_similarity = pairwise_distances(R, metric='cosine')

由item-item 計算每件商品類似度, it

item_similarity = pairwise_distances(R.T, metric='cosine')

獲得類似度就能夠計算預測矩陣P, 即將用戶與商品之間沒有交互的R(i,j)賦上一個預測值io

先考慮 item-item 咱們能夠知道若是物品m與某個物品b類似度較高,那麼 與b有交互的用戶k對b的評分會很接近於m,最簡單的是m=b,那麼評分相等,能夠給出公式來預估k對m的評分,其中分母起到正則化的做用class

用戶k對物品m的評分預測:分子表示 物品m與其餘全部物品b類似度 與 用戶對其餘物品b 的乘積 的和,至關於加權平均test

考慮user-item  若是兩個用戶類似,天然他們對某個物品評分應該接近,但若是總有些用戶a喜歡給物品評很高的分,這時候即便兩個用戶不類似,按照item-item 的公式,他們也能佔到很高的權重,這就至關於一種干擾,一種噪聲, 這樣,對每一個用戶評分作一個平均,標準化

用戶k對物品m的評分預測:   用戶k對全部物品評分平均+   (用戶k與其餘全部用戶a類似度 與 (其餘用戶a對m的評分-其餘用戶a對全部物品的平均評分)的加權和)/分母

這樣咱們就能夠編寫預測函數

def predict(R, similarity, type='item'):
    if type == 'user':
        mean_user_rating = R.mean(axis=1)# axis=1 計算每行
        rating_d = (R - mean_user_rating[:, np.newaxis]) #np.newaxis根據 R 調整矩陣
        prediction = mean_user_rating[:, np.newaxis] + similarity.dot(rating_d) / np.array([np.abs(similarity).sum(axis=1)]).T
    elif type == 'item':
        prediction = ratings.dot(similarity) / np.array([np.abs(similarity).sum(axis=1)])     
    return prediction

一般咱們還要對預測結果進行評價,有多種評價函數,通常能夠用RMSE(根平均平方偏差)

 天然咱們要拿R的非0值進行比較,計算預測先後的偏差

from sklearn.metrics import mean_squared_errordef rmse(prediction, test_R):
    prediction = prediction[test_R.nonzero()].flatten() 
    test_R= test_R[test_R.nonzero()].flatten()
    return sqrt(mean_squared_error(prediction, test_R))

 

2 model-based  採用矩陣因子分解來近似填充原矩陣

通常來講矩陣R是稀疏的,考慮矩陣計算中的奇異值分解(SVD),經過將其分解成三個矩陣,其中S對角元素稱爲奇異值,經過過濾前k大的奇異值,能夠近似保存原先矩陣的信息,正如一個圖像矩陣,選取合適的k,從新計算獲得的新圖像能夠在感官上與原圖像無差別。

具體公式如

X 是m×n , U 是m×k , S 是 k×k , V.T 是k×n

這樣經過計算就能夠獲得預測矩陣X

import scipy.sparse as sp
from scipy.sparse.linalg import svds
U, s, VT = svds(train_R, k = 15)  #選擇k=15
S=np.diag(s)
X = np.dot(np.dot(U, S), VT)

 本文主要介紹了memory-based 和 model-based的協同過濾方法

相關文章
相關標籤/搜索