基于用户的协同过滤的电影推荐算法(tensorflow)
数据集:
https://grouplens.org/datasets/movielens/
ml-latest-small
协同过滤算法理论基础
https://blog.csdn.net/u012995888/article/details/79077681
相似度计算主要有三个经典算法:余弦定理相似性度量、欧氏距离相似度度量和杰卡德相似性度量。下面分别进行说明:
余弦定理相似性度量
       三角形余弦定理公式:,由该公式可知角A越小,bc两边越近。当A为0度时,bc两边完全重合。
当bc两边为向量时,两个向量的余弦为:;
当存在多个向量时,多个向量的余弦为:
由上求余弦的向量公式,可得知当两个向量的夹角越小,两个向量方向越相近。当夹角为0时,两个向量方向完全重合。由此原理可以计算两个事物的相似度。比如,把一篇篇新闻提取成有效词语的向量,每一组有效词语向量的角度越小,则两篇新闻的相似程度越高。如下图,为了便于理解举个特例,假设新闻ABC三篇文章提取的关键字都是诗歌、李白、杜甫、王勃,并且对应文章出现的数量分别为[(诗歌,1)(李白,1)(杜甫,1)(王勃,1)]、[(诗歌,2)(李白,2)(杜甫,2)(王勃,2)]和[(诗歌,1)(李白,2)(杜甫,3)(王勃,4)]。从坐标图可以看出AB的相似度大于AC或者BC的相似度,AB的各关键字比例一样,而C相比AB更侧重诗人王勃的话题。
观察上图,你会发现新闻D和新闻A、B的相似度是一样的。这个就是余弦定理计算相似度的缺陷,因为余弦定理只关注向量的方向,并不关注向量的起始点。
欧氏距离相似性度量
       与余弦定理通过方向度量相似度不同,欧氏距离是通过计算样本实际距离在度量相似度的。
二维平面上两点a(x1,y1)与b(x2,y2)间的欧氏距离:;
三维空间两点a(x1,y1,z1)与b(x2,y2,z2)间的欧氏距离:
两个n维向量a(x11,x12,…,x1n)与 b(x21,x22,…,x2n)间的欧氏距离:
把上例的几个点代入以上公式可以算出:AB欧氏距离为√4,AC欧氏距离为√14,AD欧氏距离为√10,BC欧氏距离为√6,BD欧氏距离为√10,CD欧氏距离√30。欧氏距离越短,n微向量越“近”,向量化的物品的相似度越高。通过比较,依旧是AB的相似度最高。
提示:对比余弦定理相似度度量与欧氏距离相似度度量:
欧氏距离能够体现个体数值特征的绝对差异,所以更多的用于需要从维度的数值大小中体现差异的分析,如使用用户行为指标分析用户价值的相似度或差异。
余弦距离更多的是从方向上区分差异,而对绝对的数值不敏感,更多的用于使用用户对内容评分来区分兴趣的相似度和差异,同时修正了用户间可能存在的度量标准不统一的问题(因为余弦距离对绝对数值不敏感)。
杰卡德相似性度量
       两个集合的交集在该两个集合的并集所占的比例来度量两个集合的相似度。举例,新闻A和新闻B提取出词语集合的交集在新闻A和新闻B提取出词语集合的并集所占的比例就是AB的相似度。
协同过滤算法实现
参考:https://blog.csdn.net/sinat_38682860/article/details/80486992
基于用户的协同过滤算法[UserCF]
       案例背景:根据电影点评网站数据,给目标用户推荐电影。
