Kaggle TMDB電影數據分析

Kaggle TMDB電影數據分析

來自專欄猴子聊數據分析4 人贊了文章

導讀:本文將分為兩個部分向大家展示

1.可視化分析報告

2.使用python進行數據分析的詳細操作過程

一、可視化分析報告

二、數據分析的詳細操作過程

2.1項目簡介

項目來源於kaggle,鏈接為

TMDB 5000 Movie Dataset?

www.kaggle.com

本數據集主要展示了美國在大約100年間的4803部電影,並給出了電影的詳細描述

以下為相關欄位的解釋:

id:標識號imdb_id:IMDB 標識號popularity:在 Movie Database 上的相對頁面查看次數budget:預算(美元)revenue:收入(美元)original_title:電影名稱cast:演員列表homepage:電影首頁的 URLdirector:導演列表tagline:電影的標語keywords:與電影相關的關鍵字overview:劇情摘要runtime:電影時長genres:風格列表production_companies:製作公司列表release_date:首次上映日期vote_count:評分次數vote_average:平均評分

2.2提出問題

本文主要為了分析美國100年來電影的趨勢變化,以及各類電影的收益能力,以判斷哪種電影更加流行,並提出建議。

分為以下7個小問:

  • 問題1:電影風格隨時間的變化趨勢
  • 問題2:不同風格電影的收益能力
  • 問題3:不同風格電影預算多少對比
  • 問題4:不同風格電影的受歡迎程度
  • 問題5:不同風格電影的平均評分
  • 問題6:不同風格電影的平均評價次數
  • 問題7:原創電影與改編電影的對比

2.3 準備數據

#導入相關的包import pandas as pd import numpy as npimport matplotlib.pyplot as pltimport seaborn as sns#導入數據集,movies主要是電影的信息,credit主要是演員和相關人員的信息movies=pd.read_csv(re:pythonmovie mdb_5000_movies.csv)credit=pd.read_csv(re:pythonmovie mdb_5000_credits.csv)#兩數據集有相同的id,使用merge合併數據集,使用concat也可以,因為它們的順序是一樣的df=pd.merge(movies,credit,left_on=id,right_on=movie_id,how=inner)

刪除我們本次分析不使用的數據列

df.drop([homepage,original_title,overview,spoken_languages,status,tagline,title_y,movie_id],axis=1,inplace=True)

2. 4 數據清洗

2.4.1 缺失值處理

查看數據集的基本信息

df.info()

輸出

<class pandas.core.frame.DataFrame>Int64Index: 4803 entries, 0 to 4802Data columns (total 16 columns):budget 4803 non-null int64genres 4803 non-null objectid 4803 non-null int64keywords 4803 non-null objectoriginal_language 4803 non-null objectpopularity 4803 non-null float64production_companies 4803 non-null objectproduction_countries 4803 non-null objectrelease_date 4802 non-null objectrevenue 4803 non-null int64runtime 4801 non-null float64title_x 4803 non-null objectvote_average 4803 non-null float64vote_count 4803 non-null int64cast 4803 non-null objectcrew 4803 non-null objectdtypes: float64(3), int64(4), object(9)memory usage: 797.9+ KB

只有兩個欄位有缺失值,我們通過網路搜索得到的結果來進行填補

df[release_date].fillna(2017-11-01,inplace=True)df[runtime].fillna(98,limit=1,inplace=True)df[runtime].fillna(81,inplace=True)

2.4.2數據提取和轉換

#從release_date中提取年份from datetime import datetime as dtdf[year]=pd.to_datetime(df[release_date]).dt.yeargenres/keywords/production_companies/production_countries/cast/crew列為json類型需要解析json數據,分兩步:1. json本身為字元串類型,先轉換為字典列表,使用json.loads()2. 再將字典列錶轉換為,以|分割的字元串#收集需要轉化的列名json_column = [genres,keywords,production_companies,production_countries,cast,crew]import json#對每列需要轉化的列進行轉化for i in json_column: df[i]=df[i].apply(json.loads)#對genres/keywords/production_companies/production_countries列執行函數def switch_data1(x): list=[] for i in x: list.append(i[name]) return "|".join(list)for i in json_column[0:4]: df[i]=df[i].map(switch_data1)#對cast提取角色名稱def switch_data2(x): list=[] for i in x: list.append(i[character]) return "|".join(list)#提取導演的函數def switch_data3(x): list=[] for i in x: if i[job]==Director: list.append(i[name]) return "|".join(list)df[crew]=df[crew].apply(switch_data3)#重命名列df.rename(columns={cast:actor,crew:director},inplace=True)

2.5數據分析及可視化

問題1:電影風格隨時間的變化趨勢

#用set來收集所有的電影風格set_1=set()for i in df[genres]: set_1.update(i.split(|))set_1.remove()set_1.remove(1)set_1.remove(2)set_1.remove(3)#建立是否含有該風格的表格list_1=list(set_1)genres=pd.DataFrame()for i in list_1: genres[i]=df[genres].str.contains(i).apply(lambda x:1 if x else 0)#添加year列genres_year=pd.concat([genres,df[year]],axis=1)#將genres各列求和進行排序genres.sum().sort_values(ascending=False)

