原标题:【Python数据科学实战项目】之 基于MovieLens的影评趋势分析|详解

注:图片源于https://movielens.org/

1. 项目任务

1.1 数据来源

本项目使用GroupLens Research收集的MovieLens网站电影评分数据集进行分析

该数据集发布于2015年4月,包含2000多万条评分数据、2.7万部电影数据、46.5万个电影类型标签数据及13.8万位用户数据

本项目对该数据集中的movies及ratings两个csv数据文件进行分析

该数据集下载地址为:https://grouplens.org/datasets/movielens/

1.2 分析目的

分析得出主要电影类型(如电影数量300万以上的电影类型)

分析主要电影类型评分的变化趋势

分析主要电影类型评分变化趋势之间的联系

分析用户对不同类型电影评分之间的关系强度

1.3 分析问题

不同类型电影的平均评分变化趋势:

主要电影类型的平均评分如何变化?

对不同类型电影的平均评分进行比较会有什么发现?

不同类型电影平均评分变化趋势之间的关联程度:

不同类型电影平均评分的变化趋势之间有关联吗?

比如,喜剧片(Comedy)和冒险片(Adventure)等其他电影类型的得分之间是正相关?关联强度怎么样?

2. 项目步骤

2.1 导入包

import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport seaborn as sns

2.2 数据读取

为了方便查阅,本项目使用魔法命令(以%开始)将matplotlib图表直接嵌入在Notebook之中

% matplotlib inline

用Pandas包的read_csv()函数分别将文件movies.csv和ratings.csv读入至对应的DataFrame变量中

movies=pd.read_csv('MovieLens/movies.csv')ratings=pd.read_csv('MovieLens/ratings.csv')

显示movies的前5行数据

movies.head(5)

查看movies维度(形状)

movies.shape(27278, 3)

显示ratings的前6行数据

ratings.head(6)

查看ratings维度(形状)

ratings.shape(20000263, 4)

查看ratings的统计性描述信息

ratings.describe()

2.3 数据规整化

2.3.1 movies数据规整化处理

movies数据需要进行规整化处理(Data Tidying),原因在于genrens列不符合规整数据的基本原则

规整化处理的方法与步骤:

[1].以电影所属类型(genres)及符号’|’为依据进行分割;

[2].如果一个电影有多个类型(genres),将分割成多个列表(List);

[3].将分割后得到的多个列表(Lists)转换为一个数据框(DataFrame);

[4].将数据框的索引设置为movieId

movies_tidy1=pd.DataFrame(movies.genres.str.split('|').tolist(),index=movies.movieId)

显示movies_tidy1的前3行

movies_tidy1.head(3)

[5].按规整化数据的基本原则,采用stack()函数进行重构,并重新设置行索引

注:重新设置行索引后,原来的行索引保留为movieId列

movies_tidy2=movies_tidy1.stack().reset_index()

显示movies_tidy2的前10行

movies_tidy2.head(10)

[6].删除level_1列,将columns为0的列重命名为genres,并重新定义数据框为movies_genres

movies_genres=movies_tidy2.drop('level_1',axis=1).rename(columns={0:'genres'})movies_genres.head()

[7].将原movies数据中的genres列替换成movies_genres,得到规整化处理后的movies数据

movies=pd.merge(movies.drop('genres',axis=1),movies_genres)movies.head()

查看movies维度(形状)

movies.shape(54406, 3)

2.3.2 ratings数据规整化处理

[1].查看ratings头部数据

ratings.head()

[2].格式化时间戳为本地时间,并输出为4位数年份

import timeratings['timestamp']=ratings['timestamp'].apply(lambda x: time.strftime('%Y', time.localtime(x)))ratings.head()

2.3.3 定义新的数据集movie_ratings

基于规整化处理后的movies和ratings,构建电影评分数据集movie_ratings

[1].去掉movies中的title列,得到新movies

[2].合并新movies与ratings,连接键为movieId

[3].得到新的数据框movie_ratings

[4].显示数据框movie_ratings的前5行

