项目实战----基于协同过滤的电影推荐系统

2023-11-02


网页版—点击这里

一、数据整理

数据及介绍
MovieLens是推荐系统常用的数据集
MovieLens数据集中,用户对自己看过的电影进行评分,分值为1-5.
MovieLens包括两个大小不同的库。适用于不同规模的算法,
小规模是943个用户对1682部电影做约10000次评分的数据
大规模的是6040个用户对3900部电影做大约100万次评分

导入数据

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
%matplotlib inline
import numpy as np
import pandas as pd

#设置数据列名
header = ["user_id","item_id","rating","timesamp"]
src_data = pd.read_csv("./ml-100k/u.data",sep='\t',names=header)
src_data.head()

查看结构

src_data.info()
src_data.describe()

查看用户去重后的个数

src_data.user_id.nunique()

查看物品去重后的个数

src_data.item_id.nunique()
#检查事都有重复用户物品打分记录
src_data.duplicated(subset=["user_id","item_id"]).sum()
#每一个电影对应的客户数
item_id_usercnt = src_data.groupby("item_id").count()["user_id"]
item_id_usercnt

画图

import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"]=['SimHei']  # 用于正常显示中文标签
plt.rcParams['axes.unicode_minus']=False  # 用来正常显示负号


plt.title('每个物品对应的用户数量')
plt.xlabel("评价的客户数/人")
plt.ylabel("被评论的电影数")
plt.hist(item_id_usercnt.values)

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

#每个用户评价电影的个数
user_id_usercnt = src_data.groupby('user_id').count()["item_id"]
user_id_usercnt.values

import matplotlib.pyplot as plt
#画图
plt.hist(user_id_usercnt.values)
user_id_usercnt.quantile(q=np.arange(0,1.1,step=0.1))

二、观察用户-电影矩阵

n_users = src_data.user_id.nunique()
n_items = src_data.item_id.nunique()
print(n_users)
print(n_items)

构建用户-电影评分矩阵

src_data_matrix = np.zeros((n_users,n_items)) 
# print(src_data_matrix)    产生一个类似的全是0元素的矩阵

#src_data.itertuples()###将DataFrame转为元组##############
for line in src_data.itertuples():
#     print(line)
    src_data_matrix[line[1]-1,line[2]-1] = line[3]   #将电影和评分数给line【3】
#     print(line[3])
src_data_matrix

src_data.itertuples

判断矩阵的稀疏性

sparsity = round(len(src_data_matrix.nonzero() \
					[1])/float(n_users*n_items),3)
sparsity #非常稀疏

三、协同过滤推荐

3.1、基于电影的协同过滤

#使用sklearn.metrics.pairwise中的cosine
from sklearn.metrics.pairwise import pairwise_distances
item_similarity_m = pairwise_distances(src_data_matrix.T,metric="cosine")
item_similarity_m.shape

数据探索
1、电影相似矩阵

#非0值得比例
round(np.sum(item_similarity_m>0)
      /float(item_similarity_m.shape[0]
             *item_similarity_m.shape[1]),3)
#相似矩阵为对称矩阵
item_similarity_m[0:5,0:5].round(2)

#因为是对称的,分析上三角,得到分位数
item_similarity_m_triu = np.triu(item_similarity_m,k=1)
item_sim_nonzero = np.round(item_similarity_m_triu[item_similarity_m_triu.nonzero()],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)
"""

#########预测

# 得到预测矩阵P
user_item_prediction = src_data_matrix.dot(item_similarity_m)/ np.array([np.abs(item_similarity_m).sum(axis=1)])
user_item_prediction

# 只取预测数据集中有评分的数据集,进行评估
from sklearn.metrics import mean_squared_error
from math import sqrt
prediction_flatten = user_item_prediction[src_data_matrix.nonzero()] 
user_item_matrix_flatten = src_data_matrix[src_data_matrix.nonzero()]
sqrt(mean_squared_error(prediction_flatten, user_item_matrix_flatten))

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

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

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


2、单模型结果提升



# 相似度算法指定为欧氏距离
item_similarity_m = pairwise_distances(src_data_matrix.T, metric='euclidean')
item_similarity_m

from sklearn.model_selection import train_test_split
train_data, test_data = train_test_split(src_data, test_size=0.2)

3.2、基于用户的协同过滤推荐

#导入模块
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
import numpy as np
import pandas as pd
header = ['user_id', 'item_id', 'rating', 'timestamp']
src_data = pd.read_csv('ml-100k/u.data', sep='\t', names=header)
src_data.head()

# 用户、物品数统计
n_users = src_data.user_id.nunique()
n_items = src_data.item_id.nunique() 
# 训练集、测试集分离
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] 

1、用户相似度矩阵

#采用余弦距离
from sklearn.metrics.pairwise import pairwise_distances
user_similarity_m = pairwise_distances(train_data_matrix,metric="cosine")

2、数据探索
2.1、用户相似矩阵

#物品相似矩阵,行列
user_similarity_m.shape

#非0 比例
#round四舍五入
round(np.sum(user_similarity_m>0)/float(user_similarity_m.shape[0]
                                        *user_similarity_m.shape[1]),3)

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


#现在我们分析上三角,得到等分位数
user_similarity_m_triu = np.triu(user_similarity_m,k=1)
item_sim_nonzero2 = np.round(user_similarity_m_triu[
            user_similarity_m_triu.nonzero()
            ],3)
np.percentile(item_sim_nonzero2,np.arange(0,101,10))

"""
##############可以看出相似度得分都偏大,相似度没有区分性
"
# 得到预测矩阵P
mean_user_rating = train_data_matrix.mean(axis=1)
ratings_diff = (train_data_matrix - mean_user_rating[:, np.newaxis])   #升维度
user_prediction = mean_user_rating[:, np.newaxis] + \
    user_similarity_m.dot(ratings_diff) / \
    np.array([np.abs(user_similarity_m).sum(axis=1)]).T

