数据分析学习之路——(五)用数据告诉你电影的市场趋势

2023-11-13

        随着社会的多元化,越来越多的影视作品走入人们的生活中。但是近年来鲜有几部新制作的电影能俘获观众的心,到底是观众越来越挑剔,还是电影作品本身不够吸引力?如果你是有一个电影公司,你想制作一部电影作品,你有想过拍一部什么样的电影吗?你会选择一名什么样的导演呢?这里由Movie Database网站提供了一份数据集,主要包括1960-2015年上映的部分电影的样本集。这是UdaCity其中一个项目——tableau可视化的提供的数据集(点击链接到我的tableau可视化图形主页可以点击页面下方元数据查看不同的分析维度),我自己用Python以及统计知识再实现一遍。

数据探索

数据集一共包含了十多个字段:

        004844_CgRb_3642529.png

每个字段意义如下:

        004927_g4wD_3642529.png

数据清理

        首先用pandas库读取数据,然后我发现数据有一行是重复的,因此先要去重,同时筛选出对我们分析过程有意义的字段:

movies= movies.drop_duplicates(subset='id',keep='first')[['id','cast','director','genres','production_companies','vote_average','release_year','revenue_adj','keywords','original_title']]  # 42194重复    

        通过观察数据,会发现director、genres等字段包含了多个分类,并以"|"隔开的,因此先定义两个方法把这些拆分出来,在聚合到原DataFrame。

def def_split(movies,key):
    '''
     key为'genres'、'production_companies'等,按'|'分隔,加上expand=True会根据key聚合到数据框
    '''
    movies = movies.drop(key, axis=1).join(
        movies[key].str.split('|', expand=True).stack().reset_index(level=1, drop=True).rename(key))   
    movies = movies[[key,'id','vote_average','release_year','revenue_adj','original_title']]                  # 再次过滤我们需要的字段
    movies = movies[movies['revenue_adj']>0]                                                                  # 部分电影收入为0, 给其赋值会影响统计结果,因此过滤掉
    if key== 'production_companies':
        movies= movies[(movies[key]=='Universal Pictures') | (movies[key]=='Paramount Pictures')]             # 如果key值为production_companies(制作公司),只选取Universal Pictures # 和Paramount Pictures这两个公司进行对比分析
    return movies[[key,'id','vote_average','release_year','revenue_adj','original_title']]
def keywords_split(movies):
    '''
    当判断影片是否根据小说改编时,需要新增一列,再根据这一列的数据分组分析
    '''
    movies = movies[['keywords', 'id', 'vote_average', 'release_year', 'revenue_adj']].dropna()
    movies['novel'] = movies['keywords'].map(lambda x:'based on novel' if 'based on novel' in x else 'not based on novel')
    # 这方法很无敌,搭配匿名函数lambda,map方法直接将新值映射到Series。也可以使用下面的常规方法,易懂但代码量多些
    '''
    index=movies['keywords'].index
    arr=[]
    for key in movies['keywords']:
        if 'based on novel' in key:
            arr.append('based on novel')
        else:
            arr.append('not based on novel')
    movies['novel'] = Series(arr,index=index)
    '''
    movies = movies[movies['revenue_adj'] > 0]
    return movies[['id', 'vote_average', 'release_year', 'revenue_adj','novel']]

        我从四个维度来分析趋势,因此新建四个数据集,后文分析都基于这四个数据集:

movies_genres=def_split(movies,'genres')                                      # 按照电影分类(电影题材)
movies_production_companies=def_split(movies,'production_companies')          # 按照制作公司,Universal Pictures与Paramount Pictures对比分析
movies_director=def_split(movies,'director')                                  # 按照导演
movies_novel=keywords_split(movies)                                           # 按照剧本分类(按是否由小说改编分为改编和原创剧本)

数据分析过程

1.  电影题材的发展趋势

