TMDb数据分析报告_第1页
TMDb数据分析报告_第2页
TMDb数据分析报告_第3页
TMDb数据分析报告_第4页
TMDb数据分析报告_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、TMDb 数据分析报告学习python进数据分析段时间了,也跟着书本、上案例,包括作中的数据做了很多分析作。个项做阶段性的结。该项是kaggle上的经典项,美国百年间的电影数据分析,也是个基础数据分析项。下是录第章 提出问题1.1 项背景1.2 提出问题1.3 分析思维1.4 分析法和具1.5 本项计划第章 理解数据2.1 导包2.2 导数据2.3 理解数据第三章 数据清洗3.1 数据预处理3.2 特征提取3.3 特征选取3.4 结数据清洗报告第四章 数据分析及可视化4.1 电影风格随时间变化的趋势4.2 不同风格电影的收益能4.3 不同风格电影的受欢迎程度4.4 不同风格电影的平均评分4.5

2、 不同类型电影的平均评分次数4.6 较UniversalPicture与Paramount Picture两家巨头公司的业绩4.7 原创电影和改变电影的对4.8 电影票房收与哪些因素最相关4.9 分析结论第五章 项回顾与总结下是报告正第章 提出问题1.1 项背景本报告数据来源于Kaggle平台上的项TMDb(The Movie Database),主要是1916-2017年百年间美国电影作品,共有4803部。通过对电影数据的分析,利可视化的法,发现电影流的趋势,找到电影投资的向,为业新局者提供参考建议。本的重点在于从不同的度,数据可视化的法来分析。未能俱到。1.2 提出问题本次数据分析的核任务

3、是:通过历史电影数据的分析,为业新局者提供参考建议。细分为以下个问题:问题1:电影风格随时间变化的趋势;问题2:不同风格电影的收益能;问题3:不同风格电影的受欢迎程度;问题4:不同风格电影的平均评分;问题5:不同风格电影的平均评价次数;问题6:较UniversalPicture与Paramount Picture两家巨头公司的业绩;问题7:原创电影和改变电影的对;问题8:电影票房收与哪些因素最相关。1.3 分析思维数据分析常思维有细分、对和溯源。细分法有横切、纵切和内切。其中横切是指从各个维度的各个点来分析(如产品、渠道、户、营销等维度的各个指标点);纵切是指通过漏分析、动作轨迹分析或者志来做

4、分析;内切般是RFM来深分析。对指横切的对、纵切的对、标的对或者时间上对。溯源是指通过反复的细分,反复的对,来确定关键点所在。本项采的思维是细分-横切,从各个维度分析以找到关键信息。1.4 分析法和具本项采数据可视化的法,来呈现各部分的分析结果,回答问题数说话、图说话。数据分析过程中使Python编程语,数据处理使pandas库、numpy库,可视化需要matplotlib库、seaborn 库。使以上法、具能较好地完成本项,是适合的法和具。1.5 本项计划12号,完成第、章,前期作:具安装调试、项背景和理解数据。13、4号,完成第三、四章,主要是编写代码:完成数据清洗、数据分析和可视化。15

5、号,完成第五、六章,字部分:整理项资料,编写输出档、存档资料。第章 理解数据在Kaggle平台上找到TMDb项,下载2个原始数据集:tmdb_5000_movies.txt和tmdb_5000_credits.txt,前者存放电影的基本信息,有20个字段,后者存放演职员的信息,有4个字段。2.1 导包数据分析及可视化常库:import pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport seaborn as snsimport jsonimport warningswarnings.filterwarnings

6、(ignore)plt.rcParamsfont.sans-serif = SimHei # 处理中乱码2.2 导数据movies = pd.read_csv(D:/DataAnalysis/cases/TMDb1/tmdb_5000_movies.txt)credits= pd.read_csv(D:/DataAnalysis/cases/TMDb1/tmdb_5000_credits.txt)2.3 理解数据边看边观察,为后续的处理做准备。(1)查看数据维度:shape属性movies.shapecredits.shape(2)查看数据字段:columns属性movies.columnsc

7、redits.columns(3)查看数据统计信息:describe法movies.describe()credits.describe()(4)查看数据框信息:info法()()()(5)展数据头:head法movies.head()credits.head()结:movies表与credits有2个重复字段,id和title,接下来需要处理;movies表中homepage、release_date、runtime和tagline四个字段的数据均有缺失,也需要处理。第三章 数据清洗原始数据不适宜直接来做分析,需要进系列的清洗,

