基于MapReduce+Pandas的电影排名与推荐以及数据分析与可视化展示

本文介绍了一个结合MapReduce和Pandas实现的电影推荐系统,包括电影统计排名和个性化推荐两个模块。系统使用HDFS存储数据,通过MapReduce计算电影平均分和用户相似度,Pandas进行数据处理和可视化。协同过滤算法用于计算用户间的相似度,生成推荐电影列表。此外,文章还讨论了开发环境、实现机制和流程,以及所用到的技术如Java、Python和Hadoop的MapReduce框架。
摘要由CSDN通过智能技术生成

1 课题分析

1.1 课题背景

在大数据化和互联网+的今天,用户很难清楚自己到底需要什么。然而推荐系统的出现就极大改变了这种尴尬的情况,推荐系统改变了人们的生活方式,它可以根据设计的算法从用户的历史数据中得到用户现阶段可能想要的东西,从而使用户在浩瀚的数据中找到他们想要的,所以推荐系统会给用户带来很好的用户体验。

随着社会的不断发展,人们的生活水平显著提高,娱乐方式也多种多样。看电影目前是一种很受人们喜爱的娱乐方式。基于用户的协同过滤算法的电影推荐能根据用户的行为,在成千上万的电影中给用户制定个性化推荐电影表单。

基于用户的协同过滤推荐系统的基本原则是分析用户与用户之间的兴趣相似的关系。然后以物以类聚,人以群分的思想,系统会认为用户可能喜爱看的电影,是与他有较高相似度的人认为好看的电影。然而,这种情况会出现因为某个与他相似度最高的用户来决定推荐什么电影给用户的现象,这种现象只使用了一个与用户相似度最高的人来推荐相关电影,也即单点对结果的影响较大,所以这种推荐是片面的。因此,我们对该算法进行了改进,我们把所有的用户对电影的评分给予相关权重,然后对电影进行综合评分,这样就消除了因为某个单点而影响推荐结果。

如果关于用户对电影评级的信息越多,则推荐准确度将越高,也即看的越多,推荐效果越好。

当今时代,我们的生活方方面面都有推荐系统的身影,推荐系统正在逐渐代替传统的推荐引擎,甚至改变了人们的相关决策。智能推荐可以从海量的数据中直接提供给使用者想要的结果。

1.2 题目描述

本项目是针对于市场电影数据进行分析,然后得出结果,并根据用户喜好进行推荐。主要以下两个模块。

1.2.1 电影统计排名模块

1、根据提供的源数据,然后先利用mapreduce进行分组、求平均值、排序三个步骤,得出用户需要的电影排名数据。

2、利用pandas将mapreduce的分组、求平均值、排序进行实现,并对相关量之间的关系进行可视化展示。

1.2.2 电影推荐模块

1、使用mapreduce利用协同过滤算法,计算出用户与用户之间的相似度。此过程需要五步,对电影ID进行分组、求用户与用户之间的相似度、对用户ID进行分组、求用户的推荐评分、对推荐评分进行排序。

2、第一步可以直接使用pandas进行分组,模拟mapreduce的实现过程,并对相关量进行可视化展示,第二步是需要用mapreduce生成的用户与用户之间相似度的数据,然后进行数据清洗、预处理等操作,最后将结果直观地展示给用户,必要时可以进行可视化展示,第三步与第一步类似处理,第四步是将上两步的结果进行汇总,然后进行数据清洗等操作,获得用户需要的数据集。第五步排序就可以直接利用pandas进行,得到结果可视化展示给用户。

1.3 开发语言及开发环境

1.3.1 Java简介

Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程 。

Java具有简单性、面向对象、分布式健壮性安全性、平台独立与可移植性、多线程、动态性等特点 。Java可以编写桌面应用程序Web应用程序分布式系统嵌入式系统应用程序等 。

1.3.2 python简介

Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。

Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色语法结构。

1.3.3 MapReduce简介

MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行运算。它极大地方便了编程人员在不会分布式并行编程的情况下,将自己的程序运行在分布式系统上。当前的软件实现是指定一个Map(映射)函数,用来把一组键值对映射成一组新的键值对,指定并发的Reduce(归约)函数,用来保证所有映射的键值对中的每一个共享相同的键组。

