基于hadoop的电影推荐系统的实现

2023-11-02

1.设计任务

通过编写代码,设计一个基于Hadoop的电影推荐系统,通过此推荐系统的编写,掌握在Hadoop平台上的文件操作,数据处理的技能。

工程文件放在百度网盘了,运行run.py即可启动程序,由于代码年份久远,我已尽量打了注释,大家可以下载后进行摸索。

链接:https://pan.baidu.com/s/17OpSNstnFA1nVxDisuNBBg
提取码:9fv3

如果百度网盘失效 请移步github,里面有详细的数据集和代码

2.开发环境

windows 10
hadoop 2.8.3
python 3.+
vscode
MySQL 8.0
关于hadoop配置可以看我之前的文章
win10下配置hadoop环境

3.系统层次设计

为了使电影推荐系统的设计更加完善,提高推荐系统的可维护性和可拓展性。我们采用三种系统相结合的方式进行总的系统层次设计。分为Hadoop为主的分布式系统,python为主的算法分析系统和MySQL为主的数据库存储系统。三种系统之间相互独立,仅采用特定的程序接口进行调用,可以最大程度的增强推荐系统的稳健性。
该系统的设计框架图如下所示:
在这里插入图片描述

4.数据上传与下载

1.启动hadoop
在这里插入图片描述
2.将ml-100k数据集上传到hadoop下的ml-100k文件夹
在这里插入图片描述
上传结果如下:
在这里插入图片描述
3.与python相连接
利用python中的hdfs包,用如下代码实现hadoop与python相连接。

from hdfs import *
client = Client("http://localhost:50070")  

4.数据下载

client.download(file_user_movie,"D://VSC//vscode python//hadoop//ml-100k")
client.download(file_movie_info,"D://VSC//vscode python//hadoop//ml-100k")
client.download(user_information,"D://VSC//vscode python//hadoop//ml-100k")

5.面向电影制作方的推荐数据

运行结果如下图所示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
总览如下:
在这里插入图片描述
在这里插入图片描述

6.基于协同过滤算法的用户推荐算法

运行结果如下图:
在这里插入图片描述

7.将推荐结果存入数据库以便查阅

db = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123456', db='test', charset='utf8')
cursor = db.cursor() #新建数据库访问游标

main函数调用

 cursor.execute("drop table if exists Recommended") #检查数据库中是否存在名为recommended的数据库,若存在则删除
    sql = """
    create table Recommended (
    film varchar(80) not null,
    rating DECIMAL (7, 4) not null )
    """
    cursor.execute(sql) #创建数据库
    for i in result.keys():
        print("film:%s,rating:%f"%(movies[i],result[i]))
        sql = 'insert into Recommended (`film`,`rating`) values("%s","%f")'%(movies[i],result[i])
        cursor.execute(sql) #执行数据插入语句
        db.commit() #提交结果到数据库中

在这里插入图片描述

8.参考资料

[1]《大数据原理及应用》电子邮电出版社 林子雨著
[2] Python如何连接mysql数据库 https://www.py.cn/jishu/jichu/12706.html
[3] Movielens数据集详细介绍 https://blog.csdn.net/zwqhehe/article/details/75912003
[4] Python3调用Hadoop的API https://www.cnblogs.com/sss4/p/10443497.html
[5] Collaborative Filtering(协同过滤算法详解) https://www.cnblogs.com/ECJTUACM-873284962/p/8729010.html

9.部分源码

完整代码请移步基于Hadoop的电影推荐系统 下载
或者我的github,里面有详细的数据集和代码

def score_analysis(): #电影评分分析
    scores = {"1":0,"2":0,"3":0,"4":0,"5":0}
    for line in open(user_movie):
        user, item, score = line.split('\t')[0:3]
        scores[score] += 1

    x1 = scores.keys() #用字典的键也就是分数作为x轴
    y1 = scores.values() #用字典键对应的值也就是打分人数作为y轴
    # print(scores)

    plt.figure(figsize=(19, 10))
    plt.subplot(2,3,2)
    plt.bar(x1,y1,color = 'slateblue',width = 0.95)
    plt.title("电影评分统计图",fontsize=14)
    plt.xlabel("影片评分 (0-5)",fontsize=14)
    plt.ylabel("评分人数",fontsize = 14)