輸出為

Drama 1995Comedy 1504Action 1037Adventure 652Thriller 581Romance 483Crime 443Horror 440Fantasy 256Family 236Science Fiction 222Animation 191Mystery 165History 116Music 112Documentary 108War 47Western 41Foreign 17TV Movie 4dtype: int64

plt.style.use(ggplot)#取出前8的列名,以便以繪圖,變數太多繪出來的圖不清晰genres_columns=list(genres.sum().sort_values(ascending=False).index[0:8])f,ax=plt.subplots(figsize=(16,9))genres_year.groupby(year)[genres_columns].sum().plot(ax=ax,fontsize=14)ax.set_xlabel(year,fontsize=16)ax.set_ylabel(count,fontsize=16)ax.legend(ncol=2,fontsize=14)ax.set_title(count of genres by year,fontsize=24)plt.savefig(rE:pythonmoviecount of genres by years,dpi=200)

從上圖可以看出:

1.從1990年左右開始,所有電影數量呈現指數級的增長,尤其是排名前兩名的Drama/Comedy增長幅度和增長高度比其他類的要大很多

2.這裡最後在2017年時數量集體下跌是由於該數據量只統計到2017年初

問題2:不同電影風格收益能力的對比

不同風格電影總收益的對比

columns_2=[budget,revenue]genres_profit=pd.concat([genres,df[columns_2]],axis=1)#建立新的數據框genres_df=pd.DataFrame()for i in genres.columns: genres_df[i]=genres_profit.groupby(i)[columns_2].sum().loc[1,:]#將數據框進行轉置genres_df=genres_df.Tgenres_df[profit]=genres_df[revenue]-genres_df[budget]genres_df[profitRate]=genres_df[profit]/genres_df[budget]genres_df=genres_df.sort_values(by=profit,ascending=False)#繪圖f,ax1=plt.subplots(figsize=(16,9))genres_df[profit].plot(kind=bar,ax=ax1,color=r,alpha=.7,fontsize=14,rot=30)ax2=ax1.twinx()genres_df[profitRate].plot(ax=ax2,alpha=.5,stylex=b.-,fontsize=14)ax2.grid(False)plt.title(profit by genres,fontsize=24)ax1.set_ylabel(profit,fontsize=16)ax1.set_xlabel(genres,fontsize=16)ax2.set_ylabel(profitRate,fontsize=16)plt.savefig(re:pythonmovieprofit by genres,dpi=200)

由上圖可以看出:

1.電影風格中Adventure(冒險類)和Action(動作類)的收益能力遙遙領先,Comedy(喜劇類)和Drama(戲劇類)緊隨其後,其它類型的電影表現平平,收益遠遠小於前面四類

2.就收益率profitRate來說,大多數都大於1.0,其中收益率最高的是Documentary(紀錄片),達到了2.6但是總體收益較小

不同風格電影的平均收益對比

genres_mean=pd.DataFrame()for i in genres.columns: genres_mean[i]=genres_profit.groupby(i)[columns_2].mean().loc[1,:]genres_mean=genres_mean.Tgenres_mean[profit]=genres_mean[revenue]-genres_mean[budget]genres_mean[profitRate]=genres_mean[profit]/genres_mean[budget]genres_mean=genres_mean.sort_values(by=profit,ascending=False)#繪圖f,ax1=plt.subplots(figsize=(16,9))genres_mean[profit].plot(kind=bar,ax=ax1,color=r,alpha=.7,fontsize=14,rot=30)ax2=ax1.twinx()genres_mean[profitRate].plot(ax=ax2,alpha=.5,stylex=b.-,fontsize=14)ax2.grid(False)plt.title(mean of profit by genres,fontsize=24)ax1.set_ylabel(profit,fontsize=16)ax2.set_ylabel(profitRate,fontsize=16)plt.savefig(re:pythonmoviemean of profit by genres,dpi=200)

由上圖可以看出:

1.和上面的收益總和不同,每個風格平均每部電影中的收益均值前5為,Animation(動畫類)

Adventur(冒險類) Fantasy(奇幻類) Family(家庭類) Science Fiction(科幻)

2.在總收益中前四名在這裡分別排名為:

Adventure(冒險類) 第二名Action(動作類) 第六名Comedy(喜劇類) 第十名Drama(戲劇類) 第十五名

除了Adventure 和Action類型的電影基本上保持高收益,其他兩部電影都處於每部低收益的狀態,但是收益率也有1.0以上,說明這些都是小成本電影,投資小,回報也還可以

問題3:不同電影風格需要預算多少對比

genres_budget=pd.concat([genres,df[budget]],axis=1)genres_b_s=pd.Series()for i in genres.columns: genres_b_s[i]=genres_budget.groupby(i)[budget].mean()[1]genres_b_s=genres_b_s.sort_values(ascending=False)#繪圖f,ax=plt.subplots(figsize=(16,9))sns.barplot(x=genres_b_s,y=genres_b_s.index,ax=ax,palette=Blues_d)ax.tick_params(axis=y,labelsize=16)ax.set_xlabel(mean of budget,fontsize=16)ax.set_title(mean of budget by genres,fontsize=24)plt.savefig(re:pythonmoviemean of budget by genres,dpi=200)