1.3.4 Pandas库简介

pandas 是基于NumPy 的一种工具,该工具是为解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。你很快就会发现,它是使Python成为强大而高效的数据分析环境的重要因素之一。

2 流程分析

2.1 系统总体结构设计

1、电影总体排名系统总体架构图如图2.1和2.2所示:

 

图2.1  mapreduce处理电影排名总体架构图

 

图2.2  pandas处理电影排名总体架构图

2、电影总体推荐系统总体架构图如图2.3和2.4所示:

 

图2.3 mapreduce处理电影推荐总体架构图

 

图2.4 pandas处理电影推荐总体架构图

2.2 系统功能设计

本课程设计采用HDFS、MapRduce、以及协同过滤的相关函数、pandas预处理与可视化等相关技术实现了电影推荐和排名系统。功能比较简单,主要是实现推荐算法,没有设计前端页面,但是后台使用的推荐算法经典且严谨,借鉴了相关成功的案例,结合实际情况设计出了推荐效果较为理想的电影推荐系统。

本课程设计主要实现了两个功能模块:电影排名模块,个性化电影推荐模块。

2.3 系统实现机制

2.3.1 电影排名模块实现机制

1、系统先将采集到的用户的评分相关的数据集保存到HDFS分布式文件系统中,然后通过mapreduce先进行分组,然后基于同一部电影的所有评分算出这部电影的平均分,最后在进行排序。

 2、系统利用pandas将mapreduce的分组、求平均值、排序进行实现,并对相关量之间的关系进行可视化展示。

2.3.2 个性化电影推荐模块实现机制

1、系统先将采集到的用户的评分相关的数据集保存到HDFS分布式文件系统中,经过MapReduce基于用户的协同过滤算法,通过用户的历史数据得到相关用户与其的相似度,然后以相似度为权重计算出用户对电影的预测打分,最后根据预测打分对每一位用户进行推荐排序,得出最后结果。

2、系统利用pandas对mapreduce的实现过程进行复原,中间涉及到算法的部分则是采用mapreduce已生成的结果进行数据处理得到用户需要的格式,并且对相关量进行比较分析和可视化展示结果。

3 实现方法

3.1 技术简介

3.1.1 分布式文件系统HDFS

   Hadoop分布式文件系统(HDFS)是指被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统(Distributed File System)。它和现有的分布式文件系统有很多共同点。但同时,它和其他的分布式文件系统的区别也是很明显的。HDFS是一个高度容错性的系统,适合部署在廉价的机器上。HDFS能提供高吞吐量的数据访问,非常适合大规模数据集上的应用。HDFS放宽了一部分POSIX约束,来实现流式读取文件系统数据的目的。HDFS在最开始是作为Apache Nutch搜索引擎项目的基础架构而开发的。HDFS是Apache Hadoop Core项目的一部分HDFS由多种类型的节点组成的,其中有一个NameNode节点、一个SecondaryNameNode节点和多个DataNode节点以及其它相关节点。

3.1.2 MapReduce编程  

MapReduce是面向大数据并行处理的计算模型、框架和平台,它隐含了以下三层含义:

1)MapReduce是一个基于集群的高性能并行计算平台(Cluster Infrastructure)。它允许用市场上普通的商用服务器构成一个包含数十、数百至数千个节点的分布和并行计算集群。

2)MapReduce是一个并行计算与运行软件框架(Software Framework)。它提供了一个庞大但设计精良的并行计算软件框架,能自动完成计算任务的并行化处理,自动划分计算数据和计算任务,在集群节点上自动分配和执行任务以及收集计算结果,将数据分布存储、数据通信、容错处理等并行计算涉及到的很多系统底层的复杂细节交由系统负责处理,大大减少了软件开发人员的负担。

3)MapReduce是一个并行程序设计模型与方法(Programming Model & Methodology)。它借助于函数式程序设计语言Lisp的设计思想,提供了一种简便的并行程序设计方法,用Map和Reduce两个函数编程实现基本的并行计算任务,提供了抽象的操作和并行编程接口,以简单方便地完成大规模数据的编程和计算处理。

3.1.3 Pandas数据预处理与可视化

