TMDB电影项目分析

简介: 本数据集中包含 1 万条电影信息,信息来源为“kaggle电影数据库”(TMDb,The Movie Database),包括用户评分和票房。 主要为美国地区(1960-2015)的电影作品。

一. 提出问题

本次数据分析的核心任务是:

  • 通过对历史电影数据的统计分析,运用集中趋势测量,离散程度测量等等,对数据进行描述性统计,为电影公司投资和拍片思路提供一些方向还有角度。
    细化为下述几个小问题:
  • 问题1:什么对于票房的影响最大
  • 问题2:电影的投入对于电影票房的影响
  • 问题3:不同类型电影的发行量
  • 问题4:不同类型电影的收益能力
  • 问题5:不同风格电影的受欢迎程度

二、理解数据

工具:Jupyter Notebook
下载好的csv文件:tmdb-movies.csv
导入文件后通过对数据的查看,我们筛选出与问题重点有关的变量:

序号 变量名 说明
1 id tmdb身份标识
2 popularity 电影受欢迎程度
3 budget 电影预算(单位:$)
4 revenue 电影收入(单位:$)
5 genres 电影风格
6 release_date 发行日期
7 vote_count 评价的次数
8 vote_average 平均评分
9 release_year 发行年份

三、数据整理

  • 对数据集大概的情况进行了解
  • 查看是否有数据类型需要转换
  • 有无缺失值,是否需要填充或者删除
  • 有无冗余数据,是否需要删除
  • 查看列标签,与问题无关的列标签可以删除
# 导入语句
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)
# 数据集的行数列数
df_movie.shape
# 数据集的数据类型
df_movie.dtypes
# 检查有无缺失值
df_movie.isnull().sum()
# 检查有无冗余数据
df_movie.duplicated().sum()
# 打印列标签,方便删除用不到的列
for i,v in enumerate(df_movie.columns):
    print(i,v)

四、数据清理

  • 清理 ['imdb_id', 'original_title', 'cast', 'homepage', 'tagline', 'keywords', 'overview', 'runtime', 'production_companies'] ,以上列标签与问题关联不大。
  • 使用id列标签来查看冗余数据是否需要删除,因为id是唯一的,假如有两个一样的id,那么就可以删除多余的数据。
  • 检查缺失值所在的列,通过列标签来判断缺失值需要填充还是删除。
# 清理列标签
df_movie.drop(['imdb_id', 'original_title', 'cast', 'homepage', 'tagline', 'keywords', 'overview', 'runtime', 'production_companies'], 
             axis=1, inplace=True)

# 查看电影数据集的列标签,确定成功
df_movie.head(1)
for i,v in enumerate(df_movie.columns):
    print(v)
    
# 查看冗余数据
df_movie['id'].duplicated().any()
# 删除冗余数据
df_movie.drop_duplicates(inplace=True)
# 检查是否删除成功
df_movie.duplicated().any()
# 检查缺失值所在的列数
df_movie.isnull().any()
# 可以看出缺失值在导演和电影类型当中,可以删除缺失值
df_movie.dropna(inplace=True)
# 检查缺失值是否清理完毕
df_movie.isnull().any()

五、可视化数据

1、什么对于票房的影响最大?

# 计算相关系数矩阵
df_revenue_corr = df_movie.corr()
df_revenue_corr['revenue'].sort_values(ascending=False)

# 根据矩阵从中选出相关性最高的
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

得出:

  • 受欢迎程度和票房相关性:0.6656
  • 评价次数和票房相关性:0.7986
  • 电影预算和票房相关性:0.7293
  • 收益和票房相关性:0.9764

以上我们可以看到,相关性最高的是vote_count(投票总数)budget(电影投入)profit(电影收益)popularity(受欢迎程度)

  • 由于vote_countprofit都是在票房出来之后才会有,因此相关性最高,但同时也需要剔除。
  • 因此对popularitybudget进行可视化。
# 创建票房收入数据框
revenue = df_movie[['popularity', 'budget', 'revenue']]

# 可视化票房收入与受欢迎程度(蓝)的相关性散点图,\并配线性回归线。
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)

# 可视化票房收入电影预算(红)的相关性散点图,并配线性回归线。
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)

绘制线性相关图:

相关因素图.png

2、电影的投入对于电影票房的影响

# 得出平均预算
budget_mean = df_movie.budget.mean()

# 通过平均预算分出高低预算两组
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()

# 可视化数据
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')

绘制条形图:

高低预算对比.png

可以看出预算更高的电影,票房也会比低预算的电影更高。


3、不同类型电影的发行量

# 单独提取出genre
set_genre = set()
for x in df_movie['genres']:
    set_genre.update(x.split('|'))
set_genre.discard('')

# 转换成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)

绘制柱形图:

电影风格发行数量.png

最受欢迎的前五名:

  • Drama(戏剧)
  • Comedy(喜剧)
  • Thriller(惊险)
  • Action(动作)
  • Adventure(冒险)

4、不同类型电影的收益能力

# 可可视化数据
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)

#次纵坐标轴标签设置为百分比显示
import matplotlib.ticker as mtick

# 添加多一个兄弟轴,另一条y轴
ax2 = ax1.twinx()
ax2.plot(x, profit_rate['profit_rate'], 'ro-', lw=2, label='profit_rate')

# #次纵坐标轴标签设置为百分比显示
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(喜剧)
  • Drama(喜剧)
  • hriller(惊险)

5、不同类型电影的受欢迎程度

# 创建受欢迎程度的数据框
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)

# 可视化数据
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(动画)

六、结论

1.电影类型方面

从收益来看:

  • Adventure(冒险)
  • Action(动作)
  • Comedy(喜剧)
  • Drama(戏剧)
  • hriller(惊险)

从受欢迎程度来看:

  • Adventure(冒险)
  • Science Fiction(科幻小说)
  • Fantasy(幻想)
  • Action(动作)
  • Animation(动画)

建议:

  • 结合两组数据,我们可以看出冒险类动作类喜剧类科幻类的电影收益和受欢迎程度都比较高,建议首选以上四种类型电影。

2.电影投入方面

  • 电影投入得越多,正常来说会是个大片,票房也应该会大卖。但还需要其他综合因素的考量,例如演员阵容,导演,电影类型等等。但不可否认的是,电影投入得多,演员阵容也会更豪华,导演知名度较高,才是高票房的保障。因此,如果不考虑其他综合因素情况下,高投入会比低投入电影的票房高。
  • 电影投入包含许多的方面,有一个方面也是非常重要,那就是在上映之前,电影的知名度,也就是受欢迎的程度。因此,电影的预算建议多投入在广告宣传方面,在上映之前打响知名度。

提示:

  • 本项目分析使用的数据对于探索的问题已经足够

    • 数据量使用足够大,来源于著名的tmdb电影网站,数据量达上万条,足够对探索问题作出相关性的判断。

    • 筛选出的特征足够用于探索目标的分析,电影的票房、预算、收益、受欢迎程度和电影类型。以上筛选出来的数据集大多数与这五个特征有关

  • 探索过程中对数据的清洗、处理、操作不会对最后分析带来偏差和不确定性

    • 对于缺失值的处理:因为出现缺失值的列数对于最后分析的问题来说,并不在对比之列,因此可以删除
    • 对于冗余数据的处理:此数据集只出现了一个冗余数据,并且同一个id,因此可以删除。
    • 对于数据类型的处理:数据类型都比较合理,并没有需要转换的数据类型。

你可能感兴趣的:(TMDB电影项目分析)