movie_ratings=ratings.merge(movies.drop('title',axis=1),on='movieId',how='inner')movie_ratings.head()

[5].查看movie_ratings的维度

movie_ratings.shape(53177059, 5)

计算movies_ratings中不同类型电影的频数

[1].按genres列进行分组处理

[2].计算movieId的频数

[3].按movieId的频次进行降序

movie_ratings.groupby(['genres'],as_index=False)['movieId'].count().sort_values( by='movieId',ascending=0)

[4].过滤movie_ratings中数量在300万以下的电影种类

movie_ratings=movie_ratings.loc[movie_ratings['genres'].isin(['Drama','Comedy','Action','Thriller','Adventure','Romance','Crime','Sci-Fi'])]movie_ratings.head()

[5].查看movie_ratings的维度

movie_ratings.shape(41918630, 5)

2.4 数据分析及可视化

2.4.1 基本统计分析

计算不同电影类型的年度平均评分

方法:按年份、类型进行分组,并计算各组的均值,将timestamp列名更改为year

mean_ratings=movie_ratings.groupby(['timestamp','genres'],as_index=False)['rating'].agg(np.mean)mean_ratings.rename(columns={'timestamp':'year'},inplace=True)mean_ratings.head()

统计年度不同电影类型的标准差

方法:按年份、类型进行分组,并计算各组的标准差,将timestamp列改名为year

sd_ratings=movie_ratings.groupby(['timestamp','genres'],as_index=False)['rating'].agg(np.std,ddof=1)sd_ratings.rename(columns={'timestamp':'year'},inplace=True)sd_ratings.head()

2.4.2 变化趋势分析

对不同类型电影平均评分的时间变化趋势进行分析

方法:按'movieId','timestamp','genres'进行分组,并计算各组平均值

mg_ratings=movie_ratings.groupby(['movieId','timestamp','genres'],as_index=False)['rating'].aggregate(np.mean)mg_ratings.rename(columns={'timestamp':'year'},inplace=True)mg_ratings.rename(columns={'rating':'mg_rating_mean'},inplace=True)mg_ratings.head()

可视化:绘制不同类型电影平均评分的变化趋势图

sns.set(font_scale=1,rc={'lines.linewidth':0.5,'figure.figsize':(10,7)})sns.pointplot(x='year',y='mg_rating_mean',hue='genres',data=mg_ratings,palette='tab10')

对比分析不同时间段内的评分变化情况

方法:选取1996-2000及2011-2015两个五年时间段进行分析

ratings_9600=mg_ratings.loc[mg_ratings['year'].isin(['1996','1997','1998','1999','2000'])]ratings_1115=mg_ratings.loc[mg_ratings['year'].isin(['2011','2012','2013','2014','2015'])]

用小提琴图可视化1996-2000年间8种电影类型平均评分的分布

sns.set(font_scale=1,rc={'lines.linewidth':0.5})sns.violinplot(x='year',y='mg_rating_mean',hue='genres',data=ratings_9600,palette='rainbow_r')plt.legend(bbox_to_anchor=(1.2,0.5),loc=7)

用箱线图可视化2011-2015年间8种电影类型平均评分的分布

sns.set(font_scale=1,rc={'lines.linewidth':0.5})sns.boxplot(x='year',y='mg_rating_mean',hue='genres',data=ratings_1115,palette='Set2')plt.legend(bbox_to_anchor=(1.2,0.5),loc=7)

2.4.3 关联程度分析

对不同电影类型之间用户平均评分的关联程度进行分析

[1].按'userId','genres'进行分组,并计算每组平均分,结果存放在数据框ug_ratings

ug_ratings=movie_ratings.groupby(['userId','genres'],as_index=False)['rating'].aggregate(np.mean)ug_ratings.rename(columns={'rating':'ug_rating_mean'},inplace=True)ug_ratings.head()

[2].可视化不同类型电影用户平均评分的分布图

sns.set(style='darkgrid')g=sns.FacetGrid(ug_ratings,col='genres',sharey=False,size=5)g.map(sns.distplot,'ug_rating_mean',bins=10).set(xlim=(0,6),xticks=[1,2,3,4,5,6])