pandas 是基于NumPy 的一种工具,该工具是为解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。你很快就会发现,它是使Python成为强大而高效的数据分析环境的重要因素之一。

NumPy(Numerical Python)是Python的一种开源的数值计算扩展。这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表(nested list structure)结构要高效的多(该结构也可以用来表示矩阵(matrix)),支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。

matplotlib库是专门用于开发2D图表(包括3D图表)的,突出优点:使用起来极为简单。以渐进、交互式方式实现数据可视化。表达式和文本使用LaTeX排版。对图像元素控制力强。可输出PNG、PDF、SVG和EPS等多种格式。

3.1.4 电影排名实现

基于排序的算法,是评测物品好坏程度的较为简单的一种算法。

 

图3.1 电影排名示意图

(1)电影分组计算

通过源数据可以对电影进行分组,方便下面计算机电影平均值。

(2)电影分组求平均分计算

通过先求出电影的总分除以评价该电影的人数得出电影的平均分。

(3)根据平均分进行排序

通过电影的平均分进行降序排序,得到电影TOP N的排行榜。

3.1.5 个性化电影推荐实现

基于用户的协同过滤算法是推荐算法中最早应用的推荐算法。该推荐算法最初1992年被提出并应用于邮件过滤系统,之后被应用于新闻过滤。基于用户的协同过滤推荐算法是推荐系统中应用比较多的的一种推荐算法。基于用户的协同过滤的主要思想是通过分析不同的用户对物品的评分即喜爱情况来寻求各用户之间的相似性,从而进行相关推荐。

协同过滤常常被用于分辨某位特定顾客可能感兴趣的东西,这些结论来自于对其他相似顾客对哪些产品感兴趣的分析。协同过滤以其出色的速度和健壮性,在全球互联网领域炙手可热。

此次课程设计我们采用的是基于用户的协同过滤,通过不同用户对电影的评分来评测用户之间的相似性,基于用户之间的相似性与用户对电影的评分做出推荐相关电影。

 

图3.2 基于用户的协同过滤示意图

(1)向量空间余弦的相似度计算

余弦相似度用向量空间中两个向量夹角的余弦值作为衡量两个个体间差异的大小。相比距离度量,余弦相似度更加注重两个向量在方向上的差异,而非距离或长度上。

通过计算两个向量夹角的余弦值来求解相似度。余弦值的数据范围为[-1,1],越趋近于1,相似度越高。

(2)预测评分计算

   通过计算用户与用户之间相似度与用户对电影的评分的乘积求出预测综合评分,然后对应用户看过的电影的预测综合评分置0。

(3)根据预测评分排序

根据求出的用户对电影的预测综合评分,根据从高到低的顺序排列。根据需求去得分较高的电影作为给用户推荐的电影。

3.2 实现过程

3.2.1 电影排名实现流程图

 

图3.3 mapreduce处理电影排名流程图

 

图3.4 pandas处理电影排名流程图

3.2.2 电影排名流程梳理

1、mapreduce实现过程

第一个MapReduce实现的是以movieid分组,输出userid sorce用户id,评分)

第二个MapReduce实现的是将第一次MapReduce的输出作为输入,求出每个电影的平均评分并输出movieid和score(电影id和评分)。

第三个MapReduce实现的是将第二次的MapReduce的输出进行降序排序,通过compareTo方法进行比较。

2、pandas实现过程

第一步:使用pandas先导入源数据,先为源数据添加列名,然后按照电影ID进行分组,再统计不同电影的观影人数,并进行排序,最后取电影ID前20的进行柱状图展示。

第二步:求出每一部电影的观影评分平均值,然后选取电影ID前10的进行柱状图展示。

第三步:根据评分对电影ID进行排序。

3.2.3 个性化电影推荐实现流程图

 

图3.5 mapreduce处理个性化电影推荐流程图

 

图3.6 pandas处理个性化电影推荐流程图

3.2.4个性电影推荐流程梳理

1、mapreduce实现过程

第一个MapReduce实现的是按照uesrid(用户ID)分组,并输出movieid_score(电影id_评分),电影id分组可以,顺序可调换