def movie_year_analysis(): #电影年份分析
    yearCounts = {} #用来统计电影年份与数量的对应关系
    for year in range(1922,1999):  #按照数据集中电影的年份信息 生成年份字典
        yearCounts[str(year)] = 0

    for line in open(movie_information,encoding='ISO-8859-1'):
        release_date = line.split('|')[2]
        release_year = release_date[-4:]
        if release_year == "": continue
        yearCounts[release_year] += 1

    x2 = list(yearCounts.keys()) #获取x轴坐标并转为列表
    y2 = list(yearCounts.values())#获取y轴坐标并转为列表

    plt.subplot(2,3,5)

    plt.plot(x2,y2,label = '电影数量',color = 'cornflowerblue')
    plt.legend(loc="upper right") #设置标签图在右上角
    x_major_locator=MultipleLocator(5) #设置x轴间隔为5
    ax=plt.gca()
    ax.xaxis.set_major_locator(x_major_locator)

    plt.xticks(rotation = -60) #将x轴坐标旋转60度
    x_new = range(1922,1998)
    plt.title("电影年份统计图",fontsize=14)
    plt.xlabel("年份",fontsize=14)
    plt.ylabel("电影数量",fontsize = 14)
    # plt.show()

def occuptin_analysis():   #职业分析

    occuption_count = {}
    for line in open(user_information): 
        occuption = line.split('|')[3]
        occuption_count[occuption] = occuption_count.get(occuption,0) + 1 #统计职业及其对应人数

    sort_occuption_counts = sorted(occuption_count.items(),key=lambda k: k[1]) #将结果从小到大排序
    # print(sort_occuption_counts)
    #由于排序之后,字典类型会变成列表类型
    #然而这两种类型无法相互转换
    #所以得遍历来将列表的值转换为字典
    sort_occuption = {}
    for i in sort_occuption_counts: #将排序结果存回字典
        sort_occuption[i[0]] = i[1]
    # print(sort_occuption)

    x4 = sort_occuption.keys()
    y4 = sort_occuption.values()
    plt.subplot(2,3,6)
    plt.bar(x4,y4,color = 'blue',width = 0.8)
    plt.xticks(rotation = -60) #将x轴坐标旋转60度
    # plt.title("用户职业统计情况",fontsize=14)
    plt.xlabel("职业",fontsize=14)
    plt.ylabel("人数",fontsize=14)


def gender_analysis(): #性别分析
    unames = ['userid','age','gender','occupation','zip code']
    users = pd.read_table('u.user',sep = '\|',names = unames)
    rnames = ['userid','itemid','rating','timestamp']
    ratings = pd.read_table('u.data',names = rnames,engine = 'python')
    inames = ['itemid','movie title','release date','video release date','IMDB URL','unknown','Action','Adventure'
            ,'Animation','Children\'s','Comedy','Crime','DOcumentrary','Drama','Fatasy','Film-Noir','Horror','Musical'
            ,'Mystery','Romance','Sci-Fi','Thriller','War','Western']
    items = pd.read_table('u.item',sep = '\|',names = inames,engine = 'python')
    
    #计算男女生对电影评分的平均值和标准差
    users_df = pd.DataFrame()
    users_df['userid'] = users['userid']
    users_df['gender'] = users['gender']
    ratings_df = pd.DataFrame()
    ratings_df['userid'] = ratings['userid']
    ratings_df['rating'] = ratings['rating']
    rating_df = pd.merge(users_df,ratings_df)
    gender_table = pd.pivot_table(rating_df,index = ['gender','userid'],values = 'rating')
    gender_df = pd.DataFrame(gender_table)
    Female_df = gender_df.query("gender == ['F']")
    Male_df = gender_df.query("gender == ['M']")
    print("男性电影评分平均值:"+str(Male_df.rating.sum()/len(Male_df.rating)) +" 标准差:"+str(np.std(Male_df.rating)))
    print("女生电影评分平均值:"+str(Female_df.rating.sum()/len(Female_df.rating))+"标准差:"+str(np.std(Female_df.rating)))

    ratings_df_2 = pd.DataFrame()
    ratings_df_2['userid'] = ratings['userid']
    ratings_df_2['rating'] = ratings['rating']
    ratings_df_2['itemid'] = ratings['itemid']
    items_df = pd.DataFrame()
    items_df['itemid'] = items['itemid']
    items_df['movietitle'] = items['movie title']
    
    tmp = pd.merge(users_df,ratings_df_2)
    gender_item_df = pd.merge(tmp,items_df)
    Female_item_df = gender_item_df.query("gender == ['F']")
    Male_item_df = gender_item_df.query("gender == ['M']")
    print("女生最爱看的五部电影")
    print(Female_item_df.groupby(['movietitle']).rating.mean().sort_values(ascending = False)[0:5,])
    print("男生最爱看的五部电影")
    print(Male_item_df.groupby(['movietitle']).rating.mean().sort_values(ascending = False)[0:5,])   

