基于用户的协同过滤的电影推荐算法(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(使用基于用户及基于物品的协同过滤技术的音乐推荐系统)【更新】
摘要: 大数据催生了互联网,电子商务,也导致了信息过载.信息过载的问题可以由推荐系统来解决.推荐系统可以提供选择新产品(电影,音乐等)的建议.这篇论文介绍了一个音乐推荐系统,它会根据用户的历史行为和口 ...
随机推荐
- python zxing包解析二维码报UnicodeDecodeError错误解决办法
一般错误的原因是这个库不支持中文的解码(二维码内容包含中文). 修改如下: 进入zxing.__init__.py代码中,类BarCode下,parse方法中: 找到下面这两行原代码如下: 1 raw ...
- 1.2V转5V稳压芯片,低功耗电路
PW5100具有将低输入电压0.7V-5V之间的范围,升压型,升压到5V的稳定电压输出. 可以使其镍氢电池1.2V稳定输出5V的1.2V转5V芯片. PW5100具有极低的输入静态功耗,1.2V时,应 ...
- Centos7.4 小白式安装(初学)
虚拟机安装Centos7.4系统 适用人群(初学者) 下载Centos7.4镜像 https://pan.baidu.com/s/1NtjfdHV3OWAvfDj5vrR7HQ 提取码:hzzw 虚 ...
- 目标检测的评价指标(TP、TN、FP、FN、Precision、Recall、IoU、mIoU、AP、mAP)
1. TP TN FP FN GroundTruth 预测结果 TP(True Positives): 真的正样本 = [正样本 被正确分为 正样本] TN(True Negatives): 真的 ...
- jQ实现图片无缝轮播
在铺页面的过程中,总是会遇到轮播图需要处理,一般我是会用swiper来制作,但总会有哪个几个个例需要我自己来写功能,这里制作了一个jq用来实现图片无缝轮播的dome,分享给大家ヽ( ̄▽ ̄)ノ. dom ...
- Spring基于注解开发的注解使用之AOP(部分源代码分析)
AOP底层实现动态代理 1.导入spring-aop包依赖 <!--aopV1--> <dependency> <groupId>org.springframewo ...
- Bitter.Core系列四:Bitter ORM NETCORE ORM 全网最粗暴简单易用高性能的 NETCore ORM 之 示例 查询
一: 单表模型驱动查询 如下示例代码演示: // 根据ID 查询: var studentquery = db.FindQuery<TStudentInfo>().QueryById(12 ...
- vue初始化页面闪动问题
使用vue开发时,在vue初始化之前,由于div是不归vue管的,所以我们写的代码在还没有解析的情况下会容易出现花屏现象,看到类似于{{message}}的字样,虽然一般情况下这个时间很短暂,但是我们 ...
- JavaScript this 关键字详解
一.前言 this关键字是JavaScript中最复杂的机制之一.它是一个很特别的关键字,被自动定义在所有函数的作用域中.对于那些没有投入时间学习this机制的JavaScript开发者来说,this ...
- P1663 山
写在前面 简单的二分答案,稍微加点数学计算,很有意思. 算法思路 二分答案可行的原因:答案具有单调性. 这道题目中证明一下:首先无限高显然是能看到任何一个点的,且山的每一条边都是对答案的一个限制,因此 ...