第二、三个MapReduce实现的是按照movieid(电影id)分组,并输出userid_score(用户id_评分),两次分组目的就是实现乘积运算,然后计算用户之间的相似度(A用户喜欢电影1、电影2、电影3,B用户喜欢电影2、电影3,从而计算用户A与用户B的相似度)

第四个MapReduce实现的是以userid(用户id)分组,输出movieid_score_0.0(电影id_评分_0.0)

第五个MapReduce实现的是先将第四个MapReduce输出的分数置0(没看的就是0分),再以userid(用户id)分组,将综合评分靠前的movieid(电影id)排在前面,实现推荐功能。

2、pandas实现过程

第一步:使用pandas先导入源数据,先为源数据添加列名,然后按照用户ID进行分组,再选取用户ID为1的各列进行分析,再按照评分进行排序,最后随机选取10列数据进行柱状图展示,最后统计每一位用户所观看的电影数目进行柱状图展示。

第二步:导入mapreduce生成的用户与用户之间相似度的源数据并且展示,设置列名——"用户ID","用户ID-相似度",并按照用户ID进行排序,将用户ID-相似度进行单元格拆分,先对“用户ID-相似度”进行字符串拆分成为 “用户ID”“相似度”两列,再和前面获取的用户ID进行合并(合并包括横向和纵向合并),最后按照用户ID进行分组,最后对用户ID和另外的用户ID以及他们之间的相似度进行可视化展示。

第三步:先导入数据,设置列名——"电影ID","用户ID-评分",并按照电影ID进行排序,将用户ID_评分进行单元格拆分,然后先对“用户ID_评分”进行字符串拆分成为 “用户ID”“评分”两列,再和前面获取的电影ID进行合并(合并包括横向和纵向合并),最后按照电影ID进行分组,并将评分为0.0的给删除。

第四步:这一步模拟mapreduce执行对应用户的评分乘以相应地相似度的到推荐评分,根据第2步和第3步的结果进行完成,最后对用户ID、电影ID、以及推荐评分做一个可视化展示。

第五步:根据第四步的结果,对用户ID进行分组,然后求出评分最高的值,然后根据用户ID和推荐评分,找出最好的推荐电影,最后根据前面获得的用户ID以及对应的最高评分,获取相对应的电影ID,并推荐给用户

                                         4 设计实现

4.1 排序模块实现

排序模块是电影推荐系统的电影排名部分,本系统采用最快最简单的平均分排序算法。推荐系统先将用户对电影的评分的数据集保存到HDFS分布式文件系统中,经过MapReduce计算出电影的平均分。而pandas主要实现的是还原mapreduce的过程,在此过程中,对相关量之间的联系进行可视化展示。

4.1.1 mapreduce实现排序模块核心代码:

求每部电影的平均评分

public class WordCountReducer extends Reducer<Text, Score, Text, DoubleWritable> {

    // 每个k执行一次,即每个movieId为一组执行一次

    protected void reduce(Text key, Iterable<Score> value, Context context) throws IOException, InterruptedException {

       double total = 0;

       int i = 0;

       for (Score v : value) {

           total += v.getScore();

           i++;

       }

       // 因为score表中既然有这个电影,就必定评分了

       total = total / i;

       // 输出平均分 输出数据格式为:movieId total

       context.write(key, new DoubleWritable(total));

    }

}

对评分进行降序排列

@Override

public int compareTo(Score score) {

    if (this.score < score.getScore()) {

       return 1;

    } else {

       return -1;

    }

}

4.1.2  pandas实现排序模块具体代码

1、step1:以电影ID进行分组

df.sort_values('电影ID',inplace=True)

st1 = df.groupby(['电影ID','用户ID','评分']).all()

 

统计不同电影的观影人数,并进行排序

mc = df.groupby('电影ID')['用户ID'].count().sort_values(ascending=False)

mc = mc.reset_index().rename(columns={'用户ID':'观影人数'})

mc = mc[:10]#观影人数前十名

 

取电影ID前20的进行柱状图展示

mc.plot.bar(x='电影ID',y='观影人数')

 

2、step2:求出每一部电影的观影评分平均值

df.sort_values('电影ID',inplace=True)

st2 = df.groupby('电影ID').mean()

del st2['用户ID']