8、为后的分析、可视化做好准备。数据清洗主要分为3部分:预处理对数据进删除、填充和合并;特征提取让数据更规整;特征选取已经开始做数据分析的前步,将这部分合并到下章。3.1 数据预处理3.1.1 删除列credits中的字段title, 与movies中的字段title重复了,删除前者。法:del命令#删除title列del creditstitle#删除homepage,original_title,overview,spoken_languages,status,tagline,movie_iddel full(homepage)del full(original_title)del full(

9、overview)del full(spoken_languages)del full(status)del full(tagline)del full(movie_id)法:drop法#删除title列credits.drop(title, axis = 1,inplace = True),或者:credits = credits.drop(title, axis = 1)#删除homepage,original_title,overview,spoken_languages,status等7列full.drop(homepage, original_title, overview, spo

10、ken_languages, status, tagline, movie_id, axis =1,inplace = True)3.1.2 填充缺失值movies中release_date字段的数据缺失1条,runtime字段的数据缺失2条,需要补充。法:观察 + 查找 + 填充#填充release_date字段的缺失值#先找出release_date字段缺失值所在的、列位置#使了isnull()和布尔索引moviesrelease_date.isnull()moviesmoviesrelease_date.isnull()movies.locmoviesrelease_date.isnul

11、l()movies.loc4553, release_date = 2010-06-01#填充runtime字段的缺失值#先找出runtime字段缺失值所在的、列位置full.locfullruntime.isnull()full.loc2656, runtime = 94full.loc4140, runtime = 240法:观察 + 快速填充#填充release_date字段的缺失值moviesrelease_datemoviesrelease_date.isnull() = 2010-06-01moviesrelease_date.fillna( 2010-06-01)#填充runti

12、me字段的缺失值fullruntime.fillna(94, limit = 1,inplace = True)fullruntime.fillna(240, limit = 1,inplace = True)3.1.3 合并表格法:append法(纵向合并)法:concat法(顶级法pd调)(axis参数来控制合并的横纵向, axis=1横向合并占内存最少)full = pd.concat(movies, credits, axis = 1),或者:full = pd.concat(movies, credits, axis = 0),或者:full = pd.concat(movies,

13、credits)法三:merge法(基类调,或者实例调)full = pd.merge(movies, credits, how = left, left_on=id, right_on=movie_id)full1 = movies.merge(credits, how = left, left_on=id, right_on=movie_id)法四:join法(只能实例调)(数据有丢失,本项该法不可取)full = movies.join(credits, how = left, on = id)3.2 特征提取3.2.1 解码json字符串法:步骤,构造增矩阵,撕代码可实现。法:另外,也

14、可采成伪变量成伪矩阵get_dummies(data,prefix = string),也叫one-hot-encoding数据中genres,keywords, production_companies, production_countries, cast, crew字段均为json类型字符串,要解析出其中的关键信息,需分为两步apply/map:(1)将json类型字符串,转换为字典;(2)取出字典的关键信息。#新建个列表,存放json类型的字段Cols = genres, keywords, production_companies, production_countries, cas

15、t,crew#解码1,将json转换为字典for col in Cols:fullcol = fullcol.apply(json.loads)#解码2,将字典内键name对应的值取出来(法1撕代码,法2列表解析表达式)#法1def getname(x):list = for i in x:list.append(iname)return ,.join(list)for col in Cols0:4:fullcol = fullcol.apply(getname)#法2列表解析表达式def getname(x):list = iname for i in xreturn ,.join(list

16、)for col in Cols0:4:fullcol = fullcol.apply(getname)#继续解码2,将字典内键charactor主演对应的值取出来def getcharacter(x):list = icharacter for i in xreturn ,.join(list0:2)fullcast = fullcast.apply(getcharacter)#继续解码2,将字典内键Director导演对应的值取出来def getdirector(x):list = iname for i in x if ijob = Directorreturn ,.join(list)

17、fullcrew = fullcrew.apply(getdirector)3.2.2 去重去重操作应了:数据结构:字符串、集合、列表、字符串:str,split()集合:union(), remove(),update(), discard()提取所有的电影风格,该过程需要去重。从在genres字段中提出来的数据会重复。法:常规4步。注意union是顶级法。注意去空值。genreset = set()for x in fullgenres.str.split(,):genreset = set().union(genreset, x)genreset.remove()genrelist =

18、list(genreset)法:少的4步。updateunion简单,discard与remove效果样。genreset = set()for x in fullgenres.str.split(,):genreset.update(x)genreset.discard()genrelist = list(genreset)3.2.3 数字化法1:五合,dfname.str.contains(abc).map(lambda x:1 if x else 0)。法2:快捷pd.get_dummies(data, prefix = aaa)该过程也叫one-hot-encoding,涉及到的名词有

