基于SVD协同过滤算法实现的电影推荐系统

这里写图片描述

● 数据获取

将数据集下载并保存在本地
http://files.grouplens.org/datasets/movielens/ml-100k.zip 解压到项目文件下
其中u.data文件包含完整的数据集,README 是对整个数据文件的介绍,从中可以得知u.data中的列依次为:
user id|item id|rating|timestamp 这里的物品是指电影

二、完整代码

◆ 导入机器学习库
from IPython.core.intersectiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = 'all'
%matplotlib inline
import numpy as np
import pandas as pd
header = ['user_id','item_id','rating','timestamp']
src_data = pd.read_csv('./u.data',nep = '\t',names = header) #读取文件路径
src_data.head()                                              #查看文件
1 查看数据总体情况
src_data.discribe()
src_data.user_id.nuinique()  #查看用户去重个数
src_data.item_id.nuinique()  #查看物品去重个数

src_data.duplicated(subset = ['user_id','item_id']).sum()
                             #检查是否有重复的用户物品打分记录2.1 每个用户对应的客户数
item_id_userent = src_data.groupby('item id').count()['user_id']

import matplotlib.pyplot as plt
plt.hist(item_id_userent.values)                #通过直方图观看
plt.plot()

● 2.2 每个物品对应的用户数(10分位,20分位。。。100分位数)
np.arange(0,1.1,0.1)
item_id_userent.quantile(q = np.arange(0,1.1,0.1))

● 3 观察用户-物品矩阵
n_users = src_data.user_id.nuinique()
n_items = src_data.item_id.nuinique()

src_data_matrix = np.zeros({n_users,n_items})    #构建用户物品矩阵
for line in src_data.itertuples():
    src_data_matrix[line[1]-1,line[2]-1 = line[3]]


sparsity = round(len(src_data_matrix.nonzore()\
[1])/float(n_users*n_items),3)                   #矩阵稀疏性
sparsity
————————- 基于item的协同过滤推荐原理 ———————-
1 数据导入
from IPython.core.intersectiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = 'all'
%matplotlib inline
import numpy as np
import pandas as pd
header = ['user_id','item_id','rating','timestamp']
src_data = pd.read_csv('./u.data',nep = '\t',names = header) #读取文件路径
src_data.head()                                              #查看文件2 构建用户-物品数据统计
n_users = src_data.user_id.nuinique()
n_items = src_data.item_id.nuinique()

    #训练集-测试集分离
from sklearn.model_selection import train_test_split
train_data,test_data = train_test_split(src_data,test_size = 0.3) #拆分训练集-测试集

    #训练集-用户-物品矩阵
user_item_matrix = np.zeros(n_users,n_items)
for line in train_data.itertuples():
    user_item_matrix[line[1]-1,line[2]-1 = line[3]]

   #用户相似度矩阵(相似度算法采用余弦算法)
   #使用 sklearn.metrics.pairwise 中的 cosine
from sklearn.metrics.pairwise import pairwise_distances
item_similarity_m = pairwise_distances(user_item_matrix.T,metric = 'cosine')

item_similarity_m.shape                #物品相似度矩阵 行列

round(np.sum(item_similarity_m > 0)/float(item_similarity_m.shape[0]*\
item_similarity_m.shape[1]),3)         #非0值比例

item_similarity_m[0:5,0:5],round(2)    #相似度矩阵为对称矩阵

   #现在只分析上三角 得到等分位数
item_similarity_m_triu = np.triu(item_similarity_m,k = 1)   #对角线0右边的三角矩阵
item_sim_nonzero = np.round(item_similarity_m_triu(item_similarity_m_triu.nonzore()),3)
np.percentile(item_sim_nonzero,np.arange(0,101,10))         #得出相似度大,没有区分性

   #知识讲解:上三角函数 np.triu
arr = np.linspace(1,9,9).reshape(3,3)
np.triu(arr,k = 1)
3 训练集预测
3.1得到预测矩阵
user_item_prediction = user_item_matrix.dot(item_similarity_m)/np.array([item_similarity_m).sum(axis=1)])
 #只取预测数据集中有评分的数据集,进行评估
