前言
本项目展示了问题分解、数据清洗、数据分析与可视化的过程,最后给出了一个简单的预测模型。
数据来源是Kaggle提供的Internet Movie Database(TMDb)数据集,包括了近五千部电影的信息。
数据原地址:https://www.kaggle.com/tmdb/tmdb-movie-metadata
本文的框架如下:
准备工作
1.1 数据载入和预览
1.2 数据清洗和加工
1.3 数据筛选
票房 & 评分分析
2.0 概览(票房&评分Top 10、变化趋势)
2.1 类型(不同类型影片的数量变化趋势、票房&评分)
2.2 导演(Top 10、票房&评分分布)
2.3 主演(Top 10、票房&评分分布)
2.4 档期(数量分布、票房分布)
2.5 小结
电影评分预测
3.1 相似度计算
3.2 评分预测
1 - 准备工作
1.1 - 数据载入与预览
# 数据分析包导入
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('ggplot')
%matplotlib inline
import warnings
warnings.filterwarnings(action = 'ignore') # 忽略警告
# 数据导入,这个数据集是标准的csv格式
movies = pd.read_csv('tmdb_5000_movies.csv')
credits = pd.read_csv('tmdb_5000_credits.csv')
# 数据预览
movies.head(2)
movies.info()
credits.head(2)
credits.info()
可以看到这两个数据集提供了4803部电影的预算、票房、评分、职员表等诸多信息,而且数据比较完整(缺失值很少)。
1.2 - 数据清洗和加工
数据清洗主要包括查漏补缺、去重、纠错。
· 查漏补缺:数据集中homepage、runtime、tagline有缺失,但它们也不是我们关心的信息,可以忽略。
· 纠错:目前看不出有没有错误,在后续分析中再考虑。
· 去重:movies数据集中的id是每部电影的识别码,以此来看看有没有重复数据:
len(movies.id.unique())
有4803个不重复的id,可以认为没有重复数据。
# 数据加工主要是对一些字段进行提取和转换。
# 两个数据集都有电影id,用merge将两个表合并:
movies_credits = movies.merge(credits, left_on='id', right_on='movie_id', how='left')
movies_credits.head(5)
从预览中可以观察到,genres(类型)、keywords(关键词)、cast(职员表)这些数据都是json格式的,
我们实际需要的是name字段对应的名字,因此将这些数据转为名字列表方便后续分析。
movies_credits.genres[0]
# 首先使用json.loads 对数据进行读取:
import json
json_columns = ['genres', 'keywords', 'production_companies', 'production_countries', 'cast', 'crew']
for column in json_columns:
movies_credits[column] = movies_credits[column].apply(json.loads)
#将数据中name字段对应的名字提取出来,用列表推导式可以简洁地构造提取函数:
def extractName(column):
col = [[di['name'] for di in row] for row in column]
return col
ex_name = ['genres', 'production_companies', 'production_countries']
for column in ex_name:
movies_credits[column] = extractName(movies_credits[column])
movies_credits['actors'] = [[di['name'] for di in row[0:4]] for row in movies_credits['cast']] #演员只取前4位
movies_credits['keywords'] = [[di['name'] for di in row[0:10]] for row in movies_credits['keywords']] #关键词只取前10个
#现在genres等列变为名字列表了:
movies_credits.genres[0]
#导演、编剧和制片人信息储存在crew一列中,将其提取出来。对于crew中没有该职位的情况,用空值代替:
def extractDirector(crew, job):
name = ''
for di in crew:
if di['job'] == job:
name = di['name']
break
else:
pass
return name
movies_credits['director'] = [extractDirector(crew, 'Director') for crew in movies_credits.crew]
movies_credits['writer'] = [extractDirector(crew, 'Writer') for crew in movies_credits.crew]
movies_credits['producer'] = [extractDirector(crew, 'producer') for crew in movies_credits.crew]
#提取电影发布时间(release_date)一列中的年份,方便后续按年份来统计:
movies_credits['year'] = pd.to_datetime(movies_credits['release_date']).apply(lambda x: x.year)
1.3 - 数据筛选
#提取出我们后续分析需要的变量,去掉空值,看看数学统计:
movies = movies_credits[['title_x', 'genres', 'keywords', 'director', 'acto