st2 = st2[:10]

st2 = st2.reset_index()

st2

 

st2.plot.bar(x='电影ID',y='评分')

 

3、step3:根据评分对电影ID进行排序

st3 = st3.sort_values('评分')

st3 = st3.reset_index()

del st3['index']

 

4.2 推荐模块实现

推荐模块是电影推荐系统的核心部分,本系统采用的是基于用户的协同过滤算法。推荐系统先将采集到的用户的评分相关的数据集保存到HDFS分布式文件系统中,经过MapReduce计算出推荐结果,而pandas主要负责的是根据整个流程使用python代码实现,中间算法部分依靠mapreduce生成的数据,对相关数据进行处理,得到用户直观看懂的数据格式,然后对相关变量之间的关系进行可视化展示。

4.2.1 mapreduce实现排序模块核心代码:

通过setup方法将第一步数据(userId movieId_score)加载,并以适当格式存在allUserList变量中,以便与map中的用户求取相似度,最终得到所有用户两两之间的相似度。

@Override

  protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {

     List<Score> userList = new ArrayList<Score>();

     String data = value.toString();

     String[] split1 = data.split("\t");

     String userId = split1[0];

     String[] split2 = split1[1].split(",");

     for (String s : split2) {

         String[] split3 = s.split("_");

         String movieId = split3[0];

         String score = split3[1];

         Score r = new Score();

         r.setUserId(userId);

         r.setMovieId(movieId);

         r.setScore(Double.parseDouble(score));

         userList.add(r);

     }

     List<String> userListSimilarity = SimilarityUtil.getSimilarity(userList, allUserList);

     for (String s : userListSimilarity) {

         String[] split = s.split(",");

         String similarity = split[1] + "_" + split[2];

         //输出为<userId,userId_similarity>

         context.write(new Text(userId), new Text(similarity));

     }

  }

}

求两两用户相似度的工具类。

public class SimilarityUtil {

public static List<String> getSimilarity(List<Score> userList, List<List<Score>> allUserList) {

List<String> resultList = new ArrayList<String>();

for (List<Score> userlist2 : allUserList) {

double molecular = 0.00;

double denominator1 = 0.00;

double denominator2 = 0.00;

for (Score r1 : userList) {

for (Score r2 : userlist2) {

// r1和r2都评论了这个电影

if (r1.getMovieId().equals(r2.getMovieId())) {

// 余弦分子

molecular += r1.getScore() * r2.getScore();

// 余弦分母

denominator1 += r1.getScore() * r1.getScore();

denominator2 += r2.getScore() * r2.getScore();

}

}

}

if (denominator1 != 0 && denominator2 != 0) {

denominator1 = Math.sqrt(denominator1);

denominator2 = Math.sqrt(denominator2);

double cos = molecular / (denominator1 * denominator2);

String result = userList.get(0).getUserId() + "," + userlist2.get(0).getUserId() + "," + cos;

resultList.add(result);

} else {

String result = userList.get(0).getUserId() + "," + userlist2.get(0).getUserId() + "," + 0;

resultList.add(result);

}

}

// 输出格式userId,userId,score

return resultList;

}

}

4.2.2  pandas实现排序模块具体代码

1、step1:按照用户ID进行分组

    

   st1 = df.groupby(['用户ID','电影ID','评分']).all()

 

选取用户ID为1的各列进行分析,再按照评分进行排序,最后随机选取10列数据进行柱状图展示

mc = st1.reset_index()

mc = mc.where(mc['用户ID']==1).dropna()

mc = mc.sample(10)

mc

 

mc.plot.bar(x='电影ID',y='评分')

 

统计每一位用户所观看的电影数目

mc = df.groupby('用户ID')['电影ID'].count()

mc = mc.reset_index().rename(columns={'电影ID':'电影数目'})

mc

 

进行柱状图展示

mc.plot.bar(x='用户ID',y='电影数目')

 

2、step2:根据mapreduce生成的用户与用户之间相似度的源数据,先进行预处理,然后进行可视化展示

导入mapreduce生成的用户与用户之间相似度的源数据,并且展示

      df = pd.read_table('similarity.txt',sep='   ')

df

 