由上圖可以看出:

預算前五名為:

Animation(動畫類)、Adventur(冒險類)、Fantasy(奇幻類)、Action(動作)、Science Fiction(科幻)、

問題4:不同風格電影受歡迎的程度

genres_popu2=pd.Series()for i in genres.columns: genres_popu2[i]=genres_popu.groupby(i)[popularity].mean()[1]genres_popu2=genres_popu2.sort_values(ascending=False)#繪圖f,ax=plt.subplots(figsize=(16,9))sns.barplot(x=genres_popu2,y=genres_popu2.index,ax=ax,palette=Blues_d)ax.tick_params(axis=y,labelsize=16)ax.set_xlabel(mean of popularity,fontsize=16)ax.set_title(mean of popularity by genres,fontsize=24)plt.savefig(re:pythonmoviemean of popularity by genres,dpi=200)

由上圖可以看出:

1.Animation(動畫類)、Science Fiction(科幻)、Adventur(冒險類)、Fantasy(奇幻類)

流行程度最高,其他類別要低上一個級別

問題5:不同風格電影的平均評分

genres_vote_avg=pd.concat([genres,df[vote_average]],axis=1)genres_vote_avg2=pd.Series()for i in genres.columns: genres_vote_avg2[i]=genres_vote_avg.groupby(i)[vote_average].mean()[1]genres_vote_avg2=genres_vote_avg2.sort_values(ascending=False)#繪圖f,ax=plt.subplots(figsize=(16,9))sns.barplot(x=genres_vote_avg2,y=genres_vote_avg2.index,ax=ax,palette=Blues_d)ax.tick_params(axis=y,labelsize=16)ax.set_xlabel(mean of vote_average,fontsize=16)ax.set_title(mean of vote_average by genres,fontsize=24)plt.savefig(re:pythonmoviemean of vote_average by genres,dpi=200)

由上圖可以看出:

1.評分前五的為History(歷史類) War(戰爭類) Drama(戲劇類) Foreign(外國類) Animation(動畫類)

2.對整個genres來說,每種風格的平均評分差別不大,所謂蘿蔔白菜,各有所愛

問題6:不同電影風格與評價次數的關係

genres_vote_count=pd.concat([genres,df[vote_count]],axis=1)genres_vote_count2=pd.Series()for i in genres.columns: genres_vote_count2[i]=genres_vote_count.groupby(i)[vote_count].mean()[1]genres_vote_count2=genres_vote_count2.sort_values(ascending=False)#繪圖f,ax=plt.subplots(figsize=(16,9))sns.barplot(x=genres_vote_count2,y=genres_vote_count2.index,ax=ax,palette=Blues_d)ax.tick_params(axis=y,labelsize=16)ax.set_xlabel(mean of vote_count,fontsize=16)ax.set_title(mean of vote_count by genres,fontsize=24)plt.savefig(re:pythonmoviemean of vote_count by genres,dpi=200)

由上圖可以看出:

1.評價次數前五的為Science Fiction(科幻)、Adventure(冒險類)、Fantasy(奇幻類)、Animation(動畫類)、Action(動作類),這個一定程度上也可以反應各種風格電影的流行趨勢,和上面的問題3相對應,評價次數越多,流行度越高!

問題7:原創電影與改編電影對比

novel_df =df[keywords].str.contains(based on).apply(lambda x:1 if x else 0)novel_df=pd.concat([novel_df,df[columns_2]],axis=1)#按是否為改編計算均值mean_1=novel_df.groupby(keywords)[columns_2].mean()mean_1[profit]=mean_1[revenue]-mean_1[budget]#按是否為改編進行記數countcount_1=novel_df.groupby(keywords)[keywords].count()#開始繪圖plt.style.use(ggplot)f,[ax1,ax2]=plt.subplots(1,2,figsize=(16,6.5))mean_1[profit].plot(kind=bar,ax=ax1,fontsize=14)ax1.set_xticklabels([原創電影,改編電影],rotation=0,fontsize=14)ax1.set_title(原創電影和改編電影的平均收益對比,fontsize=18)plt.axis(equal)count_1.plot(kind=pie,labels=[原創電影,改編電影],autopct=%.1f%%,pctdistance=.7,ax=ax2,fontsize=14)plt.ylabel()plt.axis(equal)ax2.set_title(原創電影和改編電影的數量佔比,fontsize=18)plt.savefig(re:pythonmovie原創與改編電影,dpi=200)

由上圖可以看出:

1.原創和改編電影中改編電影的收益一般要比原創的要高,估計有很多原著粉來看改編的電影

2.改編電影的數量遠遠少於原創電影

推薦閱讀:

又一大波比賽來襲,開發,NLP隨你選!—5月國內大數據比賽資訊,總獎池超900萬
0 大數據學習計劃
主成分分析(PCA)原理詳解
閑話國內大數據發展簡史&產業化落地
數據分析思維-提供另外一種審視世界的視角

TAG:數據挖掘 | 數據分析 | 電影票房 |