[3].对数据框ug_ratings进行重构操作(reshape),生成对应的透视表

pivot=ug_ratings.pivot(index='userId',columns='genres',values='ug_rating_mean')pivot.head()

[4].通过关联图分析关联程度

4.1 绘制Comedy,Adventure两种类型电影评分的联合图,分析关联程度

sns.jointplot('Comedy','Adventure',pivot,kind='reg',color='g')

4.2 绘制Comedy,Drama两种类型电影评分的联合图,分析关联程度

sns.jointplot('Comedy','Drama',pivot,kind='reg',color='b')

4.3 绘制 Comedy,Romance 两种类型电影评分的联合图,分析关联程度

sns.jointplot('Comedy','Romance',pivot,kind='reg',color='r')

4.4 绘制 Comedy,Thriller 两种类型电影评分的联合图,分析关联程度

sns.jointplot('Comedy','Thriller',pivot,kind='reg',color='g')

4.5 绘制Comedy,Action两种类型电影评分的联合图,分析关联程度

sns.jointplot('Comedy','Action',pivot,kind='reg',color='b')

4.6 绘制 Comedy,Crime 两种类型电影评分的联合图,分析关联程度

sns.jointplot('Comedy','Crime',pivot,kind='reg',color='g')

4.7 绘制 Comedy,Sci-Fi 两种类型电影评分的联合图,分析关联程度

sns.jointplot('Comedy','Sci-Fi',pivot,kind='reg',color='r')

3. 结果分析

3.1 变化趋势分析

电影数量超过300万的主要电影类型有8种:戏剧(Drama)、喜剧(Comedy)、动作(Action)、惊悚(Thriller)、冒险(Adventure)、爱情(Romance)、犯罪(Crime)和科幻(Sci-Fi);

上述8种主要电影类型的平均评分在1996-1998年间均呈下降趋势,之后变化平稳,平均评分均低于3.5分;

1995-2015年间,科幻(Sci-Fi)类电影的平均评分一直最低,动作(Action)类电影的平均评分也比较低;

1995-2015年间,戏剧(Drama)、爱情(Romance)、犯罪(Crime)三种类型电影的平均评分最高。

注:图片源于网络

3.2 关联程度分析

喜剧(Comedy)类电影与其他7种电影类型的得分之间均呈现正相关关系;

喜剧(Comedy)与爱情(Romance)的得分关联程度最高,相关系数达0.72;

喜剧(Comedy)与科幻(Sci-Fi)的得分关联程度最低,相关系数为0.55。

END

【注释】

本文是在Sandipan Dey分析工作的基础上,进行了如下改进:

1.通过数据分析确定主要电影类型(原文没有给出电影类型选择依据)

2.提供了每个步骤的全套源代码(原文没有提供全部代码)

3.对文字解释部分进行了翻译和优化(原文部分地方为灰色难点)

4.对源代码和注释部分进行了优化(原文的源代码和注释需要优化)

5.将原文翻译成中文(原文为英文)