设置列名——"用户ID","用户ID-相似度",并按照用户ID进行排序

df.columns = ["用户ID","用户ID-相似度"]

df = df.sort_values('用户ID')

df = df.reset_index()

del df['index']

df

 

将用户ID-相似度进行单元格拆分

st2 = df['用户ID-相似度'].str.split(',', expand=True)  

st2

 

获取源数据的第一列数据,方便与下列分割的数据进行汇总称为一个新的表格

df = df['用户ID'].reset_index()

del df['index']

df

创建一个空的 DataFrame,用来存放最后处理好的数据,格式为——'用户ID', "另一个用户ID", "用户相似度"

df_empty = pd.DataFrame(columns=['用户ID', "另一个用户ID", "用户相似度"])

df_empty

先对“用户ID-相似度”进行字符串拆分成为 “用户ID”“相似度”两列,再和前面获取的用户ID进行合并(合并包括横向和纵向合并),最后按照用户ID进行分组

for j in st2.columns:

    str2 = st2[j].str.split('_',expand=True)

    str2.columns = ["另一个用户ID", "用户相似度"]

    str3 = pd.concat([df,str2],axis=1)

    df_empty = pd.concat([df_empty,str3],axis=0)

df_empty = df_empty.groupby(['用户ID',"另一个用户ID", "用户相似度"]).all()

df_empty1 = df_empty.reset_index()

df_empty1

 

对用户ID和另外的用户ID以及他们之间的相似度进行可视化展示

正在上传…重新上传取消

3、step3:对第三个mapreduce生成的数据进行处理,最后展现格式为——(‘电影ID’、‘用户ID’、评分)

导入数据

df = pd.read_table('movieGroup.txt',sep='   ')

df

正在上传…重新上传取消

设置列名——"电影ID","用户ID-评分",并按照电影ID进行排序

df.columns = ["电影ID","用户ID_评分"]

df = df.sort_values('电影ID')

df = df.reset_index()

del df['index']

df

正在上传…重新上传取消

设置列名——"电影ID","用户ID-评分",并按照电影ID进行排序

df.columns = ["电影ID","用户ID_评分"]

df = df.sort_values('电影ID')

df = df.reset_index()

del df['index']

df

正在上传…重新上传取消

将用户ID_评分进行单元格拆分

st3 = df['用户ID_评分'].str.split(',', expand=True)  

st3

正在上传…重新上传取消

获取源数据的第一列数据,方便与下列分割的数据进行汇总称为一个新的表格

df = df['电影ID'].reset_index()

del df['index']

df

正在上传…重新上传取消

创建一个空的 DataFrame,用来存放最后处理好的数据,格式为——'电影ID', "用户ID", "评分"

df_empty = pd.DataFrame(columns=['电影ID', "用户ID", "评分"])

df_empty

正在上传…重新上传取消

先对“用户ID_评分”进行字符串拆分成为 “用户ID”“评分”两列,再和前面获取的电影ID进行合并(合并包括横向和纵向合并),最后按照电影ID进行分组,并将评分为0.0的给删除

for j in st3.columns:

    str2 = st3[j].str.split('_',expand=True)

    str2.columns = ["用户ID", "评分"]

    str3 = pd.concat([df,str2],axis=1)

    df_empty = pd.concat([df_empty,str3],axis=0)

df_empty = df_empty.groupby(['电影ID',"用户ID", "评分"]).all()

df_empty = df_empty.reset_index()

df_empty2 = df_empty.drop(df_empty[df_empty['评分']=='0.0'].index)

df_empty2

正在上传…重新上传取消

4、step4:这一步模拟mapreduce执行对应用户的评分乘以相应地相似度的到推荐评分,根据第2步和第3步的结果进行完成

df_empty3 = pd.DataFrame(columns=['用户ID', "电影ID", "推荐评分"])

df_empty3

正在上传…重新上传取消

for i in range(0,len(df_empty1)):

    n1 = df_empty1.iloc[i][1]

    for j in range(0,len(df_empty2)):

        n2 = df_empty2.iloc[j][1]

        if(n1==n2):

            n3 = float(df_empty1.iloc[i][2])*float(df_empty2.iloc[j][2])

            a1 = str(df_empty1.iloc[i][0])

            a2 = str(df_empty2.iloc[j][0])

            a3 = str(n3)

            df_empty3 = df_empty3.append({'用户ID':a1,'电影ID':a2,'推荐评分':a3},ignore_index=True)        

