python實現推薦系統
兩種最普遍的推薦系統的類型是基于內容和協同過濾(CF)。協同過濾基于用戶對產品的態度產生推薦,基于內容的推薦系統基于物品屬性的相似性進行推薦。CF可以分為基于內存的協同過濾和基于模型的協同過濾。
我們將使用MovieLens數據集,它是在實現和測試推薦引擎時所使用的最常見的數據集之一,包含來自943個用戶以及精選的1682部電影的評分。
導入numpy和pandas庫
import numpy as np
import pandas as pd
讀入u.data數據文件
header = ['user_id', 'item_id', 'rating', 'timestamp']
df = pd.read_csv('u.data', sep = '\t', names = header)
查看用戶和電影的數量
n_users = df.user_id.unique().shape[0]
n_items = df.item_id.unique().shape[0]
print 'Number of users = ' + str(n_users) + ' | Number of movies = ' + str(n_items)
Number of users = 943 | Number of movies = 1682
使用scikit-learn庫將數據集分割成測試集和訓練集,調用 Cross_validation.train_test_split 根據測試樣本的比例(test_size)將數據混洗并分割成兩個數據集。
from sklearn import cross_validation as cv
train_data,test_data = cv.train_test_split(df, test_size = 0.25)
##基于內存的協同過濾
基于內存的協同過濾方法可以分為兩個部分:用戶-產品協同過濾和產品-產品協同過濾。用戶-產品協同過濾將選取一個特定的用戶,基于打分的相似性發現類似于該用戶的用戶,并推薦那些相似用戶喜歡的產品。產品-產品協同過濾會選取一個產品,發現喜歡該產品的用戶,并找到這些相似用戶還喜歡的其它產品。
用戶-產品協同過濾:“喜歡這東西的人也喜歡……”
產品-產品協同過濾:“像你一樣的人也喜歡……”
在這兩種情況下,從整個數據集構建一個用戶產品矩陣。
用戶產品矩陣的例子:
計算相似性,并創建一個相似性矩陣。
在產品-產品協同過濾中的產品之間的相似性是通過觀察所有對兩個產品打分的用戶來度量的。
在用戶-產品協同過濾中的用戶之間的相似性是通過觀察所有同時被兩個用戶打分的產品來度量的。
通常用于推薦系統中的距離矩陣是余弦相似性,其中,打分被看成n維空間中的向量,而相似性是基于這些向量之間的角度進行計算的。用戶a和m的余弦相似性可以用下面的公式進行計算:
要計算產品m和b之間的相似性,使用公式:
創建用戶產品矩陣,針對測試數據和訓練數據,創建兩個矩陣:
train_data_matrix = np.zeros((n_users,n_items))
for line in train_data.itertuples():
train_data_matrix[line[1]-1, line[2]-1] = line[3]
test_data_matrix = np.zeros((n_users, n_items))
for line in test_data.itertuples():
test_data_matrix[line[1]-1, line[2]-1] = line[3]
使用sklearn的pairwise_distances函數來計算余弦相似性。
from sklearn.metrics.pairwise import pairwise_distances
user_similarity = pairwise_distances(train_data_matrix, metric = "cosine")
item_similarity = pairwise_distances(train_data_matrix.T, metric = "cosine")
已經創建了相似性矩陣:user_similarity和item_similarity,因此,可以通過基于用戶的CF應用下面的公式做出預測:
可以將用戶k和用戶a之間的相似性看成權重,乘以相似用戶a(校正的平均評分用戶)的評分,這里需要規范化該值,使得打分位于1到5之間,最后對嘗試預測的用戶的平均評分求和。
基于產品的CF應用下面的公司進行預測,此時無需糾正用戶的平均打分
def predict(rating, similarity, type = 'user'):
if type == 'user':
mean_user_rating = rating.mean(axis = 1)
rating_diff = (rating - mean_user_rating[:,np.newaxis])
pred = mean_user_rating[:,np.newaxis] + similarity.dot(rating_diff) / np.array([np.abs(similarity).sum(axis=1)]).T
elif type == 'item':
pred = rating.dot(similarity) / np.array([np.abs(similarity).sum(axis=1)])
return pred
item_prediction = predict(train_data_matrix, item_similarity, type ='item')
user_prediction = predict(train_data_matrix, user_similarity, type ='user')
####評估
這里采用均方根誤差(RMSE)來度量預測評分的準確性
可以使用sklearn的mean_square_error(MSE)函數,其中RMSE僅僅是MSE的平方根。
from sklearn.metrics import mean_squared_error
from math import sqrt
defrmse(prediction, ground_truth):
prediction = prediction[ground_truth.nonzero()].flatten()
ground_truth = ground_truth[ground_truth.nonzero()].flatten()
return sqrt(mean_squared_error(prediction, ground_truth))
print 'User based CF RMSE: ' + str(rmse(user_prediction, test_data_matrix))
print 'Item based CF RMSe: ' + str(rmse(item_prediction, test_data_matrix))
User basedCF RMSE: 3.12466203536
Item basedCF RMSe: 3.45056350625
可以看出,基于內存的算法很容易實現并產生合理的預測質量。
##基于模型的協同過濾
基于模型的協同過濾是基于矩陣分解(MF)的,矩陣分解廣泛應用于推薦系統中,它比基于內存的CF有更好的擴展性和稀疏性。MF的目標是從已知的評分中學習用戶的潛在喜好和產品的潛在屬性,隨后通過用戶和產品的潛在特征的點積來預測未知的評分。
計算MovieLens數據集的稀疏度:
sparsity = round(1.0 - len(df) / float(n_users*n_items),3)
print 'The sparsity level of MovieLen100K is ' + str(sparsity * 100) + '%'
The sparsity level of MovieLen100K is 93.7%
###SVD
一般的方程可以表示為:
給定m * n矩陣X:
U 是一個(m * r)正交矩陣
S 是一個對角線上為非負實數的(r * r)對角矩陣
V^T是一個(r * n)正交矩陣
S的對角線上的元素被稱為X的奇異值。
陣X可以被分解成U,S和V。U矩陣表示對應于隱藏特性空間中的用戶的特性矩陣,而V矩陣表示對應于隱藏特性空間中的產品的特性矩陣。
現在,可以通過U, S和V^T的點積進行預測了:
import scipy.sparse as sp
from scipy.sparse.linalg import svds
u, s, vt = svds(train_data_matrix, k = 20)
s_diag_matrix = np.diag(s)
x_pred = np.dot(np.dot(u,s_diag_matrix),vt)
print 'User-based CF MSE: ' + str(rmse(x_pred, test_data_matrix))
User-basedCF MSE: 2.72035726617
總結:
實現了簡單的協同過濾方法,包括基于內存的CF和基于模型的CF
基于內存的模型是基于產品或用戶之間的相似性,這里采用余弦相似性。
基于模型的CD是基于矩陣分解,采用SVD來分解矩陣
標準的協同過濾方法在面對冷啟動的情況時表現不佳。
來自:https://jlunevermore.github.io/2016/06/25/36.python實現推薦系統/