2.2、训练数据

from sklearn.metrics import mean_squared_error
from math import sqrt
prediction_flatten = user_prediction[train_data_matrix.nonzero()] 
train_data_matrix_flatten = train_data_matrix[train_data_matrix.nonzero()]
sqrt(mean_squared_error(prediction_flatten, train_data_matrix_flatten))

2.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]

2.4、只取预测数据集中有评分的数据集

from sklearn.metrics import mean_squared_error
from math import sqrt
prediction_flatten = user_prediction[test_data_matrix.nonzero()] 
test_data_matrix_flatten = test_data_matrix[test_data_matrix.nonzero()]
sqrt(mean_squared_error(prediction_flatten, test_data_matrix_flatten))

3、提升

#####相似度算法指定为欧氏距离
user_similarity_m = pairwise_distances(train_data_matrix, \
									metric='euclidean')
train_data, test_data = train_test_split(src_data, test_size=0.2)

###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)
u.shape
s.shape
vt.shape
s_diag_matrix.shape
svd_prediction.shape
"""
(943, 20)
(20,)
(20, 1682)
(20, 20)
(943, 1682)
"""
# 查看预测矩阵值分布
pd.Series(np.percentile(svd_prediction, np.arange(0, 101, 10))).map("{:.2f}".format)
# 查看训练数据矩阵值分布
pd.Series(np.percentile( train_data_matrix, np.arange(0, 101, 10))).map("{:.2f}".format)
# 查看训练数据矩阵非0值分布
pd.Series(np.percentile( train_data_matrix[train_data_matrix.nonzero()],\
				 np.arange(0, 101, 10))).map("{:.2f}".format)

## 预测值限定最小值和最大值
# 将预测值中小于0的值,赋值为0
svd_prediction[svd_prediction<0] = 0
# 将预测值中大于5的值,赋值为5
svd_prediction[svd_prediction>5] = 5

评估

# 只取预测数据集中有评分的数据集,进行评估
from sklearn.metrics import mean_squared_error
from math import sqrt
prediction_flatten = svd_prediction[train_data_matrix.nonzero()] 
train_data_matrix_flatten = train_data_matrix[train_data_matrix.nonzero()]
sqrt(mean_squared_error(prediction_flatten, train_data_matrix_flatten))


# 只取预测数据集中有评分的数据集
from sklearn.metrics import mean_squared_error
from math import sqrt
prediction_flatten = svd_prediction[test_data_matrix.nonzero()] 
test_data_matrix_flatten = test_data_matrix[test_data_matrix.nonzero()]
sqrt(mean_squared_error(prediction_flatten, test_data_matrix_flatten))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

项目实战----基于协同过滤的电影推荐系统 的相关文章