df_empty3

正在上传…重新上传取消

对用户ID、电影ID、以及推荐评分做一个可视化展示

正在上传…重新上传取消

5、step5:根据第4步的结果,选取每位用户推荐评分最高的电影进行可视化展示

根据第四步的结果,对用户ID进行分组,然后求出评分最高的值

max = df_empty3.groupby("用户ID")["推荐评分"].max()

max = max.sort_index()

max = max.reset_index()

max

正在上传…重新上传取消

根据用户ID和推荐评分,找出最好的推荐电影

df_empty4 = pd.DataFrame(columns=["用户ID", "推荐的电影ID"])

df_empty4

正在上传…重新上传取消

根据前面获得的用户ID以及对应的最高评分,获取相对应的电影ID,并推荐给用户

for i in range(0,len(max)):

    for j in range(0,len(df_empty3)):

        if (max.iloc[i][0]==df_empty3.iloc[j][0])&(max.iloc[i][1]==df_empty3.iloc[j][2]):

            a1 = str(max.iloc[i][0])

            a2 = str(df_empty3.iloc[j][1])

            df_empty4 = df_empty4.append({'用户ID':a1,'推荐的电影ID':a2},ignore_index=True)

            # print(a1,a2)

df_empty4 = df_empty4.groupby('用户ID').first()

df_empty4 = df_empty4.reset_index()

df_empty4

正在上传…重新上传取消

对用户的最高的推荐评分进行可视化展示

max = max['推荐评分'].astype(float)

max.plot.bar(x='用户ID',y='推荐评分')

正在上传…重新上传取消

5 结果与分析

5.1 电影排名功能展示

5.1.1  mapreduce实现电影排名功能展示图

1、电影分组结果展示如图5.1所示,数据类型为(电影ID,用户ID,评分)

 

图5.1 电影分组效果图

2、电影求平均值结果展示如图5.2所示,数据类型为(电影ID,用户ID,评分)

 

图5.2 电影求平均值效果图

3、电影排序结果展示如图5.3所示,数据类型为(电影ID,评分)

正在上传…重新上传取消

 

5.1.2  pandas实现电影排名功能展示图

1、电影分组结果展示如图5.4所示,数据类型为(电影ID,用户ID,评分)

 

图5.4 电影排序效果图2

取电影ID前20的进行柱状图展示

 

图5.5 电影分组柱状图

2、电影求平均值结果展示如图5.6所示,数据类型为(电影ID,评分)

 

图5.6 电影求平均值效果图2

 

图5.7 电影排序柱状图

3、电影排序结果展示如图5.8所示,数据类型为(电影ID,评分)

 

图5.8 电影排序效果图2

5.2 电影推荐功能展示

5.2.1  mapreduce实现电影推荐功能展示图

1、电影推荐——根据用户分组结果展示如图5.9所示,数据类型为(用户ID,电影ID_评分)

 

图5.9 用户分组效果图

2、电影推荐——求出用户与用户之间相似度结果展示如图5.10所示,数据类型为(用户ID,用户ID _相似度)

 

图5.10 用户与用户之间相似度效果图

3、电影推荐——根据电影ID进行分组结果展示如图5.11 所示,数据类型为(用户ID,用户ID _相似度)

 

图5.11 电影ID进行分组效果图

4、电影推荐——根据第二部和第三步的结果进行相乘得出最终结果展示如图5.12所示,数据类型为(用户ID,电影ID_推荐评分)

 

图5.12 电影最终评分效果图

5、电影推荐——根据最终推荐评分进行展示结果如图5.13所示,数据类型为(用户ID,电影ID_推荐评分)

 

图5.13 电影最终评分排序效果图

5.2.2  pandas实现电影推荐功能展示图

1、电影推荐——根据用户分组结果展示如图5.14所示,数据类型为(用户ID,电影ID_评分)

 

图5.14 用户分组效果图2