python计算各类型电影的评分_【Python数据科学实战项目】之 基于MovieLens的影评趋势分析|详解...相关推荐

  1. 基于点击量的趋势分析python_【Python数据科学实战项目】之 基于MovieLens的影评趋势分析详解...

    原标题:[Python数据科学实战项目]之 基于MovieLens的影评趋势分析详解 本文转自: 数据科学DataScience 注:图片源于https://movielens.org/ 1. 项目任 ...

  2. python计算各类型电影的评分_python(15)-pandas-多类型统计-电影分类问题

    1.情境描述:用于电影分类,一个电影可以属于好几类. 按类型统计片子数. 2.实现步骤:读文件->统计分类->全0数组(行,列)->赋值为1->各列求和 3.知识点: 3.1嵌 ...

  3. ajax将数据显示在class为content的标签中_[原创]数据可视化实战项目

    数据可视化实战项目 NLP 数据可视化 request BeautifulSoup #爬虫所需import requestsfrom bs4 import BeautifulSoup# Nlp可视化所 ...

  4. python计算在月球的体重程序_# Python程序语言设计基础(第二版)程序练习题

    Python程序语言设计基础(第二版)程序练习题 3.1 重量计算,月球上物体的体重是在地球上的16.5%,假如你在地球上每年增长0.5kg,编写程序输出未来10年你在地球和月球上的体重状况. cur ...

  5. python主成分对变量的贡献率_(数据科学学习手札20)主成分分析原理推导Python自编函数实现...

    主成分分析(principal component analysis,简称PCA)是一种经典且简单的机器学习算法,其主要目的是用较少的变量去解释原来资料中的大部分变异,期望能将现有的众多相关性很高的变 ...

  6. TTL怎么计算拉电流和灌电流_配电线路安全电流如何计算?低压供电线路导线怎么选择?图文详解...

    导线截面导线的截面通常是由发热条件.机械强度.经济电流密度.电压损失和导线长期允许安全载流量等因素决定的.但从节约能源的原则出发,应将"电能损耗大小"作为选择导线截面的首要依据. ...

  7. 宝藏网站!机器学习概念可视化;LeetCode面试必看清单;104个Python数据科学实战项目;必应超清壁纸;前沿论文 | ShowMeAI资讯日报

    ShowMeAI日报系列全新升级!覆盖AI人工智能 工具&框架 | 项目&代码 | 博文&分享 | 数据&资源 | 研究&论文 等方向.点击查看 历史文章列表, ...

  8. Python计算两个numpy数组的交集(Intersection)实战:两个输入数组的交集并排序、获取交集元素及其索引、如果输入数组不是一维的,它们将被展平(flatten),然后计算交集

    Python计算两个numpy数组的交集(Intersection)实战:两个输入数组的交集并排序.获取交集元素及其索引.如果输入数组不是一维的,它们将被展平(flatten),然后计算交集 目录

  9. 数据科学学习心得_学习数据科学时如何保持动力

    数据科学学习心得 When trying to learn anything all by yourself, it is easy to lose motivation and get thrown ...

最新文章

  1. python类方法以及类调用实例方法的理解
  2. BigInteger和BigDecimal类
  3. vs2015_ef 连接mysql
  4. flume-elasticsearch-sink indexName
  5. eclipse adt for linux,Eclipse IDE,ADT对于Android SDk错误
  6. 独家 | 2021双11背后的数据库硬核科技
  7. python如何全网爬取_如何通过Python爬取互联网
  8. 16进制 hbase phoenix_HBase 和 Phoenix 的使用
  9. 在Ubuntu下用桌面图形界面挂载分区
  10. delphi生产者消费者模式代码_并发设计模式:生产者-消费者模式,并发提高效率...
  11. java和c的反汇编_JAVAP -C反汇编指令的学习(转载)
  12. 区块链技术人才严重不足,平均薪资 2.58 万
  13. 【java学习之路】(java SE篇)010.多线程
  14. hibernate+spring+struts集成,并自动生成实体类和DAO层的步奏
  15. (转)比特币基金难产 区块链基金成首发
  16. 微信支付商户平台 —公立医院申请
  17. ureport2报错/by zero的解决方法
  18. Linux界面美化---Zsh终端
  19. 微信开发五之微信红包开发
  20. ZStack-ZCCE-网络实验-VPC网络创建

热门文章

  1. 解决 Hadoop 启动 ERROR: Attempting to operate on hdfs namenode as root 的方法
  2. Freeline体验
  3. 使用 Freeline 纪录篇
  4. 网页中嵌入Flash的方法讨论
  5. 初次尝试ESP8266带CH340串口开发板踩过的坑
  6. 盖档案骑缝章的样本_盖印鉴骑缝章的技巧 涨知识了
  7. 计算机组成原理 扩展指令的操作码,【计算机组成原理】指令系统
  8. 苹果官方鼠标移动速度慢问题解决(Magic Mouse)2021-07-29
  9. RPC-BDY(4)-nacos注册中心
  10. 通过给CC2540刷固件的方式使用抓包软件smartRF packet sniffer