思路步骤:
计算其他用户和目标用户的相似度(使用欧氏距离算法);
根据相似度的高低找出K个目标用户最相似的邻居;
在这些邻居喜欢的电影中,根据邻居与你的远近程度算出每个电影的推荐度;
根据每一件物品的推荐度高低给你推荐物品。
代码:
# -*- coding: utf-8 -*-
"""
Created on Sat Jul 13 17:24:33 2019
@author: Erio
""" #协同过滤
import pandas as pd
import numpy as np
import tensorflow as tf ratings_df = pd.read_csv('C:/Users/lenovo/Desktop/ml-latest-small/ml-latest-small/ratings.csv')
#print(ratings_df.tail())
#tail命令用于输入文件中的尾部内容。tail命令默认在屏幕上显示指定文件的末尾5行。 movies_df = pd.read_csv('C:/Users/lenovo/Desktop/ml-latest-small/ml-latest-small/movies.csv')
#print(movies_df.tail()) movies_df['movieRow'] = movies_df.index
#生成一列‘movieRow’,等于索引值index
#print(movies_df.tail()) movies_df = movies_df[['movieRow','movieId','title']]
#筛选三列出来
movies_df.to_csv('C:/Users/lenovo/Desktop/ml-latest-small/ml-latest-small/moviesProcessed.csv', index=False, header=True, encoding='utf-8')
#生成一个新的文件moviesProcessed.csv
#print(movies_df.tail()) ratings_df = pd.merge(ratings_df, movies_df, on='movieId')
#print(ratings_df.head()) ratings_df = ratings_df[['userId','movieRow','rating']]
#筛选出三列
ratings_df.to_csv('C:/Users/lenovo/Desktop/ml-latest-small/ml-latest-small/ratingsProcessed.csv', index=False, header=True, encoding='utf-8')
#导出一个新的文件ratingsProcessed.csv
#print(ratings_df.head()) userNo = ratings_df['userId'].max() + 1
#userNo的最大值
movieNo = ratings_df['movieRow'].max() + 1
#movieNo的最大值 rating = np.zeros((movieNo,userNo))
#创建一个值都是0的数据
flag = 0
ratings_df_length = np.shape(ratings_df)[0]
#查看矩阵ratings_df的第一维度是多少
for index,row in ratings_df.iterrows():
#interrows(),对表格ratings_df进行遍历
rating[int(row['movieRow']),int(row['userId'])] = row['rating']
#将ratings_df表里的'movieRow'和'userId'列,填上row的‘评分’
flag += 1 record = rating > 0
record
record = np.array(record, dtype = int)
#更改数据类型,0表示用户没有对电影评分,1表示用户已经对电影评分
record
#print(record) def normalizeRatings(rating, record):
m, n =rating.shape
#m代表电影数量,n代表用户数量
rating_mean = np.zeros((m,1))
#每部电影的平均得分
rating_norm = np.zeros((m,n))
#处理过的评分
for i in range(m):
idx = record[i,:] !=0
#每部电影的评分,[i,:]表示每一行的所有列
rating_mean[i] = np.mean(rating[i,idx])
#第i行,评过份idx的用户的平均得分;
#np.mean() 对所有元素求均值
rating_norm[i,idx] -= rating_mean[i]
#rating_norm = 原始得分-平均得分
return rating_norm, rating_mean rating_norm, rating_mean = normalizeRatings(rating, record) rating_norm =np.nan_to_num(rating_norm)
#对值为NaNN进行处理,改成数值0
rating_norm rating_mean =np.nan_to_num(rating_mean)
#对值为NaNN进行处理,改成数值0
rating_mean num_features = 10
X_parameters = tf.Variable(tf.random_normal([movieNo, num_features],stddev = 0.35))
Theta_parameters = tf.Variable(tf.random_normal([userNo, num_features],stddev = 0.35))
#tf.Variables()初始化变量
#tf.random_normal()函数用于从服从指定正太分布的数值中取出指定个数的值,mean: 正态分布的均值。stddev: 正态分布的标准差。dtype: 输出的类型 loss = 1/2 * tf.reduce_sum(((tf.matmul(X_parameters, Theta_parameters, transpose_b = True) - rating_norm) * record) ** 2) + 1/2 * (tf.reduce_sum(X_parameters ** 2) + tf.reduce_sum(Theta_parameters ** 2))
#基于内容的推荐算法模型 optimizer = tf.train.AdamOptimizer(1e-4)
# https://blog.csdn.net/lenbow/article/details/52218551
train = optimizer.minimize(loss)
# Optimizer.minimize对一个损失变量基本上做两件事
# 它计算相对于模型参数的损失梯度。
# 然后应用计算出的梯度来更新变量。 # tf.summary的用法 https://www.cnblogs.com/lyc-seu/p/8647792.html
tf.summary.scalar('loss',loss)
#用来显示标量信息 summaryMerged = tf.summary.merge_all()
#merge_all 可以将所有summary全部保存到磁盘,以便tensorboard显示。
filename = './movie_tensorborad'
writer = tf.summary.FileWriter(filename)
#指定一个文件用来保存图。
sess = tf.Session()
#https://www.cnblogs.com/wuzhitj/p/6648610.html
init = tf.global_variables_initializer()
sess.run(init)
#运行 for i in range(5000):
_, movie_summary = sess.run([train, summaryMerged])
# 把训练的结果summaryMerged存在movie里
writer.add_summary(movie_summary, i)
# 把训练的结果保存下来 #评估模型
Current_X_parameters, Current_Theta_parameters = sess.run([X_parameters, Theta_parameters])
# Current_X_parameters为用户内容矩阵,Current_Theta_parameters用户喜好矩阵
predicts = np.dot(Current_X_parameters,Current_Theta_parameters.T) + rating_mean
# dot函数是np中的矩阵乘法,np.dot(x,y) 等价于 x.dot(y)
errors = np.sqrt(np.sum((predicts - rating)**2))
# sqrt(arr) ,计算各元素的平方根
#print(errors) #3772.2766689811433 #这里user_id改为input就可以实现任意推荐了
user_id = 15
sortedResult = predicts[:, int(user_id)].argsort()[::-1]
# argsort()函数返回的是数组值从小到大的索引值; argsort()[::-1] 返回的是数组值从大到小的索引值
idx = 0
print('为该用户推荐的评分最高的10部电影是:'.center(80,'='))
# center() 返回一个原字符串居中,并使用空格填充至长度 width 的新字符串。默认填充字符为空格。
for i in sortedResult:
print('评分: %.2f, 电影名: %s' % (predicts[i,int(user_id)],movies_df.iloc[i]['title']))
# .iloc的用法:https://www.cnblogs.com/harvey888/p/6006200.html
idx += 1
if idx == 10:break
效果:

基于用户的协同过滤的电影推荐算法(tensorflow)的更多相关文章
- 基于用户的协同过滤电影推荐user-CF  python
		
协同过滤包括基于物品的协同过滤和基于用户的协同过滤,本文基于电影评分数据做基于用户的推荐 主要做三个部分:1.读取数据:2.构建用户与用户的相似度矩阵:3.进行推荐: 查看数据u.data 主要用到前 ...
 - 推荐召回--基于用户的协同过滤UserCF
		
目录 1. 前言 2. 原理 3. 数据及相似度计算 4. 根据相似度计算结果 5. 相关问题 5.1 如何提炼用户日志数据? 5.2 用户相似度计算很耗时,有什么好的方法? 5.3 有哪些改进措施? ...
 - Mahout实现基于用户的协同过滤算法
		
Mahout中对协同过滤算法进行了封装,看一个简单的基于用户的协同过滤算法. 基于用户:通过用户对物品的偏好程度来计算出用户的在喜好上的近邻,从而根据近邻的喜好推测出用户的喜好并推荐. 图片来源 程序 ...
 - 【推荐系统实战】:C++实现基于用户的协同过滤(UserCollaborativeFilter)
		
好早的时候就打算写这篇文章,可是还是參加阿里大数据竞赛的第一季三月份的时候实验就完毕了.硬生生是拖到了十一假期.自己也是醉了... 找工作不是非常顺利,希望写点东西回想一下知识.然后再攒点人品吧,仅仅 ...
 - (数据挖掘-入门-3)基于用户的协同过滤之k近邻
		