19、增矩阵、伪矩阵、哑矩阵、哑变量、伪变量、数字化、值化、map(字典)。两个法的差异在于name字段的各个数据有1个还是多个伪变量。本项数据的genres列有多个伪变量,适合法来处理。#新建数据框dfgenre_df = pd.DataFrame()#五合,进one-hot-encoding,为genre_df的20个列赋值for genre in genrelist:genre_dfgenre = fullgenres.str.contains(genre).map(lambda x: 1 if x else 0)3.2.4 类型转换重点提下时间类型的转换,带格式化的。数据中release_d

20、ate字段是字符串类型的,先转换为期类型,再取年份,得整型。fullrelease_date = pd.to_datetime(fullrelease_date, format = %Y-%m-%d).dt.year3.2.5 重命名列对处理过的字段release_date,cast和crew,进重命名。name_dict = release_date: year,cast:actor, crew:directorfull.rename(columns = name_dict, inplace = True)3.3 特征选取在分析每个问题之前,有个重要的步骤,是通过选取特征构造出合适的数据框,

21、以便效地进分析并输出可视化图形。在解决前提出的若问题过程中,会频繁地构造数据框,这有个窍门就是:在分析每个问题时,选取要分析的数据列,忽略与本问题关的数据列,或者再添加特定序列,从构造出个新数据框,不是在原始数据上做分析动作,否则后思维越来越混乱,数据混淆在起了。需要注意的是,数据复杂度有三个层次,依次是DataFrame、Series、List/Dict/Index,在构造数据框的时候参考这三个层次,尽量避免构造复杂度的数据。3.3.1 构造Series法1:在原始数据框中截取;法2:使Series定义,List/DictSeries。3.3.2 构造DataFrame法1:在原始数据框中截

22、取;法2:使DataFrame定义,Series/List/Dict/IndexDataFrame;法3:合并;法3:计算。3.4 结数据清洗报告在数据清洗这部分,删除了title、homepage,original_title等8列,填充了runtime, release_date列的缺失值,合并了movies和credits两个表格,对6个json类数据进解码提出关键信息,对genres列做了one-hot编码,对release_date做了类型转换,并对3个列进了重命名,最终得到的数据框full,4308,16列,数据框genre_df,4308,20列。第四章 数据分析及可视化对1.2

23、中的九个问题逐个分析。数据可视化是对每个问题,每个特定的数据框进可视化,发现数据背后的规律和真相。常图形有散点图、柱状图、直图、折线图、饼图、箱线图和词云图;较为常的图形有:提琴图。4.1 电影风格随时间变化的趋势4.1.1 构造数据框#1、构造数据框(截取+合并)genre_dfyear = fullyear#各种类型电影的数量随时间变化的趋势genre_by_yeargenre_by_year = genre_df.groupby(year).sum()#各种类型电影的总数genreSum_by_year#升序genreSum_by_year = genre_by_year.sum().s

24、ort_values()#降序genreSum_by_year = genre_by_year.sum().sort_values(ascending = False)4.1.2 可视化#可视化genreSum_by_yearfrom pylab import rcParamsparams = legend.fontsize: 12,legend.handlelength: 10rcParams.update(params)fig = plt.figure(figsize=(20, 5)ax = plt.subplot(1, 1,1)ax = genreSum_by_year.plot(kin

25、d = bar)plt.title(Film genre by year, fontsize = 18)plt.xlabel(genre, fontsize = 18)plt.ylabel(amount, fontsize = 18)fig.savefig(Film genre by year.png)#可视化genre_by_yearfrom pylab import rcParamsparams = legend.fontsize: 10,legend.handlelength: 3rcParams.update(params)#genre_by_year = genre_by_year.

