数据集:

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)的更多相关文章

  1. 基于用户的协同过滤电影推荐user-CF python

    协同过滤包括基于物品的协同过滤和基于用户的协同过滤,本文基于电影评分数据做基于用户的推荐 主要做三个部分:1.读取数据:2.构建用户与用户的相似度矩阵:3.进行推荐: 查看数据u.data 主要用到前 ...

  2. 推荐召回--基于用户的协同过滤UserCF

    目录 1. 前言 2. 原理 3. 数据及相似度计算 4. 根据相似度计算结果 5. 相关问题 5.1 如何提炼用户日志数据? 5.2 用户相似度计算很耗时,有什么好的方法? 5.3 有哪些改进措施? ...

  3. Mahout实现基于用户的协同过滤算法

    Mahout中对协同过滤算法进行了封装,看一个简单的基于用户的协同过滤算法. 基于用户:通过用户对物品的偏好程度来计算出用户的在喜好上的近邻,从而根据近邻的喜好推测出用户的喜好并推荐. 图片来源 程序 ...

  4. 【推荐系统实战】:C++实现基于用户的协同过滤(UserCollaborativeFilter)

    好早的时候就打算写这篇文章,可是还是參加阿里大数据竞赛的第一季三月份的时候实验就完毕了.硬生生是拖到了十一假期.自己也是醉了... 找工作不是非常顺利,希望写点东西回想一下知识.然后再攒点人品吧,仅仅 ...

  5. (数据挖掘-入门-3)基于用户的协同过滤之k近邻

    主要内容: 1.k近邻 2.python实现 1.什么是k近邻(KNN) 在入门-1中,简单地实现了基于用户协同过滤的最近邻算法,所谓最近邻,就是找到距离最近或最相似的用户,将他的物品推荐出来. 而这 ...

  6. 案例:Spark基于用户的协同过滤算法

    https://mp.weixin.qq.com/s?__biz=MzA3MDY0NTMxOQ==&mid=2247484291&idx=1&sn=4599b4e31c2190 ...

  7. 基于用户的协同过滤(UserCF)

  8. 基于物品的协同过滤item-CF 之电影推荐 python

    推荐算法有基于协同的Collaboration Filtering:包括 user Based和item Based:基于内容 : Content Based 协同过滤包括基于物品的协同过滤和基于用户 ...

  9. Music Recommendation System with User-based and Item-based Collaborative Filtering Technique(使用基于用户及基于物品的协同过滤技术的音乐推荐系统)【更新】

    摘要: 大数据催生了互联网,电子商务,也导致了信息过载.信息过载的问题可以由推荐系统来解决.推荐系统可以提供选择新产品(电影,音乐等)的建议.这篇论文介绍了一个音乐推荐系统,它会根据用户的历史行为和口 ...

随机推荐

  1. vue href url地址写法

  2. 天天用SpringBoot居然还不知道它的自动装配的原理?

    引言 最近有个读者在面试,面试中被问到了这样一个问题"看你项目中用到了springboot,你说下springboot的自动配置是怎么实现的?"这应该是一个springboot里面 ...

  3. SDNU_ACM_ICPC_2021_Winter_Practice_4th [个人赛]

    传送门 D - Odd Divisor 题意: 给你一个n,问你n是否至少有一个奇数因子(这里题意没说清,没说是不是只有一个还是可以有多个!AC以后才发现是不止一个 思路: 如果这个数没有奇数因子,那 ...

  4. scrapy-redis非多网址采集的使用

    问题描述 默认RedisSpider在启动时,首先会读取redis中的spidername:start_urls,如果有值则根据url构建request对象. 现在的要求是,根据特定关键词采集. 例如 ...

  5. HA工作机制

    HA工作机制 HA:高可用(7*24小时不中断服务) 主要的HA是针对集群的master节点的,即namenode和resourcemanager,毕竟DataNode挂掉之后影响 不是特别大,重启就 ...

  6. (hive)hive优化(转载)

    1. 概述 1.1 hive的特征: 可以通过SQL轻松访问数据的工具,从而实现数据仓库任务,如提取/转换/加载(ETL),报告和数据分析: 它可以使已经存储的数据结构化: 可以直接访问存储在Apac ...

  7. 如何使用Conda源快速安装PyTorch?

    数据科学交流群,群号:189158789,欢迎各位对数据科学感兴趣的小伙伴的加入! 1.切换国内源 1.1.在家目录生成.condarc conda config --set show_channel ...

  8. Centos7部署FytSoa项目至Docker——第一步:安装Docker

    FytSoa项目地址:https://gitee.com/feiyit/FytSoaCms 部署完成地址:http://82.156.127.60:8000/ 先到腾讯云申请一年的云服务器,我买的是一 ...

  9. 浅聊ARP

    今天借用思科公司的Cisco Packet Tracer Student这款软件浅聊ARP 什么是ARP? ARP即地址解析协议(Address Resolution Protocol),是根据Ip地 ...

  10. (7)Linux使用注意事项

    1.Linux 严格区分大小写 和 Windows 不同,Linux 是严格区分大小写的,包括文件名和目录名.命令.命令选项.配置文件设置选项等. 2.Windows 下的程序不能直接在 Linux ...