主要内容: 1.k近邻 2.python实现 1.什么是k近邻(KNN) 在入门-1中,简单地实现了基于用户协同过滤的最近邻算法,所谓最近邻,就是找到距离最近或最相似的用户,将他的物品推荐出来. 而这 ...
 - 案例:Spark基于用户的协同过滤算法
		
https://mp.weixin.qq.com/s?__biz=MzA3MDY0NTMxOQ==&mid=2247484291&idx=1&sn=4599b4e31c2190 ...
 - 基于用户的协同过滤(UserCF)
 - 基于物品的协同过滤item-CF 之电影推荐 python
		
推荐算法有基于协同的Collaboration Filtering:包括 user Based和item Based:基于内容 : Content Based 协同过滤包括基于物品的协同过滤和基于用户 ...
 - Music Recommendation System with User-based and  Item-based Collaborative Filtering Technique(使用基于用户及基于物品的协同过滤技术的音乐推荐系统)【更新】
		
摘要: 大数据催生了互联网,电子商务,也导致了信息过载.信息过载的问题可以由推荐系统来解决.推荐系统可以提供选择新产品(电影,音乐等)的建议.这篇论文介绍了一个音乐推荐系统,它会根据用户的历史行为和口 ...
 
随机推荐
- Flask源码流程分析(一)
			
Flask源码流程分析: 1.项目启动: 1.实例化Flask对象 1. 重要的加载项: * url_rule_class = Rule * url_map_class = Map * session ...
 - ORB-SLAM2-tracking线程
			
tracking线程 Tracking线程的主要工作是从图像中提取ORB特征,根据上一帧进行姿态估计或者进行通过全局重定位初始化位姿,然后跟踪已经重建的局部地图,优化位姿,再根据一些规则确定新的关键帧 ...
 - 代码托管从业者 Git 指南
			
本文作者:李博文 - CODING 后端开发工程师 前言 六七年前,我机缘巧合进入了代码托管行业,做过基于 Git 支持 SVN 客户端接入.Git 代码托管平台分布式.Git 代码托管读写分离.Gi ...
 - java基础-01代理类
			
简单的代理类实现案例主实现类:ProxyTestimport java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;im ...
 - (Oracle)索引实战(转载)
			
人们在使用SQL时往往会陷入一个误区,即太关注于所得的结果是否正确,而忽略了不同的实现方法之间可能存在的性能差异,这种性能差异在大型的或是复杂的数据库环境中(如联机事务处理OLTP或决策支持系统DSS ...
 - 使用Robo 3T访问MongoDB数据库
			
使用Robo 3T操作MongoDB数据库教程:https://blog.csdn.net/baidu_39298625/article/details/99654596 在IDEA中用三个jar包链 ...
 - noip 注意事项 (个人向)
			
目录 非常重要 对拍 空间 极限数据 模数,YES/NO等大小写 个人 考场 神仙 czdzx 说要写,我也来写 非常重要 对拍 空间 极限数据 模数,YES/NO等大小写 个人 养身体,不要紧张,不 ...
 - 【ElasticSearch】 使用AWS云ES服务来分析程序日志
			
最近公司系统升级,有些API的调用接口达到了每天10几万的请求量.目前公司里的日志,都是写文本文件中的.为了能够更好的分析这些日志数据,公司采用了AWS 的 ElasticSearch服务来分析日志. ...
 - 解决 ThinkPHP5 RCE 在PHP7下,不能使用包含的问题
			
今天朋友遇到一个ThinkPHP5 _method 的RCE漏洞,环境是:tp5014开启debug,linux,PHP7,日志,Session都写不进去,没办法包含的情况. 思路就是使用反序列化,回 ...
 - Docker容器启动Mysql,Docker实现Mysql主从,读写分离
			
Docker容器启动Mysql,Docker实现Mysql主从,读写分离 一.Docker文件编排 二.配置主从复制 2.1 配置master 2.2 配置slave 三.验证主从复制 3.1 mas ...