选取用户ID为1的各列进行分析,再按照评分进行排序,最后随机选取10列数据进行柱状图展示如图5.15所示

 

图5.15 用户分组柱状图1

统计每一位用户所观看的电影数目,并用柱状图展示,如图5.16所示:

 

图5.15 用户分组柱状图2

2、电影推荐——求出用户与用户之间相似度结果展示如图5.16所示,数据类型为(用户ID,用户ID,相似度)

 

图5.16 用户与用户之间相似度效果图

对用户ID和另外的用户ID以及他们之间的相似度进行可视化展示,如图5.17所示:

 

图5.17 用户相似度可视化图

3、电影推荐——根据电影ID进行分组结果展示如图5.18 所示,数据类型为(用户ID,用户ID _相似度)

 

图5.18 电影ID进行分组效果图

4、电影推荐——根据第二部和第三步的结果进行相乘得出最终结果展示如图5.19所示,数据类型为(用户ID,电影ID_推荐评分)

 

图5.19 电影最终评分效果图

对用户ID、电影ID、以及推荐评分做一个可视化展示,如图5.20所示:

 

图5.20 电影最终评分可视化图

5、电影推荐——根据最终推荐评分进行展示结果如图5.21所示,数据类型为(用户ID,推荐评分)

 

图5.21 电影推荐评分效果图

根据最终推荐评分进行推荐展示结果如图5.22所示,数据类型为(用户ID,推荐电影)

 

图5.22 电影推荐电影效果图

对用户的最高的推荐评分进行可视化展示如图5.23所示:

 

图5.23 电影推荐评分可视化图

6 学习体会

6.1 遇到问题和解决方法

因为这学期刚好学了hadoop和数据导入与预处理两门课程,所以我决定将这两门课程结合起来做一个基于MapReduce+Pandas的电影排名与推荐以及数据分析与可视化展示。数据用的是网上找的数据。在这次课设中,我们遇到了很多问题,因为这次课设中还用到了协同过滤算法,采用两个向量夹角的余弦值作为相似度的计算,比其它的算法简单,高效,高级。在课设期间遇到了很多问题,通过自我修改、查阅相关资料结合实际情况进行修正。再比如数据分析目的不明确,分析思路不明确,对于函数使用不够灵活,描述性分析不太理解等等。我的解决方法是,把老师提供的案例中的代码好好敲了一下,多加练习,问题也就迎刃而解。

6.2 收获与感悟

  通过本次大作业,我收获了很多。懂得了数据处理的流程,以及数据预处理的思想,也学会了pandas中各种函数的使用,其次是数据分析的思想,利用多个方面进行分析,开阔了我的思维,最后的可视化又打开了我图形化界面的大门,总之,做了这个大作业,我收获良多。在课设中遇到问题是很正常的,只要设计者具有冷静思考,善于分析的能力,就一定可以解决任何问题。此次课设帮助我们更加理解这一学期学到的知识,并且深刻认识到只学习书本上的知识是远远不够。实践是检验真理的唯一指标,只要亲自动手实践了后,才会更加深入的去理解它,消化它。

参考文献

[1]赵恩毅,王瑞刚.基于Hadoop平台的聚类协同过滤推荐方法研究[J].计算机与数字工程,2019,47(10):2529-2533+2588.

[2]张鹏程. 推荐算法自动选择框架的研究与实现[D].沈阳师范大学,2019.

[3]陈旭. 基于Hadoop的电影推荐系统的研究与实现[D].辽宁大学,2019.

[4]汪晶. 基于聚类的协同过滤推荐算法研究[D].长江大学,2019.

[5]张玉叶.基于协同过滤的电影推荐系统的设计与实现[J].电脑知识与技术,2019,15(06):70-73.

[6]陶华平. 基于Hadoop的电影推荐系统的设计与实现[D].大连理工大学,2018.

[7]李沂桥. 基于Hadoop平台的电影推荐系统的设计与实现[D].贵州大学,2018.

[8]wesley J.Chun.Python核心编程(第二版[M.人民邮电出版社,2012.

[9]蔡立,量化投资以 python为工具[M,电子工业出版社,2017

[10]吴升.大数据平台中数据分析工具的设计与实现[D].东南大学硕士论文,2015

  • 19
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值