movies_genres.groupby(['genres','release_year'])['genres'].count().unstack('genres').plot()

        195211_ipDs_3642529.png

        很明显戏剧(Drama)、喜剧(Comedy)和惊悚(Thriller)三种类型的电影越来越受导演青睐,因为这三类电影增长的数量是最快。

movies_genres.groupby(['genres'])['vote_average'].mean().plot(kind='bar')

        195442_aWGi_3642529.png

        不同题材电影的评分差距不太大,经过平均下来看,都保持在6分左右。

movies_genres.groupby(['genres','release_year'])['revenue_adj'].sum().unstack('genres').plot()

        195848_qEGW_3642529.png

        但是对于电影收入来讲,对比则很能说明问题了,动作(Action)和冒险(Adventure)题材类的电影挣钱最多,而这两类电影的拍摄数量不算是最多的,说明这两类电影很卖座,票房都比较高。而类似于战争(War)和西部(Western)两种题材的电影既不卖座,大众接受度也不高,因此有被淘汰的趋势。

2.  电影公司Universal Pictures 与 Paramount Pictures对比

# 需要分析电影制作公司对不同电影题材的喜好,因此将电影分类的数据合并在一起
movies_production_companies=pd.merge(movies_production_companies,movies_genres,how='left') 
movies_production_companies.groupby(['production_companies','genres'])['production_companies'].count().unstack('production_companies').plot(kind='bar')

        200214_xZPI_3642529.png

        两个公司都在喜剧(Comedy)、动作(Action)、戏剧(Drama)以及惊悚(Thriller)题材投入了较多资源,拍摄的电影数量比其他题材要多很多,但在仔细看一下,发现Universal Pictures总是略胜一筹,几乎每个题材所拍摄的影片都比Paramount Pictures要多,但优势不太大。

movies_production_companies.groupby(['production_companies','genres'])['revenue_adj'].sum().unstack('production_companies').plot(kind='barh')

        200831_xfjC_3642529.png

        两个公司拍摄的不同题材电影,给公司带来主要收入的依然是动作(Action)、冒险(Adventure)、戏剧(Drama)、喜剧(Comedy)和惊悚(Thriller)这几类主要题材的影片,两个公司的表现情况也是差距不大。Universal Pictures 和 Paramount Pictures两制作公司无论是在尝试制作不同题材的电影方面,还是电影对公司的营收,亦或是观众对两个公司电影的接受程度,都表现出相当的一致性,因此我们有理由认为,两个公司旗鼓相当!

3.  改编电影与原创电影对比

movies_novel.groupby(['novel','release_year'])['novel'].count().unstack('novel').plot()

        201442_skar_3642529.png

        总体来讲,电影公司还是会选择拍摄原创剧本的电影,仅仅会选择少量的小说进行翻拍。由于小说剧本的限制或者是导演对于重现小说情节场景把握不住方向等原因,一般导演不会直接选择已有的小说等剧本,更多的选择是新编剧本。随着时间的推移,这种选择导致的对比效果越来越明显。

movies_novel.groupby(['novel','release_year'])['vote_average'].mean().unstack('novel').plot(kind='line')

        201838_kakV_3642529.png

        也许是因为小说自身的经典,再加上导演完美的呈现,我们会发现,通过改编的电影评分会比原创电影要高一些。改编电影评分起伏较大,这个应该是跟电影还原小说剧情、内涵有很大关系,但是总体还是比原创的电影略胜一筹。

4.  寻找最佳导演

director={}                                                                                # 构造字典格式生成云图
movies_director = movies_director.groupby('director')['id'].apply(lambda x:x.count())      # 计算每一位导演执导电影的数量
for i in range(len(movies_director)):
    director[movies_director.index[i]] = float(movies_director.ix[i])                      # {A:xx, B:xx, C:xx}
