推荐系统学习(一)--电影推荐系统搭建
1. 推荐系统的架构
本文采用的数据集来源于Netflix用户电影评分数据,实现一个简单的基于用户的协同过滤推荐系统,其中采用皮尔逊系数衡量两个用户之间的相似度。
数据集地址
使用到的数据文件:
2. 数据的预处理
由于数据量过大,这里仅选择原数据集中的1000个用户及其评分数据进行推荐算法的简单实现,否则在单机上难以运行(仅1000个用户数据的处理时间已经达到了数十分钟)。
首先选择1000个用户:
def __selectSomeUsers(self):print("随机选择1000个用户")if os.path.exists("data/train.json") and os.path.exists("data/test.json"):return list()else:users = set()for file in os.listdir(self.file_path):one_path = "{}/{}".format(self.file_path, file)print("{}".format(one_path))with open(one_path, "r") as fp:for line in fp.readlines():if line.strip().endswith(":"):continueuserID,_,_ = line.split(",")users.add(userID)some_users = random.sample(list(users),1000)print(some_users)return some_users
然后加载评分数据信息并分割训练集和测试集:
# 加载并拆分数据def _load_and_split_data(self):train = dict()test = dict()if os.path.exists("data/train.json") and os.path.exists("data/test.json"):print("从文件中加载数据集")train = json.load(open("data/train.json"))test = json.load(open("data/test.json"))print("数据加载完成")else:i=0random.seed(self.seed)for file in os.listdir(self.file_path):one_path = "{}/{}".format(self.file_path, file)print("{}".format(one_path))with open(one_path, "r") as fp:movieID = fp.readline().split(":")[0]print("movie ID:"+movieID)for line in fp.readlines():if line.strip().endswith(":"):movieID = line.split(":")[0]print("movie ID:"+movieID)continueuserID, rate, _ = line.split(",")if(userID in self.some_users):if random.randint(1,50) == 1:test.setdefault(userID,{})[movieID] = int(rate)else:train.setdefault(userID, {})[movieID] = int(rate)print("加载数据到 data/train.json data/test/json")json.dump(train,open("data/train.json","w"))json.dump(test,open("data/test.json","w"))print("数据加载完成")return train,test
3. 计算用户相似度
这里采用皮尔逊系数进行计算,采用其近似计算如下:
r′=∑i=1nxiyi−∑i=1nxi∑i=1nyin∑i=1nxi2−(∑i=1nxi)2n∑i=1nyi2−(∑i=1nyi)2nr'=\frac{\sum_{i=1}^{n}x_iy_i-\frac{\sum_{i=1}^{n}x_i\sum_{i=1}^{n}y_i}{n}} {\sqrt{\sum_{i=1}^{n}x_i^2- \frac{ \left( \sum_{i=1}^{n}x_i \right)^2 }{n}} \sqrt{\sum_{i=1}^{n}y_i^2- \frac{ \left( \sum_{i=1}^{n}y_i \right)^2 }{n} }}r′=∑i=1nxi2−n(∑i=1nxi)2∑i=1nyi2−n(∑i=1nyi)2∑i=1nxiyi−n∑i=1nxi∑i=1nyi
def pearson(self, rating1, rating2):sum_xy = 0sum_x = 0sum_y = 0sum_x2 = 0sum_y2 = 0num = 0for key in rating1.keys():if key in rating2.keys():num += 1x = rating1[key]y = rating2[key]sum_xy += x * ysum_x += xsum_y += ysum_x2 += math.pow(x,2)sum_y2 += math.pow(y,2)if num == 0:return 0denominator = math.sqrt( sum_x2 - math.pow(sum_x,2) / num) * math.sqrt( sum_y2 - math.pow(sum_y,2) / num)if denominator == 0:return 0else:return (sum_xy - (sum_x * sum_y) / num) / denominator
4. 基于协同过滤进行推荐
即采用KNN寻找用户user的k个近邻并进行排序,并选择其中评分较高的n个电影,推荐给当前用户即可。
def recommend(self,userID):neighborUser = dict()for user in self.train.keys():if userID != user:distance = self.pearson(self.train[userID], self.train[user])neighborUser[user] = distancenewNU = sorted(neighborUser.items(), key= lambda k:k[1],reverse=True)movies = dict()for (sim_user,sim) in newNU[:self.k]:for movieID in self.train[sim_user].keys():movies.setdefault(movieID,0)movies[movieID] += sim * self.train[sim_user][movieID]newMovies = sorted(movies.items(),key=lambda k:k[1],reverse=True)return newMovies
代码附录:
import os
import json
import random
import mathclass FisrtRec:"""初始化函数file_path: 数据文件路径seed: 随机数种子k: 选取的近邻个数n_items: 推荐的电影数量"""def __init__(self, file_path, seed, k, n_items):self.file_path = file_pathself.seed = seedself.k = kself.n_items = n_itemsself.some_users = self.__selectSomeUsers()self.train,self.test = self._load_and_split_data()def __selectSomeUsers(self):print("随机选择1000个用户")if os.path.exists("data/train.json") and os.path.exists("data/test.json"):return list()else:users = set()for file in os.listdir(self.file_path):one_path = "{}/{}".format(self.file_path, file)print("{}".format(one_path))with open(one_path, "r") as fp:for line in fp.readlines():if line.strip().endswith(":"):continueuserID,_,_ = line.split(",")users.add(userID)some_users = random.sample(list(users),1000)print(some_users)return some_users# 加载并拆分数据def _load_and_split_data(self):train = dict()test = dict()if os.path.exists("data/train.json") and os.path.exists("data/test.json"):print("从文件中加载数据集")train = json.load(open("data/train.json"))test = json.load(open("data/test.json"))print("数据加载完成")else:i=0random.seed(self.seed)for file in os.listdir(self.file_path):one_path = "{}/{}".format(self.file_path, file)print("{}".format(one_path))with open(one_path, "r") as fp:movieID = fp.readline().split(":")[0]print("movie ID:"+movieID)for line in fp.readlines():if line.strip().endswith(":"):movieID = line.split(":")[0]print("movie ID:"+movieID)continueuserID, rate, _ = line.split(",")if(userID in self.some_users):if random.randint(1,50) == 1:test.setdefault(userID,{})[movieID] = int(rate)else:train.setdefault(userID, {})[movieID] = int(rate)print("加载数据到 data/train.json data/test/json")json.dump(train,open("data/train.json","w"))json.dump(test,open("data/test.json","w"))print("数据加载完成")return train,testdef pearson(self, rating1, rating2):sum_xy = 0sum_x = 0sum_y = 0sum_x2 = 0sum_y2 = 0num = 0for key in rating1.keys():if key in rating2.keys():num += 1x = rating1[key]y = rating2[key]sum_xy += x * ysum_x += xsum_y += ysum_x2 += math.pow(x,2)sum_y2 += math.pow(y,2)if num == 0:return 0denominator = math.sqrt( sum_x2 - math.pow(sum_x,2) / num) * math.sqrt( sum_y2 - math.pow(sum_y,2) / num)if denominator == 0:return 0else:return (sum_xy - (sum_x * sum_y) / num) / denominatordef recommend(self,userID):neighborUser = dict()for user in self.train.keys():if userID != user:distance = self.pearson(self.train[userID], self.train[user])neighborUser[user] = distancenewNU = sorted(neighborUser.items(), key= lambda k:k[1],reverse=True)movies = dict()for (sim_user,sim) in newNU[:self.k]:for movieID in self.train[sim_user].keys():movies.setdefault(movieID,0)movies[movieID] += sim * self.train[sim_user][movieID]newMovies = sorted(movies.items(),key=lambda k:k[1],reverse=True)return newMoviesdef evaluate(self,num=100):print("评估准确率")precisions = list()random.seed(10)for userID in random.sample(self.test.keys(),num):hit = 0result = self.recommend(userID)[:self.n_items]for(item,rate) in result:if item in self.test[userID]:hit+=1precisions.append(hit/self.n_items)return sum(precisions) / precisions.__len__()if __name__ == "__main__":file_path = "C:\\Users\\Mr.Throne\\Desktop\\推荐系统\\archive\\data"seed = 30k = 10n_items = 5f_rec = FisrtRec(file_path,seed,k,n_items)# result = f_rec.recommend("968796")print("算法推荐准确率:{}".format(f_rec.evaluate()))
推荐系统学习(一)--电影推荐系统搭建相关推荐
- hadoop学习-Netflix电影推荐系统
1.推荐系统概述 电子商务网站是推荐系统应用的重要领域之一,当当网的图书推荐,大众点评的美食推荐,QQ好友推荐等等,推荐无处不在. 从企业角度,推荐系统的应用可以增加销售额等等,对于用户而言,系统仿佛 ...
- 《推荐系统学习》之推荐系统那点事
转载自:http://www.admin10000.com/document/4995.html 推荐系统的误区 回想起来,我也算是国内接触推荐系统较早的人之一了,最近和人聊天,觉得不少人对推荐系统有 ...
- springboot基于JAVA的电影推荐系统的开发与实现毕业设计源码112306
目 录 摘要 Abstract 第1章前言 1.1研究背景 1.2研究现状 1.3系统开发目标 第2章技术与原理 2.1 JSP介绍 2.2 JAVA技术 2.3 MySQL数据库 2.4 ...
- (附源码)springboot基于JAVA的电影推荐系统的开发与实现 毕业设计112306
目 录 摘 要 4 Abstract 5 第1章 前 言 6 1.1 研究背景 6 1.2 研究现状 6 1.3 系统开发目标 6 第2章 技术与原理 8 2.1 JSP介绍 8 2.2 JAVA技术 ...
- springboot基于JAVA的电影推荐系统的开发与实现 附源码-毕业设计112306
目 录 摘要 4 Abstract 5 第1章前言 6 1.1研究背景 6 1.2研究现状 6 1.3系统开发目标 6 第2章技术与原理 8 2.1 JSP介绍 8 2.2 JAVA技术 8 ...
- python推荐系统-基于Python的推荐系统的设计与实现
张玉叶 摘 要: 大数据时代的推荐系统可以帮助用户从海量信息中高效地获取自己的潜在需求,是大数据在互联网领域的典型应用.文章介绍了利用Python语言实现的一个基于物品的协同过滤算法推荐系统,给出了 ...
- 毕业设计 - 题目:推荐系统构建和应用 推荐系统
文章目录 0 前言 1 什么是推荐系统 2 毕业设计 - 能做哪些推荐系统? 2.1 电商推荐系统 2.3 电影推荐系统 2.4 音乐推荐系统 2.5 就业推荐系统 2.6 图书推荐系统 2.7 小说 ...
- 基础环境搭建——基于Spark平台的协同过滤实时电影推荐系统项目系列博客(五)
系列文章目录 初识推荐系统--基于Spark平台的协同过滤实时电影推荐系统项目系列博客(一) 利用用户行为数据--基于Spark平台的协同过滤实时电影推荐系统项目系列博客(二) 项目主要效果展示--基 ...
- 社区项目分享 | 用 Jina 搭建一个电影推荐系统
我们每天都在接触推荐系统,短视频.电商.外卖.演出.广告-- 今天,我们将演示 Jina AI 社区用户 Achintya 的项目,他用 Jina 搭建了一个电影推荐系统. 电影推荐系统原理概览 在这 ...
- Python+Django电影推荐系统搭建
文章目录 1. 新建虚拟环境 2. 数据库设置 2.1 安装PostGreSQL 2.2 为MovieGEEK创建数据库 2.3 安装Python数据库驱动程序 2.4 配置Django数据库连接以连 ...
最新文章
- java语言仅支持单重继承_java语言程序设计基础篇习题_复习题_第十一章
- JSON是什么?它能带来什么?
- win10电脑pppoe拨号模块损坏_电脑维修免费在线咨询
- CUDA内存类型memory
- 技术人生,专家本色——采访张善友老师后的一点感受
- SpringBoot中的Tomcat是如何启动的
- Android Studio 使用笔记:工具窗口浮动与布局恢复
- 双系统安装(win10系统+Ubuntu)
- 【AD封装】贴片插件晶振(带3D)
- 《仿美团SSM版》项目研发总结
- 微博奥运营销策略复盘,探索双十一微博品牌营销新手法!!
- 云服务(腾讯云)的安全防范措施
- 《Real-Time Rendering 4th Edition》全文翻译 - 第7章 阴影(下)7.7 ~ 7.10
- js问号点的作用(?.)和问号问号(??)的用法
- Java20:NullPointerException
- android 扫描手机内存和SD卡,获取手机的视频、音频文件。把获取不到的文件扫描出来
- 学术英语理工(第二版)Unit4课文翻译
- 51单片机节日彩灯控制c语言,采用AT89C51单片机设计的可编程彩灯控制
- js创建节点及节点操作
- 经典PID控制器的缺陷
热门文章
- 旅游推荐系统毕业设计总结(包含旅游信息爬取、算法应用和旅游推荐系统实现)
- React native 分享 友盟分享SDK
- 欧姆龙多PLC串行链接模式的应用
- 电视盒子cpu天梯图 电视盒子CPU性能天梯图2022
- java怎么引入矢量图标库,阿里巴巴矢量图标库Iconfont的使用方法
- c语言指针的作用 举例,c语言指针详解(c语言指针用法举例)
- 算法图解第一章笔记与习题(算法简介)
- SLAM技术与市场杂谈
- Android端公司通讯录开发与实现(二)
- android xml 注释快捷键,xml注释(xml注释掉一段代码)