def gender_compare():
    u_cols = ['user_id', 'age', 'sex', 'occupation', 'zip_code']
    users = pd.read_csv(user_information, sep='|', names=u_cols,encoding='latin-1')

    r_cols = ['user_id', 'movie_id', 'rating', 'unix_timestamp']
    ratings = pd.read_csv(user_movie, sep='\t', names=r_cols,encoding='latin-1')

    m_cols = ['movie_id', 'title', 'release_date', 'video_release_date', 'imdb_url'] 
    movies = pd.read_csv(movie_information, sep='|', names=m_cols, usecols=range(5),encoding='latin-1') 

    # 数据集整合

    movie_ratings = pd.merge(movies, ratings) 
    lens = pd.merge(movie_ratings, users)
    labels = ['0-9', '10-19', '20-29', '30-39', '40-49', '50-59', '60-69', '70-79']
    lens['age_group'] = pd.cut(lens.age, range(0, 81, 10), right=False, labels=labels)
    lens[['age', 'age_group']].drop_duplicates()[:10]
    lens.groupby('age_group').agg({'rating': [np.size, np.mean]})
    most_50 = lens.groupby('movie_id').size().sort_values(ascending=False)[:50]
    lens.set_index('movie_id', inplace=True)
    by_age = lens.loc[most_50.index].groupby(['title', 'age_group'])

    lens.reset_index('movie_id', inplace=True)  
    pivoted = lens.pivot_table(index=['movie_id', 'title'],
                            columns=['sex'],
                            values='rating',
                            fill_value=0)
    pivoted['diff'] = pivoted.M - pivoted.F

    plt.subplot(2,3,3)
    users.age.plot.hist(bins=30,edgecolor='black')
    
    plt.title("用户年龄分布图",fontsize=14)
    plt.ylabel('用户数量',fontsize=14)
    plt.xlabel('用户年龄',fontsize=14)


    pivoted.reset_index('movie_id', inplace=True)
    disagreements = pivoted[pivoted.movie_id.isin(most_50.index)]['diff']
    plt.subplot(1,3,1)
    disagreements.sort_values().plot(kind='barh',color = 'dodgerblue')
    plt.title('男/女性平均评分\n(差异>0=受男性青睐)',fontsize=14)
    plt.ylabel('电影',fontsize=14)
    plt.xlabel('平均评级差',fontsize=14)

def ItemSimilarity(user_movie):
    C = {} #存放最终的物品相似度矩阵
    N = {} #存放每个电影评分人数
    for user, items in user_movie.items():
        for i in items.keys():
            print(i)
            N.setdefault(i,0)
            N[i] += 1
            C.setdefault(i,{})
            for j in items.keys():
                if i == j : continue
                C[i].setdefault(j,0)
                C[i][j] += 1

        W = {} #计算最终物品余弦相似度矩阵
        for i, related_items in C.items():
            W.setdefault(i,{})
            for j,cij in related_items.items():
                W[i][j] = cij /(math.sqrt(N[i] * N[j]))
    return W

def Recommend(user, user_movie, W, K, N): #根据矩阵为具体用户推荐
    rank = {}
    action_item = user_movie[user]
    for item, score in action_item.items():
        for j, wj  in sorted(W[item].items(),key = lambda x: x[1], reverse = True)[0:K]:
            if j in action_item.keys():
                continue
            rank.setdefault(j,0)
            rank[j] += score * wj
    return dict(sorted(rank.items(),key = lambda x:x[1],reverse= True)[0:N]) #排序 取前N个结果