wordcloud=WordCloud(font_path='C:/Users/Nekyo/tools/SOFTWARE/Anaconda2/Library/lib/fonts/songti.ttf',
                    width=1000,height=600,background_color='white')                        # 云图使用的汉字字体,自带的字体库没有需要下载
wordcloud.fit_words(director)
plt.imshow(wordcloud)

        202837_cW5R_3642529.png

        云图的优势在于很容易就能看到需要的信息,斯皮尔伯格等几位名导拍摄的电影远多于其他导演。

movies_director = movies_director[(movies_director['director']=='Ridley Scott') | (movies_director['director']=='Steven Spielberg') |
                                  (movies_director['director']=='Clint Eastwood') |(movies_director['director']=='Woody Allen')]
movies_director.groupby(['director','release_year'])['revenue_adj'].sum().unstack('director').plot(kind='bar', stacked=True)
movies_director.groupby(['genres','director','release_year'])['revenue_adj'].sum().unstack(['genres']).plot(kind='bar', stacked=True)

        203135_C5hw_3642529.png

        203849_RTeY_3642529.png

        在这个数据集中,我发现有4名导演执导的电影在20部以上,但是相较于其他三位来讲,斯皮尔伯格无异于更出色。如果我们计算历年电影所带来的收入,或者是平均计算每一部影片的收入,斯皮尔伯格确确实实将其他三位远远抛在了后面;至于他们四位涉足的不同题材的电影,通过上面的收入对比,第三幅小图表现出的结果——斯皮尔伯格无疑是碾压性的。也就是说,观众还是更买斯皮尔伯格的账,他绝大部分的电影票房都超过了其他电影,唯一我们能一眼看出来的就只有2001和2015年输给了Ridley Scott的《汉尼拔(Hannibal)》和《火星救援(The Martian)》,但是仍然影响不了斯皮尔伯格在电影票房的霸主地位。