26、loc1960:2020, :fig = plt.figure(figsize=(20, 12)plt.xlabel(Year, fontsize = 10)plt.ylabel(Amount, fontsize = 10)plt.xticks(range(1920, 2030,5)plt.title(Film amount by year, fontsize = 10)plt.plot(genre_by_year)plt.legend(genre_by_year, loc = best)#plt.legend(genre_by_year, loc = best,ncol= 2)fig.sav

27、efig(Film amount by year_8.png)#genre_by_year.plot() #理解为默认设置,不同于上设定了各个参数4.1.3 分析结果(1)从上世纪90年代开始,整个电影市场各种类型的电影数量呈现爆发式增长;(2)其中Drama、Comedy、Thriller、Romance、Adventure这五类类电影增长最快。4.2 不同风格电影的收益能4.2.1 构造数据框#构造数据框(定义+合并+截取+计算)fullprofit = fullrevenue - fullbudgetprofit_df = pd.DataFrame()profit_df = pd.con

28、cat(genre_df.iloc:, :-1, fullprofit, axis = 1)#各种类型电影的收益profit_by_genre#构造Series,保存profit,其index为电影类型genrelist。(定义+计算)#此处的计算是重点,要理解数据框结构,掌握计算逻辑,灵活运。profit_by_genre = pd.Series(index = genrelist)for gen in genrelist:profit_by_genre.locgen = profit_df.loc:, gen, profit.groupby(gen).sum().loc1, profit#

29、排序,升序profit_by_genre = profit_by_genre.sort_values()4.2.2 可视化fig = plt.figure(figsize=(20, 12)plt.xlabel(Profit, fontsize = 12)plt.ylabel(Genre, fontsize = 12)plt.title(Profit by Genre, fontsize = 12)profit_by_genre.plot(kind = barh)fig.savefig(Profit by Genre_1.png)#构造分析budget的数据框并可视化budget_df = pd

30、.DataFrame()budget_df = pd.concat(genre_df.iloc:, :-1, fullbudget, axis = 1)budget_by_genre = pd.Series(index = genrelist)for gen in genrelist:budget_by_genre.locgen = budget_df.loc:, gen, budget.groupby(gen).sum().loc1, budgetbudget_by_genre = budget_by_genre.sort_values()fig = plt.figure(figsize=(

31、20, 12)plt.xlabel(Budget, fontsize = 15)plt.ylabel(Genre, fontsize = 15)plt.title(Budget by Genre, fontsize = 15)profit_by_genre.plot(kind = barh)fig.savefig(Budget by Genre_1.png)4.2.3 分析结果可以看出Adventure、Action、Comedy、Drama和Thriller电影收益最。4.3 不同风格电影的受欢迎程度4.3.1 构造数据框popu_by_genrepopu_df = pd.DataFrame

32、()popu_df = pd.concat(genre_df.iloc:, :-1, fullpopularity, axis = 1)popu_by_genre = pd.Series(index = genrelist)for gen in genrelist:popu_by_genre.locgen = popu_df.loc:, gen, popularity.groupby(gen).mean().loc1, popularitypopu_by_genre.sort_values(inplace=True)4.3.2 可视化fig = plt.figure(figsize=(20,

33、12)plt.xlabel(Mean of popularity, fontsize = 15)plt.ylabel(Genre, fontsize = 15)plt.title(Mean of popularity, fontsize = 15)popu_by_genre.plot(kind = barh)fig.savefig(popularity_by_genre_1.png)4.3.3 分析结果可以看出,Adventure、Animation最受欢迎4.4 不同风格电影的平均评分4.4.1 构造数据框vote_avg_by_genrevote_avg_df = pd.DataFrame

34、()vote_avg_df = pd.concat(genre_df.iloc:, :-1, fullvote_average, axis = 1)vote_avg_by_genre = pd.Series(index = genrelist)for gen in genrelist:vote_avg_by_genre.locgen = vote_avg_df.loc:, gen, vote_average.groupby(gen).mean().loc1, vote_averagevote_avg_by_genre.sort_values(inplace=True) #排序、升序fullpo

35、pularity.corr(fullvote_average) #相关性值为: 0.27#可以看出,电影的平均受欢迎程度与平均评分的相关性很低4.4.2 可视化fig = plt.figure(figsize=(20, 12)plt.xlabel(vote_average, fontsize = 15)plt.ylabel(Genre, fontsize = 15)plt.xlim(5, 7,0.5)#plt.xticks(range(5, 7,1) # 给效果不够好。plt.title(vote avg by genre, fontsize = 15)vote_avg_by_genre.pl

36、ot(kind = barh)fig.savefig(vote_avg_by_genre_3.png)4.4.3 分析结果不同类型电影的平均评分,数据很接近。没有显著的差异,最低值与最值的差距不到1#另外,也可以可视化全部平均分,频率分布直图sns.distplot(data,bins=)fig = plt.figure(figsize=(20, 12)plt.xlabel(vote_average, fontsize = 12)plt.ylabel(distributio of vote_avg, fontsize = 12)plt.xticks(range(11)plt.title(vot

37、e avg by genre, fontsize = 12)sns.distplot(fullvote_average, bins = 30)fig.savefig(distributio of vote_avg.png)#分析结果#不同类型电影的平均评分,在5-8之间4.5 不同类型电影的平均评分次数4.5.1 构造数据框vote_count_df、vote_count_avg_by_genrevote_count_df = pd.DataFrame()vote_count_df = pd.concat(genre_df.iloc:, :-1, fullvote_count, axis =

38、1)vote_count_avg_by_genre = pd.Series(index = genrelist)for gen in genrelist:vote_count_avg_by_genre.locgen = vote_count_df.loc:, gen, vote_count.groupby(gen).mean().loc1, vote_countvote_avg_by_genre.sort_values(inplace=True)4.5.2 可视化fig = plt.figure(figsize=(20, 12)plt.xlabel(amount, fontsize = 15)

39、plt.ylabel(Genre, fontsize = 15)plt.title(vote_count_avg_by_genre, fontsize = 15)vote_count_avg_by_genre.plot(kind = barh)fig.savefig(vote_count_avg_by_genre_1.png)4.5.3 分析结果可以看出,Adventure、Science Fiction两类电影获得的评价平均次数是最多的。4.6 较UniversalPicture与Paramount Picture两家巨头公司的业绩4.6.1 构造数据框#构造两公司业绩数据框revenue_

40、by_company#公司列表companycompany_list = Paramount Pictures, Universal Picturescompany_df = pd.DataFrame()for company in company_list:company_dfcompany = fullproduction_companies.str.contains(company).apply(lambda x: 1 if x else 0)#company_df = pd.merge(company_df, genre_df.loc:, :-1, fullrevenue, axis

41、= 1)company_df = pd.concat(company_df, fullrevenue, axis = 1)revenue_by_company = pd.Series(index = company_list)for company in company_list:revenue_by_company.loccompany = company_df.loc:, company, revenue.groupby(company).sum().loc1,revenue4.6.2 可视化fig = plt.figure(figsize=(20, 12)plt.xlabel(amoun

42、t, fontsize = 15)plt.ylabel(Genre, fontsize = 15)plt.title(Paramount vs Universal , fontsize = 15)revenue_by_company.plot(kind = barh)fig.savefig(revenue_by_company_1.png)4.6.3 分析结果Universal Pictures公司的票房收于Paramount Pictures公司4.7 原创电影和改变电影的对该问题继续细分为原创电影和改编电影数量的对、利润的对4.7.1 构造数据框#原创电影和改编电影数量的对#原创的电影:o

43、riginal- based on = false#改编来的电影:recompose - based on = trueoriginal_recompose_list = original, recomposeoriginal_recompose_df = pd.DataFrame()original_recompose_dftype = fullkeywords.str.contains(based on).apply(lambda x: 1 if x else 0)#original_vs_recompose = pd.DataFrame(index = original_recompos

44、e_list, columns = count, budget,revenue,profit)original_vs_recompose = pd.Series(index = original_recompose_list )original_vs_recomposeoriginal = original_recompose_df.groupby(type).type.count().loc0original_vs_recomposerecompose = original_recompose_df.groupby(type).type.count().loc14.7.2 可视化#可视化fi

45、g = plt.figure(figsize=(10, 8)plt.xlabel(company, fontsize = 10)plt.ylabel(count, fontsize = 10)plt.title(Paramount vs Universal , fontsize = 10)original_vs_recompose.plot(kind = bar)fig.savefig(original_vs_recompose_1.png)4.7.3 分析结果#原创电影的数量远多于改编电影#补充#原创电影和改变电影利润的对#构造数据框prof_original_recompose = pd.

46、Series(index = original_recompose_list)prof_original_recomposeoriginal = original_recompose_df.groupby(type).profit.sum().loc0prof_original_recomposerecompose = original_recompose_df.groupby(type).profit.sum().loc1#可视化fig = plt.figure(figsize=(10, 8)plt.xlabel(company, fontsize = 10)plt.ylabel(count

47、, fontsize = 10)plt.title(profit Paramount vs Universal , fontsize = 10)prof_original_recompose.plot(kind = bar)fig.savefig(profit Paramount vs Universal_1.png)#分析结果#原创电影的利润远远多于改编电影4.8 电影票房收与哪些因素最相关4.8.1 构造数据框fullbudget, popularity, revenue, runtime, vote_average, vote_count.corr()fullbudget, popula

48、rity, revenue, runtime, vote_average, vote_count.corr().iloc2#票房收与预算、受欢迎程度、评价次数三个指标相关性较强revenue_df = fullpopularity, vote_count, budget,revenue4.8.2 可视化#三个:散点图+线性回归线fig = plt.figure(figsize = (15, 5)ax1 = plt.subplot(1, 3,1)ax1 = sns.regplot(x=popularity, y=revenue, data = revenue_df)ax1.text(400, 3e9, r=0.64,fontsize=12)plt.xlabel(popularity, fontsize=12)plt.ylabel(revenue, fontsize=12)plt.

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论