随机推荐

  • 生活中哪些地方运用计算机网络,计算机网络技术在生活中应用.doc

    计算机网络技术在生活中应用 计算机网络技术在生活中应用 摘 要 近年来 计算机网络技术得以飞速发展 也在很大程度上改变了人们的生活方式 它可以说是人类发展历程中的新突破 进入二十一世纪之后 社会逐渐向着网络化的方向发展 计算机网络技术逐渐成
  • 2021水流向何处

    只要房价不涨 不用担心钱被稀释 钱不值钱 说白了就是货更加值钱了 货变贵了 这个货可以是白菜萝卜 可以是汽车 也可以是房子 汽车等工业品明显是更加不值钱 变便宜了 白菜萝卜等需要大量纯粹劳动力的货 是变贵了 但是人民工资水平的上涨能够更上它
  • springboot+mybatis+redis+thymeleaf Web项目搭建 开箱即用

    手动搭建了一个springboot mybatis redis thymeleaf的Web后台项目 因此写篇博客记录下搭建的完整过程 文章最后有完整代码地址 首先简单介绍下用到的技术框架及用途 1 springboot框架 项目主体结构 2
  • 简单递归(最大公约数,阶乘)

    include
  • Centos6.8安装glib-2.32.1

    Centos6 8安装glib 2 32 1遇到的问题及解决方法 1 glib 2 32 1下载网址 http ftp gnome org pub gnome sources glib 2 32 glib 2 32 1 tar xz 2 执
  • OpenWrt系统安全改进<三> --- Web UI密码错误控制

    OpenWrt系统安全改进 lt 二 gt 中所做的尝试 是为了增强用户登录的鉴权机制 密码输错三次就禁用用户一段时间 PAM可以实现对用户登录的控制 但是进一步操作中发现WebUI的登录并没有支持PAM 前功尽弃 了解了一下OpenWrt
  • jmeter 安装部署

    1 软件安装 1 1 Windows安装 1 1 1 软件下载 进入官网 http jmeter apache org 直接下载zip包 下载后直接解压 eg我的解压路径如下 D Program Files apache jmeter 5
  • GitHub拉取报错remote: Support for password authentication was removed on August 13, 2021

    问题描述 今天从GitHub上拉取我自己的私有仓库 结果报错说自21年8月13日后不在支持用户名密码方式验证 如图所示 解决方案 通过查看别人博客原博主以及官网阅读 得知可以通过创建个人访问令牌 personal access token
  • 【附源码】Python小游戏 ——开心消消乐

    目录 前言 开发工具 环境搭建 效果展示 选择关卡首页 游戏界面 过关 代码展示 模块导入 主函数 声音类 树类 元素类 数组类 前言 今天主要是给大家拿牌一个小游戏 开心消消乐 看看有没有小伙伴能够通过呀 开发工具 Python版本 3
  • 网络无法访问互联网是什么原因

    很多用户在使用手机或电脑连接网络时 明明可以正常连接 但却无法访问互联网 网络无法访问互联网是什么意思 无法连接到互联网是指当前只可访问本地网络的资源 没办法正常上外网 访问网页 上 QQ 微信等 网络无法访问互联网是什么原因 网络无法访问
  • Python的Logging模块

    1 日志的相关概念 日志是指记录系统或应用程序运行状态 事件和错误信息的文件或数据 在计算机系统中 日志通常用于故障排除 性能分析 安全审计等方面 日志可以记录各种信息 如系统启动和关闭时间 应用程序的运行状态 用户登录和操作记录 网络通信
  • 6.英文字母排序 (20分)

    题目内容 编写一个程序 当输入不超过 个字符组成的英文文字时 计算机将这个句子中的字母按英文字典字母顺序重新排列 排列后的单词的长度要与原始句子中的长度相同 并且要求只对 到 的字母重新排列 其它字符保持原来的状态 输入描述 一个字符串 包
  • python安装程序已停止工作_python.exe已经停止工作

    昨天 我成功地将sip pyqt4和vtk 包括python的绑定 安装在64位windows7虚拟机上 在 但是 当我执行 import vtk 操作时 会弹出一个对话框 import vtk python exe已经停止工作 在 事件查
  • CGAN原理及tensorflow代码

    1 首先说明一下CGAN的意义 GAN的原始模型有很多可以改进的缺点 首当其中就是 模型不可控 从上面对GAN的介绍能够看出 模型以一个随机噪声为输入 显然 我们很难对输出的结构进行控制 例如 使用纯粹的GAN 我们可以训练出一个生成器 输
  • 关于超过js的number类型最大值(9007199254740992),的解决办法

    bug经过 点击修改无法展示信息 修改时调用queryOne 以id long 为值 页面传过去的id 1480042498255640 00 在数据库中该id 148004249825564012 即错误的id 根本原因 js的numbe
  • DPText-DETR: 基于动态点query的场景文本检测,更高更快更鲁棒

    针对场景文本检测任务 近期基于DEtection TRansformer DETR 框架预测控制点的研究工作较为活跃 在基于DETR的检测器中 query的构建方式至关重要 现有方法中较为粗糙的位置先验信息构建导致了较低的训练效率以及性能
  • MATLAB 图像处理 简单人脸检测(详细,你上你也行)

    1 人脸检测原理框图 整体思路是寻找图片中最大的连通域 将其认定为人脸 第一个环节均值滤波 是为了减弱图像的相关细节部分 以免毛刺影响后期连通域的形成 二值化方便形态学处理 减少运算量 考虑到人脸有黑人和白人黄种人 黑人肤色较深 在二值化之
  • 网络编程中的sockfd是什么?

    2023年5月22日 周一早上 今天早上学习网络编程时遇到了sockfd这个变量 于是学习了一下 顺便写篇博客来记录自己的学习成功 sockfd是什么意思 sock 是socket的缩写 fd 则是file descriptor的缩写 表示
  • 人声频率范围及各频段音色效果

    国际制定的数字电话机的通信标准是300 3400Hz这是 3db标准 也就是说300HZ和3400HZ的传输电压幅度降低到正常的0 707倍 并不是一过这两个频率电压就完全消失了 现实中也做不到如此精确的滤波电路 人讲话的频率主要集中在1
  • 项目实战----基于协同过滤的电影推荐系统

    文章目录 一 数据整理 二 观察用户 电影矩阵 三 协同过滤推荐 3 1 基于电影的协同过滤 3 2 基于用户的协同过滤推荐 网页版 点击这里 一 数据整理 数据及介绍 MovieLens是推荐系统常用的数据集 MovieLens数据集中