movies_director = movies_director[movies_director['director']=='Steven Spielberg']                # 只看Steven Spielberg
movies_director = pd.merge(movies_director,movies_genres,how='left')                              # 分析Steven Spielberg拍摄的电影题材
movies_spielberg =  movies_director[['director','original_title','vote_average','revenue_adj']].drop_duplicates()
movies_spielberg.plot(x='vote_average',y='revenue_adj',kind='scatter')
for i in range(len(movies_spielberg)):
    plt.text(movies_spielberg.iloc[i]['vote_average'], movies_spielberg.iloc[i]['revenue_adj'], 
        movies_spielberg.iloc[i]['original_title'], ha='center', va='bottom')                     # 标记

        204716_zqjY_3642529.png

        至于斯皮尔伯格执导的电影,当属经典中的经典,无论是票房神话《大白鲨(Jaws)》、《E.T. 外星人(E.T. the Extra-Terrestrial)》、《侏罗纪公园(Jurassic Park)》,还是评分超神的《辛德勒名单(Schindler's List)》都给我们留下了深刻的印象,也是其他导演难以逾越的高峰,更是电影史上灿烂的瑰宝。

统计分析

        提个问题,如果单独把斯皮尔伯格执导的电影拿出来分析,他是否代表了这个行业的平均水平?其实这问题很简单,明显高于啊。那么我们用统计的思想从电影评分和收入来分析下。我把整个数据集看作一个整体,斯皮尔伯格执导的电影看作一个独立样本(这里不是随机的哈),我们可以计算出整体的均值,样本的均值、方差,并且样本的数量时28<30,因此我选择单尾t检验来检验上述猜测。

零假设H0:斯皮尔伯格代表了这个行业的平均水平,212042_kqv6_3642529.png  ;对立假设H1:斯皮尔伯格高于这个行业的平均水平,212138_Taub_3642529.png

movies = movies[movies['revenue_adj']>0]
movies_spielberg = movies_director[movies_director['director']=='Steven Spielberg']
sp_mean=movies_spielberg['vote_average'].mean()
mo_mean=movies['vote_average'].mean()
sd = np.sqrt(((movies_spielberg['vote_average'] - movies_spielberg['vote_average'].mean())**2).sum()/(28-1))  # 求标准偏差,这里不能直接用np.var()
t=(sp_mean-mo_mean)/(sd/np.sqrt(28-1))

        取显著性水平alpha=0.05,自由度v=28-1=27,查t表格得到t值为1.703,而我们计算出来的结果如下:

        214115_nLaf_3642529.png

        计算得到的t统计量为4.85578>1.703,因此拒绝零假设,认为斯皮尔伯格的电影评分与整个行业的平均水平显著性不同,要高一些。

        使用更高级的方法,引入scipy库的统计方法,对评分字段进行单样本检验,得到的结果:

print ttest_1samp(a=movies_spielberg['vote_average'], popmean=mo_mean)

        214820_a6yo_3642529.png                             

        跟上面方法分析的结果一致,p值要比0.05小,位于拒绝域内,接受对立假设。同样针对电影的收入,也可以用同样的方法检验,这里不再赘述。

结论

        尽管这个样本不能代表整个电影数据,但是通过这样的分析我们能够了解大概的趋势。如果你拥有一个电影公司想制作一部电影并且想收获不菲的票房成绩,一些小众题材的剧本就不要选择了,最好选择时下热门的动作、喜剧类电影;尽量选择原创剧本,除非你要改编的剧本本身就特别好,比如复仇者联盟漫画系列,否则还是建议你请一个好的编剧;最后一定要记住,一个优秀的导演至为重要,用现在影视行业流行的话来讲,大IP呀!想好怎么做了吗,Good luck!

转载于:https://my.oschina.net/nekyo/blog/1554676

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据分析学习之路——(五)用数据告诉你电影的市场趋势 的相关文章

随机推荐

  • 我一个专科生,在上海打拼10年才拿到20k的月薪,普通人逆袭有多难?

    自我介绍 我是专科毕业 在原来的领域深耕近十年又考虑转行 有家庭有娃 有房贷 所以我认为这可能代表了一类人 代表哪一类人群呢 你看 学历一般 能力有限 在大城市打拼多年又难以留下来 处在职业生涯的瓶颈期 又处在人生道路的迷茫期 就是这类人
  • codeforces 1169 D. Good Triple

    题意 有长为n的串 其中有几个 ll rr 符合条件 首先 长度超过9的串一定符合条件 枚举左端点ll 右端点控制在ll 8就行 剩下的直接加 include
  • UNIX环境高级编程 学习笔记 第十五章 进程间通信

    进程间通信可通过传送打开的文件 也可以经由fork和exec函数来传送 还可以通过文件系统传送 IPC InterProcess Communication 进程间通信 是进程通信方式的统称 不同UNIX系统支持的IPC形式不同 虽然SUS
  • net::ERR_CONNECTION_REFUSED,Network Error

    net ERR CONNECTION REFUSED 项目部署服务器后报如图所示错误 但在本地调用后台RESRful接口数据没问题 最后发现是tomcat服务器没有开 开了后没有再次执行命令使后台运行 其实这个问题从两点能够发现 一是执行n
  • 解决Anaconda导入第三方包的各种问题

    1 win R win R 输入 HOMEPATH 然后找到 condarc 把里面的内容改为 ssl verify true show channel urls true channels http mirrors tuna tsingh
  • 点云数据做简单的平面的分割 三维场景中有平面,杯子,和其他物体 实现欧式聚类提取 对三维点云组成的场景进行分割

    点云分割是根据空间 几何和纹理等特征对点云进行划分 使得同一划分内的点云拥有相似的特征 点云的有效分割往往是许多应用的前提 例如逆向工作 CAD领域对零件的不同扫描表面进行分割 然后才能更好的进行空洞修复曲面重建 特征描述和提取 进而进行基
  • Qt 事件过滤器 - EventFilter

    事件过滤器 见名之意 就是将事件过滤一遍 将不需要的事件都清除掉 剩下需要的事件进行操作 可能讲得不是很透彻 那就看下图 就很明白了 原本事件应该直接发送给 组件对象 但是现在却先将事件发送给 过滤器对象 经过过滤的事件再发给 组件对象 如
  • xss level11

    Level11 1 2 毫无头绪 查看PHP源代码发现 是从头文件的referer获取的输入 3 用Burp抓包 修改头文件如下 4 再点击Proxy界面的forward 回到浏览器页面如下 5 点击即可 转载于 https www cnb
  • 走进强化学习

    一 什么是强化学习 强化学习是机器学习里面的一个分支 是一个智能体通过不断的与环境产生互动而不断改进它的行为 从而积累最大奖励的一个决策过程 智能体在完成某项任务时 首先通过动作A与周围环境进行交互 在动作A和环境的作用下 智能体会产生新的
  • CUDA 计算线程索引的一般公式

    第一种方法 CUDA thread index int blockId blockIdx z gridDim x gridDim y blockIdx y gridDim x blockIdx x int threadId blockId
  • Couldn‘t resolve host

    Centos6安装完并配置静态ip地址后 发现yum命令下载出现Couldn t resolve host ping www baidu com 出现域名解析错误 百度大部分答案是在 etc sysconfig network script
  • 用java求出1-1/2+1/3-1/4…..1/100的和

    public class sumPractice3 public static void main String args 需求 求出1 1 2 1 3 1 4 1 100的和 分子始终为1 double num 1 定义个变量用来存储计算
  • 三个基于WebRTC开源MCU框架的横向对比

    1 licode 官网地址 http lynckia com licode index html 官方demo地址 https chotis2 dit upm es Github地址 https github com lynckia lic
  • switch的用法

    switch语句 实际生活中 需要做出很多选择 大家都知道做选择可以使用if语句 但是如果选择太多 if语句使用起来就会很繁琐 这个时候就需要一个能将代码简化的语句 也就是我们今天的主角switch语句 switch语句是一个多分支选择语句
  • 【中等】【LeetCode刷题笔记(二十九)】之54.螺旋矩阵

    本文章由公号 开发小鸽 发布 欢迎关注 老规矩 妹妹镇楼 一 题目 一 题干 给定一个包含 m x n 个元素的矩阵 m 行 n 列 请按照顺时针螺旋顺序 返回矩阵中的所有元素 二 示例 示例 1 输入 1 2 3 4 5 6 7 8 9
  • 零基础如何使用IDEA启动前后端分离中的前端项目(Vue)?

    一 在IDEA中配置vue插件 点击File gt Settings gt Plugins gt 搜索vue js插件进行安装 下面的图中我已经安装好了 二 搭建node js环境 安装node js 可以去官网下载 安装过程就很简单 直接
  • 活动预告丨SMP十周年系列论坛第一期:社交机器人论坛开幕

    全国社会媒体处理大会十周年系列论坛 第一期 SMP2021社交机器人论坛 将于2021年11月13日 周六 上午线上举办 旨在探讨社交机器人领域的热点和前沿 探索构建更智能的社交机器人的学术研究和技术方案 人机对话系统是人工智能领域最具挑战
  • LocalDate、LocalDateTime互转String

    目录 1 LocalDate String互转 LocalDate转String String转LocalDate 2 LocalDateTime String互转 LocalDateTime转String String转LocalDate
  • c语言连点器脚本

    include
  • 数据分析学习之路——(五)用数据告诉你电影的市场趋势

    随着社会的多元化 越来越多的影视作品走入人们的生活中 但是近年来鲜有几部新制作的电影能俘获观众的心 到底是观众越来越挑剔 还是电影作品本身不够吸引力 如果你是有一个电影公司 你想制作一部电影作品 你有想过拍一部什么样的电影吗 你会选择一名什