簡介: 本數(shù)據(jù)集中包含 1 萬條電影信息,信息來源為“kaggle電影數(shù)據(jù)庫”(TMDb,The Movie Database),包括用戶評分和票房。 主要為美國地區(qū)(1960-2015)的電影作品。
一. 提出問題
本次數(shù)據(jù)分析的核心任務(wù)是:
- 通過對歷史電影數(shù)據(jù)的統(tǒng)計分析,運用集中趨勢測量,離散程度測量等等,對數(shù)據(jù)進行描述性統(tǒng)計,為電影公司投資和拍片思路提供一些方向還有角度。
細化為下述幾個小問題: - 問題1:什么對于票房的影響最大
- 問題2:電影的投入對于電影票房的影響
- 問題3:不同類型電影的發(fā)行量
- 問題4:不同類型電影的收益能力
- 問題5:不同風格電影的受歡迎程度
二、理解數(shù)據(jù)
工具:Jupyter Notebook
下載好的csv文件:tmdb-movies.csv
導入文件后通過對數(shù)據(jù)的查看,我們篩選出與問題重點有關(guān)的變量:
| 序號 | 變量名 | 說明 |
|---|---|---|
| 1 | id | tmdb身份標識 |
| 2 | popularity | 電影受歡迎程度 |
| 3 | budget | 電影預(yù)算(單位:$) |
| 4 | revenue | 電影收入(單位:$) |
| 5 | genres | 電影風格 |
| 6 | release_date | 發(fā)行日期 |
| 7 | vote_count | 評價的次數(shù) |
| 8 | vote_average | 平均評分 |
| 9 | release_year | 發(fā)行年份 |
三、數(shù)據(jù)整理
- 對數(shù)據(jù)集大概的情況進行了解
- 查看是否有數(shù)據(jù)類型需要轉(zhuǎn)換
- 有無缺失值,是否需要填充或者刪除
- 有無冗余數(shù)據(jù),是否需要刪除
- 查看列標簽,與問題無關(guān)的列標簽可以刪除
# 導入語句
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
# 讀取文件
df_movie = pd.read_csv('tmdb-movies.csv')
# 查看文件
df_movie.head(1)
# 數(shù)據(jù)集的行數(shù)列數(shù)
df_movie.shape
# 數(shù)據(jù)集的數(shù)據(jù)類型
df_movie.dtypes
# 檢查有無缺失值
df_movie.isnull().sum()
# 檢查有無冗余數(shù)據(jù)
df_movie.duplicated().sum()
# 打印列標簽,方便刪除用不到的列
for i,v in enumerate(df_movie.columns):
print(i,v)
四、數(shù)據(jù)清理
- 清理 ['imdb_id', 'original_title', 'cast', 'homepage', 'tagline', 'keywords', 'overview', 'runtime', 'production_companies'] ,以上列標簽與問題關(guān)聯(lián)不大。
- 使用id列標簽來查看冗余數(shù)據(jù)是否需要刪除,因為id是唯一的,假如有兩個一樣的id,那么就可以刪除多余的數(shù)據(jù)。
- 檢查缺失值所在的列,通過列標簽來判斷缺失值需要填充還是刪除。
# 清理列標簽
df_movie.drop(['imdb_id', 'original_title', 'cast', 'homepage', 'tagline', 'keywords', 'overview', 'runtime', 'production_companies'],
axis=1, inplace=True)
# 查看電影數(shù)據(jù)集的列標簽,確定成功
df_movie.head(1)
for i,v in enumerate(df_movie.columns):
print(v)
# 查看冗余數(shù)據(jù)
df_movie['id'].duplicated().any()
# 刪除冗余數(shù)據(jù)
df_movie.drop_duplicates(inplace=True)
# 檢查是否刪除成功
df_movie.duplicated().any()
# 檢查缺失值所在的列數(shù)
df_movie.isnull().any()
# 可以看出缺失值在導演和電影類型當中,可以刪除缺失值
df_movie.dropna(inplace=True)
# 檢查缺失值是否清理完畢
df_movie.isnull().any()
五、可視化數(shù)據(jù)
1、什么對于票房的影響最大?
# 計算相關(guān)系數(shù)矩陣
df_revenue_corr = df_movie.corr()
df_revenue_corr['revenue'].sort_values(ascending=False)
# 根據(jù)矩陣從中選出相關(guān)性最高的
df_movie[['popularity', 'vote_count', 'budget', 'profit', revenue']].corr()
| popularity | vote_count | budget | profit | revenue | |
|---|---|---|---|---|---|
| popularity | 1.000000 | 0.794798 | 0.541389 | 0.632243 | 0.665637 |
| vote_count | 0.794798 | 1.000000 | 0.641547 | 0.761011 | 0.798562 |
| budget | 0.541389 | 0.641547 | 1.000000 | 0.564219 | 0.729293 |
| profit | 0.632243 | 0.761011 | 0.564219 | 1.000000 | 0.976375 |
| revenue | 0.665637 | 0.798562 | 0.729293 | 0.976375 | 1.000000 |
得出:
- 受歡迎程度和票房相關(guān)性:0.6656
- 評價次數(shù)和票房相關(guān)性:0.7986
- 電影預(yù)算和票房相關(guān)性:0.7293
- 收益和票房相關(guān)性:0.9764
以上我們可以看到,相關(guān)性最高的是vote_count(投票總數(shù)),budget(電影投入),profit(電影收益),popularity(受歡迎程度)
- 由于
vote_count和profit都是在票房出來之后才會有,因此相關(guān)性最高,但同時也需要剔除。 - 因此對
popularity和budget進行可視化。
# 創(chuàng)建票房收入數(shù)據(jù)框
revenue = df_movie[['popularity', 'budget', 'revenue']]
# 可視化票房收入與受歡迎程度(藍)的相關(guān)性散點圖,\并配線性回歸線。
fig = plt.figure(figsize=(17, 5))
ax1 = plt.subplot(131)
ax1 = sns.regplot(x='popularity', y='revenue', data=revenue, x_jitter=.1)
plt.title('revenue by popularity',fontsize=15)
plt.xlabel('popularity',fontsize=12)
plt.ylabel('revenue',fontsize=12)
# 可視化票房收入電影預(yù)算(紅)的相關(guān)性散點圖,并配線性回歸線。
ax2 = plt.subplot(132)
ax2 = sns.regplot(x='budget', y='revenue', data=revenue, x_jitter=.1,color='r',marker='+')
plt.title('revenue by budget',fontsize=15)
plt.xlabel('budget',fontsize=12)
plt.ylabel('revenue',fontsize=12)
繪制線性相關(guān)圖:

相關(guān)因素圖.png
2、電影的投入對于電影票房的影響
# 得出平均預(yù)算
budget_mean = df_movie.budget.mean()
# 通過平均預(yù)算分出高低預(yù)算兩組
low_budget = df_movie.query('budget < {}'.format(budget_mean))
high_budget = df_movie.query('budget >= {}'.format(budget_mean))
new_samples = df_movie.shape[0]
new_samples == low_budget['revenue'].count() + high_budget['revenue'].count()
# 得出平均收入
mean_revenue_low = low_vote['revenue'].mean()
mean_revenue_high = high_vote['revenue'].mean()
# 可視化數(shù)據(jù)
locations = [1, 2]
heights = [mean_revenue_low, mean_revenue_high]
labels = ['Low Budget', 'High Bubget']
plt.bar(locations, heights, tick_label = labels)
plt.title('Average Revenue by Bubget')
plt.xlabel('Budget Content')
plt.ylabel('Revenue')
繪制條形圖:

高低預(yù)算對比.png
可以看出預(yù)算更高的電影,票房也會比低預(yù)算的電影更高。
3、不同類型電影的發(fā)行量
# 單獨提取出genre
set_genre = set()
for x in df_movie['genres']:
set_genre.update(x.split('|'))
set_genre.discard('')
# 轉(zhuǎn)換成dataframe類型
df_genre = pd.DataFrame()
for genre in set_genre:
df_genre[genre] = df_movie['genres'].str.contains(genre).map(lambda x:1 if x else 0)
df_genre['year']=df_movie['release_year']
# 形成新的列
genre_by_year = df_genre.groupby('year').sum()
genresum_by_year = genre_by_year.sum().sort_values()
fig = plt.figure(figsize=(12,10))
ax = plt.subplot(111)
ax = genresum_by_year.plot.bar(alpha=.7)
plt.xticks(rotation=60)
plt.title('Top genre', fontsize=15)
plt.xlabel('genre', fontsize=15)
plt.ylabel('count', fontsize=15)
繪制柱形圖:

電影風格發(fā)行數(shù)量.png
最受歡迎的前五名:
- Drama(戲?。?/li>
- Comedy(喜?。?/li>
- Thriller(驚險)
- Action(動作)
- Adventure(冒險)
4、不同類型電影的收益能力
# 可可視化數(shù)據(jù)
fig = plt.figure(figsize=(18,13))
ax1 = fig.add_subplot(111)
plt.bar(x, profit_rate['profit'], label='profit', alpha=.7)
plt.xticks(x,xl,rotation=60,fontsize=12)
plt.yticks(fontsize=12)
ax1.set_title('Profit by genres', fontsize=20)
ax1.set_ylabel('Film Profit',fontsize=18)
ax1.set_xlabel('Genre',fontsize=18)
ax1.set_ylim(0,1.2e11)
ax1.legend(loc=2,fontsize=15)
#次縱坐標軸標簽設(shè)置為百分比顯示
import matplotlib.ticker as mtick
# 添加多一個兄弟軸,另一條y軸
ax2 = ax1.twinx()
ax2.plot(x, profit_rate['profit_rate'], 'ro-', lw=2, label='profit_rate')
# #次縱坐標軸標簽設(shè)置為百分比顯示
fmt='%.2f%%'
yticks = mtick.FormatStrFormatter(fmt)
ax2.yaxis.set_major_formatter(yticks)
plt.yticks(fontsize=15)
ax2.set_ylabel('Profit_rate',fontsize=18)
ax2.legend(loc=1,fontsize=15)
plt.grid(0)
繪制條形圖和折線圖:

電影風格收益能力.png
收益能力最高的五個類型:
- Adventure(冒險)
- Action(動作)
- Comedy(喜?。?/li>
- Drama(喜劇)
- hriller(驚險)
5、不同類型電影的受歡迎程度
# 創(chuàng)建受歡迎程度的數(shù)據(jù)框
df_popularity = pd.DataFrame()
df_popularity = pd.concat([df_genre.iloc[:, :-1], df_movie['popularity']], axis=1)
df_popularity.head()
# 計算每個風格電影的受歡迎程度的均值
popularity_mean = []
for genre in set_genre:
popularity_mean.append(df_popularity.groupby(genre, as_index=False).mean().loc[1,'popularity'])
genre_popularity = pd.DataFrame(index=set_genre)
genre_popularity['popularity_mean'] = popularity_mean
genre_popularity.sort_values('popularity_mean', inplace=True)
# 可視化數(shù)據(jù)
fig = plt.figure(figsize=(14, 8))
ax = plt.subplot(111)
genre_popularity.plot(ax=ax, kind='barh')
plt.title('Popularity by genre', fontsize=18)
plt.xlabel('Mean of popularity', fontsize=15)
plt.ylabel('Film genres', fontsize=14)
plt.xticks(fontsize=11)
plt.yticks(fontsize=11)
plt.legend(fontsize=11)
繪制橫向條形圖:

電影風格受歡迎程度.png
受歡迎程度最高的五個類型:
- Adventure(冒險)
- Science Fiction(科幻小說)
- Fantasy(幻想)
- Action(動作)
- Animation(動畫)
六、結(jié)論
1.電影類型方面
從收益來看:
- Adventure(冒險)
- Action(動作)
- Comedy(喜?。?/li>
- Drama(戲?。?/li>
- hriller(驚險)
從受歡迎程度來看:
- Adventure(冒險)
- Science Fiction(科幻小說)
- Fantasy(幻想)
- Action(動作)
- Animation(動畫)
建議:
- 結(jié)合兩組數(shù)據(jù),我們可以看出
冒險類,動作類,喜劇類,科幻類的電影收益和受歡迎程度都比較高,建議首選以上四種類型電影。
2.電影投入方面
- 電影投入得越多,正常來說會是個大片,票房也應(yīng)該會大賣。但還需要其他綜合因素的考量,例如演員陣容,導演,電影類型等等。但不可否認的是,電影投入得多,演員陣容也會更豪華,導演知名度較高,才是高票房的保障。因此,如果不考慮其他綜合因素情況下,高投入會比低投入電影的票房高。
- 電影投入包含許多的方面,有一個方面也是非常重要,那就是在上映之前,電影的知名度,也就是受歡迎的程度。因此,電影的預(yù)算建議多投入在廣告宣傳方面,在上映之前打響知名度。
提示:
-
本項目分析使用的數(shù)據(jù)對于探索的問題已經(jīng)足夠
數(shù)據(jù)量使用足夠大,來源于著名的tmdb電影網(wǎng)站,數(shù)據(jù)量達上萬條,足夠?qū)μ剿鲉栴}作出相關(guān)性的判斷。
篩選出的特征足夠用于探索目標的分析,電影的票房、預(yù)算、收益、受歡迎程度和電影類型。以上篩選出來的數(shù)據(jù)集大多數(shù)與這五個特征有關(guān)
-
探索過程中對數(shù)據(jù)的清洗、處理、操作不會對最后分析帶來偏差和不確定性
- 對于缺失值的處理:因為出現(xiàn)缺失值的列數(shù)對于最后分析的問題來說,并不在對比之列,因此可以刪除
- 對于冗余數(shù)據(jù)的處理:此數(shù)據(jù)集只出現(xiàn)了一個冗余數(shù)據(jù),并且同一個id,因此可以刪除。
- 對于數(shù)據(jù)類型的處理:數(shù)據(jù)類型都比較合理,并沒有需要轉(zhuǎn)換的數(shù)據(jù)類型。