class information_counts(MRJob):
    """ 
    聚合单个用户的下的所有评分数据
    格式为:user_id, (item_count, rating_sum, [(item_id,rating)...])
    """
    def group_by_user_rating(self, key, line):

        user_id, item_id, rating = line.split('|')
        yield user_id, (item_id, float(rating))
 
    def count_ratings_users_freq(self, user_id, values):

        item_count = 0
        item_sum = 0
        final = []
        for item_id, rating in values:
            item_count += 1
            item_sum += rating
            final.append((item_id, rating))
 
        yield user_id, (item_count, item_sum, final)
 
    def steps(self):
        return [MRStep(mapper=self.group_by_user_rating,
                        reducer=self.count_ratings_users_freq),]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于hadoop的电影推荐系统的实现 的相关文章

  • 使用数据库进行日志记录

    大多数日志似乎都是纯文本形式 而不是放入 MySQL 其他类型的数据库中 这是否有原因 在我看来 将它们放入数据库将使分析变得非常非常容易 但这会以牺牲速度还是其他什么为代价 我不太关心可移植性 显然你会有数据库连接的文本日志 我能想到两大
  • 使用多级解决方案计算二维网格中的最近邻

    我有一个问题 在 x y 大小的网格中 我提供了一个点 并且我需要找到最近的邻居 在实践中 我试图在 pygame 中找到距离光标最近的点 该点跨越颜色距离阈值 计算如下 sqrt rgb1 0 rgb2 0 2 rgb1 1 rgb2 1
  • 在Python中以交互方式执行多行语句

    我是 Python 世界的新手 这是我用 Python 编写的第一个程序 我来自 R 世界 所以这对我来说有点不直观 当我执行时 In 15 import math import random random random math sqrt
  • Django 不会以奇怪的错误“AttributeError: 'module' object has no attribute 'getargspec'”启动

    我对 Django 的内部结构有点缺乏经验 所以我现在完全陷入困境 它昨天起作用了 但我不记得我改变过任何重要的东西 当我转身时DEBUG True任何恰好位于列表中第一个的模块上都有堆栈跟踪 Traceback most recent c
  • reStructuredText:README.rst 未在 PyPI 上解析

    我有一个托管在 Github 和 PyPI 上的 Python 项目 在 Github 上 https github com sloria TextBlob blob master README rst https github com s
  • 如何使用 PyMongo 在重复键错误后继续插入

    如果我需要在 MongoDB 中插入尚不存在的文档 db stock update one document set document upsert True 将完成这项工作 如果我错了 请随时纠正我 但是 如果我有一个文档列表并想将它们全
  • 返回上个月的日期时间对象

    如果 timedelta 在它的构造函数中有一个月份参数就好了 那么最简单的方法是什么 EDIT 正如下面指出的那样 我并没有认真考虑这一点 我真正想要的是上个月的任何一天 因为最终我只会获取年份和月份 因此 给定一个日期时间对象 返回的最
  • 在 iPython/pandas 中绘制多条线会生成多个图

    我试图了解 matplotlib 的状态机模型 但在尝试在单个图上绘制多条线时遇到错误 据我了解 以下代码应该生成包含两行的单个图 import pandas as pd import pandas io data as web aapl
  • 如何使用 Celery 多工作人员启用自动缩放?

    命令celery worker A proj autoscale 10 1 loglevel info启动具有自动缩放功能的工作人员 当创建多个工人时 me mypc projects x celery multi start mywork
  • uri 警告中缺少端口:使用 Python OpenCV cv2.VideoCapture() 打开文件时出错

    当我尝试流式传输 ipcam 时 出现了如下所示的错误 tcp 000000000048c640 uri 中缺少端口 警告 打开文件时出错 build opencv modules videoio src cap ffmpeg impl h
  • 根据第三个变量更改散点图中的标记样式

    我正在处理多列字典 我想绘制两列 然后根据第三列和第四列更改标记的颜色和样式 我很难改变 pylab 散点图中的标记样式 我的方法适用于颜色 不幸的是不适用于标记样式 x 1 2 3 4 5 6 y 1 3 4 5 6 7 m k l l
  • 根据列索引重命名 Dataframe 列

    是否有内置函数可以按索引重命名 pandas 数据框 我以为我知道列标题的名称 但事实证明第二列中有一些十六进制字符 根据我接收数据的方式 我将来可能会在第 2 列中遇到这个问题 因此我无法将这些特定的十六进制字符硬编码到 datafram
  • 更换壳牌管道[重复]

    这个问题在这里已经有答案了 在 subprocess 模块的 Python 2 7 文档中 我找到了以下片段 p1 Popen dmesg stdout PIPE p2 Popen grep hda stdin p1 stdout stdo
  • 在 Python 中访问 argparse 的参数值

    我正在尝试为我的程序设置一些简单的标志参数 但无法弄清楚如何访问它们 我有 argparser parser argparse ArgumentParser description Simple PostScript Interpreter
  • 在 HDF5 (PyTables) 中存储 numpy 稀疏矩阵

    我在使用 PyTables 存储 numpy csr matrix 时遇到问题 我收到此错误 TypeError objects of type csr matrix are not supported in this context so
  • 如何获取Windows批处理的父文件夹

    我正在编写一个批处理文件 我需要获取该bat文件的父文件夹 有可能吗 注意 我的意思是批处理文件的父文件夹 而不是调用该批处理的提示的当前目录 Thanks 批处理的父文件夹位于变量中 dp0位于 例子 echo off setlocal
  • 如何在Tensorflow中保存估计器以供以后使用?

    我按照教程 TF Layers 指南 构建卷积神经网络 以下是代码 https github com tensorflow tensorflow blob r1 1 tensorflow examples tutorials layers
  • Streamlabs API 405 响应代码

    我正在尝试使用Streamlabs API https dev streamlabs com Streamlabs API 使用 Oauth2 来创建应用程序 因此 首先我将使用我的应用程序的用户发送到一个授权链接 其中包含我的应用程序的客
  • 如何使用 Pandas Series 绘制两个不同长度/开始日期的时间序列?

    我正在绘制 每周总事件 的几个熊猫系列对象 系列中的数据events per week看起来像这样 Datetime 1995 10 09 45 1995 10 16 63 1995 10 23 83 1995 10 30 91 1995
  • Python 中的字符串slugification

    我正在寻找 slugify 字符串的最佳方法 蛞蝓 是什么 https stackoverflow com questions 427102 in django what is a slug 我当前的解决方案基于这个食谱 http code