from sklearn.metrics import mean_squared_error
from math import sqrt
prediction_flatten = user_item_prediction[user_item_matrix.nonzore()]
user_item_matrix_flatten = user_item_matrix[user_item_matrix.nonzore()]
sqrt(mean_squared_error(prediction_flatten,user_item_matrix_flatten))

3.2 测试集预测 
test_data_matrix = np.zeros(n_users,n_items)    #测试数据集构建
for line in test_data.itertuples():
    test_item_matrix[line[1]-1,line[2]-1 = line[3]]

   #预测矩阵
item_prediction = user_item_matrix.dot(item_similarity_m)/np.array\
([item_similarity_m).sum(axis=1)])

   #只取预测数据集中有评分的数据集评估
from sklearn.metrics import mean_squared_error
from math import sqrt
prediction_flatten = item_prediction[test_data_matrix.nonzore()]
test_data_matrix_flatten = test_data_matrix[test_data_matrix.nonzore()]
sqrt(mean_squared_error(prediction_flatten,test_data_matrix_flatten))

3.3 单模型结果提升思路
    #改变相似度算法--余弦近距离->欧式距离
item_similarity_m = pairwise_distances(user_item_matrix.T,metric = 'euclidean')
    #增加训练数据
train_data,test_data = train_test_split(src_data,test_size = 0.2)
——————– 基于SVD的协同过滤推荐原理 ———————-
1.数据导入
from IPython.core.intersectiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = 'all'
%matplotlib inline
import numpy as np
import pandas as pd
header = ['user_id','item_id','rating','timestamp']
src_data = pd.read_csv('./u.data',nep = '\t',names = header) #读取文件路径
src_data.head()     #查看文件2 构建用户-物品数据统计
n_users = src_data.user_id.nuinique()
n_items = src_data.item_id.nuinique()
    #训练集-测试集分离
from sklearn.model_selection import train_test_split
train_data,test_data = train_test_split(src_data,test_size = 0.3)   #拆分训练集-测试集
    #训练集-用户-物品矩阵
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]]
3 SVD矩阵
import scipy.sparse as sp
from scipy.sparse.linalg import svds

    #get SVD components from train matrix.Choose k.
u,s,vt = svds(train_data_matrix,k = 20)
s_diag_matrix = np.diag(s)
svd_prediction = np.dot(np.dot(u,s_diag_matrix),vt)

● 3.1 查看数据
u.shape
s.shape
vt.shape
s_diag_matrix
svd_prediction.shape

    #查看-预测矩阵值分布
pd.Series(np.precentile(svd_prediction,np.arange(0,101,10))).map('{:.2f}'.format)   
    #查看--训练数据-矩阵值分布
pd.Series(np.precentile(train_data_matrix,np.arange(0,101,10))).map('{:.2f}'.format)
    #查看--训练数据-矩阵-非0值分布
pd.Series(np.precentile(train_data_matrix[train_data_matrix,nonzore()]np.arange(0,101,10))).map('{:.2f}'.format)

● 3.2 预测值-限定最大值和最小值
svd_prediction[svd_prediction < 0] = 0          #预测值小于0 则为0
svd_prediction[svd_prediction > 5] = 5          #预测值大于5 则为53.3 RMSE评估--训练集预测
 #只取预测数据集中有评分的数据集,进行评估
from sklearn.metrics import mean_squared_error
from math import sqrt
prediction_flatten = svd_prediction[train_data_matrix.nonzore()]
train_data_matrix_flatten = train_data_matrix[train_data_matrix.nonzore()]
sqrt(mean_squared_error(prediction_flatten,train_data_matrix_flatten))

● 3.4 测试集预测
 #只取预测数据集中有评分的数据集评估
from sklearn.metrics import mean_squared_error
from math import sqrt
prediction_flatten = svd_prediction[test_data_matrix.nonzore()]
test_data_matrix_flatten = test_data_matrix[test_data_matrix.nonzore()]
sqrt(mean_squared_error(prediction_flatten,test_data_matrix_flatten))

● 3.5 单模型结果提升思路
 #1 改变相似度算法--余弦近距离->欧式距离
item_similarity_m = pairwise_distances(user_item_matrix.T,metric = 'euclidean')
 #2 增加训练数据
train_data,test_data = train_test_split(src_data,test_size = 0.2)

猜你喜欢

转载自blog.csdn.net/wsp_1138886114/article/details/80658864