Kaggle TMDB電影數據分析
來自專欄猴子聊數據分析4 人贊了文章
導讀:本文將分為兩個部分向大家展示
1.可視化分析報告
2.使用python進行數據分析的詳細操作過程
一、可視化分析報告
二、數據分析的詳細操作過程
2.1項目簡介
項目來源於kaggle,鏈接為
TMDB 5000 Movie Dataset
本數據集主要展示了美國在大約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)原理詳解
※閑話國內大數據發展簡史&產業化落地
※數據分析思維-提供另外一種審視世界的視角