随机推荐

  • Mybatis-多表联查

    多表联查 一 步骤一 创建pojo实体类 二 步骤二 明确两个实体类之间的关系 三 步骤三 修改pojo实体类 四 步骤四 编写Mapper接口 五 步骤五 编写Mapper映射文件 题目1 通过订单id查询订单详情以及所属用户 题目2 通
  • mysql字段更新拼接_更新数据库中值为拼接字符串的字段

    我们开发系统涉及权限的时候 会处理到用户和角色的关系 通常情况下 我们会建一个用户角色关系映射表 user role mapping 字段有id user id role id 如果某个用户有多个角色 那么在user role mappin
  • C语言课程设计学生籍贯信息,C语言课程设计 学生籍贯信息记录簿设计.doc

    C语言与程序设计课程设计 学生籍贯信息记录簿设计 学 院 信息工程 班 级 物联1301班 学 号 131408119 姓 名 滕玲 一 设计目的 该软件主要是编辑一个学生籍贯信息记录簿记录每个学生信息 包括 学号 姓名 籍贯 具体功能 1
  • flex布局采用justify-content:space-between时,当为两个内容时中间被空出的解决方案

    我们在用flex布局的时候有时会用到justify content space between属性 这个属性是让弹性容器内的元素向两端对齐 div class box div div div div div div div div div
  • 广度优先遍历进阶

    第七周 BFS 广度优先搜索 733 127 130 317 505 529 1263 1197 815 934 广度优先模板 void bfs queue
  • filetime,systemtime相互转化,获取文件创建时间,访问时间,修改时间,获取指定时间之前之后的SYSTEMTIME

    deleteOldFiles cpp 定义控制台应用程序的入口点 include stdafx h include
  • 脑科学和类脑智能技术综述学习笔记

    文章目录 Part1 脑科学 1 脑科学与类脑研究概述 摘要 引言 1 国际脑科学和类脑研究的回顾与前瞻 1 1 脑科学的回顾 现代神经科学的起点是 神经解剖学和组织学 对神经系统结构的认识和分析 1 2 脑科学领域的重大问题 从图谱制作到
  • Unity3d实现红外热成像效果

    1 将需要在红外图像中高亮的物体设置到图层PostProcessing 2 新建一个相机CameraHighLight 设置其Culling Mask为PostProcessing 也就是在这个相机中只有PostProcessing图层的物
  • ArcGIS Pro免费试用申请与安装配置

    ArcGIS Pro免费试用申请与安装配置 每个邮箱可以申请21天的试用 1 打开申请网站 https www esri com zh cn arcgis products arcgis pro trial 2 注册ArcGIS试用 3 在
  • JS子窗口向父窗口传值

    方法一 用模式窗口 returnValue是javascript中html的window对象的属性 目的是返回窗口值 当用window showModalDialog函数打开一个IE的模式窗口 模式窗口就是子窗口 打开后不能操作父窗口 只能
  • 斐波那契数列求和——C语言(小白版)

    斐波那契数列求和 C语言 小白版 题目要求 斐波那契数列 1 1 2 3 5 8 13 21 34 不难发现当n gt 2时 an an 1 an 2 要求 当屏幕输入n n gt 2 时 输出前n项以及前n项的和 注意 我们不使用递归 也
  • 使用Qt创建模拟时钟

    main cpp include
  • Java的数据结构之枚举、向量、栈、字典

    Java工具包提供了强大的数据结构 在Java中的数据结构主要包括以下几种接口和类 枚举 Enumeration 位集合 BitSet 向量 Vector 栈 Stack 字典 Dictionary 哈希表 Hashtable 属性 Pro
  • Java Character 类

    Character 类用于对单个字符进行操作 Character 类在对象中包装一个基本类型 char 的值 实例 char ch a Unicode 字符表示形式 char uniChar u039A 字符数组 char charArra
  • 实战演习(五)——人脸识别(CNN)简单演练

    笔者是一个痴迷于挖掘数据中的价值的学习人 希望在平日的工作学习中 挖掘数据的价值 找寻数据的秘密 笔者认为 数据的价值不仅仅只体现在企业中 个人也可以体会到数据的魅力 用技术力量探索行为密码 让大数据助跑每一个人 欢迎直筒们关注我的公众号
  • 运输层协议概述

    紫色代表一级目录 粉红代表二级目录 蓝色代表三级目录 红色代表关键字 橙色代表说明 运输层协议概述 进程之间的通信 从通信的角度看 运输层向它上面的应用层提供通信服务 它属于面向通信部分的最高层 从信息处理的角度看 运输层是用户功能中的最低
  • 【陈工笔记】# LaTeX中,单元格数据居中方式 #

    良好的习惯 才不会让努力白白浪费 第一种方式 使用 p 1 5cm lt centering 指定单元格大小并设置对齐 其中p 1 5cm 指定大小 lt centering 指定对齐方式 使用 lt centering 时 需引入宏包 u
  • 点云学习---入门

    1 点云数据格式 常见的点云格式包括 las 用于激光雷达点云及其他任何三维xyz元组 是一种用于交换三维点数据的公共文件格式 文件主要由4部分组成 包括公共头块 包含版本号 缩放因子 偏移值 时间 范围等 变长记录 包含变长类型数据 坐标
  • Windows环境Mycat数据库分库分表中间件部署

    Windows环境Mycat数据库分库分表中间件部署 标签 数据库中间件mycat分布式集群 2016 08 23 00 17 957人阅读 评论 0 收藏 举报 分类 分布式开发技术 12 版权声明 本文为博主原创文章 未经博主允许不得转
  • 基于hadoop的电影推荐系统的实现

    1 设计任务 通过编写代码 设计一个基于Hadoop的电影推荐系统 通过此推荐系统的编写 掌握在Hadoop平台上的文件操作 数据处理的技能 工程文件放在百度网盘了 运行run py即可启动程序 由于代码年份久远 我已尽量打了注释 大家可以