电影票房预测-kaggle项目Python项目

该文研究了如何基于电影元数据预测票房,涉及数据清洗、特征提取,如上映年月日、类型、制作公司、演员等。通过分析上映月份与票房的关系,发现6月和12月为高票房期。此外,还展示了不同电影类型的历年平均票房趋势,以及主要制片公司的票房表现。最后,进行了特征工程,包括对票房和预算列的对数变换,为构建预测模型(如Lasso和Ridge回归)做准备。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

研究问题:如何根据电影上映前的一些信息来预测出该电影的票房。
数据来源
数据主要是电影数据库中的 7000 多部过去电影的元数据。提供的数据信息包括演员,工作人员,情节关键词,预算,海报,发布日期,语言,制作公司和国家等。

数据导入

还是之前一模一样的操作

#数据导入
import pandas as pd
df = pd.read_csv("https://labfile.oss.aliyuncs.com/courses/1363/TMDB.csv")
df.head()
#数据查看
df.shape
df.info()
df.describe()
df.describe(include=['O'])
#查看一下票房前10的电影
df.sort_values(by='revenue', ascending=False).head(10)[
    ['title', 'revenue', 'release_date']]

数据预处理

数据预处理:数据清洗+填充空缺值等

上映时间
release_date为电影的上映时间列,对该列进行处理。将时间中的年、月、日这些信息都分别提取出来。

def date_features(df):
    df['release_date'] = pd.to_datetime(df['release_date'])  # 转换为时间戳
    df['release_year'] = df['release_date'].dt.year  # 提取年
    df['release_month'] = df['release_date'].dt.month     # 提取月
    df['release_day'] = df['release_date'].dt.day  # 提取日
    df['release_quarter'] = df['release_date'].dt.quarter  # 提取季度
    return df

df = date_features(df)
df['release_year'].head()

检查是否存在异常值,即电影上映时间超过 2019 年,因为收集的数据是 2019 年之前的。

import numpy as np
# 查看大于 2019 的数据
df['release_year'].iloc[np.where(df['release_year'] > 2019)][:10]
#存在异常值,需要处理。大于2019的减去100
df['release_year'] = np.where(
    df['release_year'] > 2019, df['release_year']-100, df['release_year'])
df['release_year'].iloc[np.where(df['release_year'] > 2019)][:10]
#已经没有大于2019的了
cols = ['release_year', 'release_month',
        'release_day']
df[cols].isnull().sum()
#再查看日期列是否有缺失值,结果显示没有
#其他列还是存在着空值情况的

显示票房随时间变化,即每月的票房分布。进行月对比

#显示每个月的平均电影票房
from matplotlib import pyplot as plt
%matplotlib inline
fig = plt.figure(figsize=(14, 4))
df.groupby('release_month').agg('mean')['revenue'].plot(kind='bar', rot=0)
plt.ylabel('Revenue (100 million dollars)')
#由图可以看到,电影的上映时间主要集中在 6 月和 12 月。这可能的原因是这两段时间都是假期。

得到图表后应该给出合适的结论

#显示每年的电影平均票房数
release_year_mean_data = df.groupby(['release_year'])['revenue'].mean()
fig = plt.figure(figsize=(14,5))
plt.plot(release_year_mean_data)
plt.ylabel('Mean revenue value')
plt.title('Mean revenue Over Years') 
#从上图可以看到,电影的每年平均票房都是逐年递增的,这可能跟我们的经济增长有关,因为人们越来越有钱了,花费在精神上的消费比例也越来越大了。
#每次做出图后,最好给一个结论

和上面的代码类似

#电影时长与年份的折线图
release_year_mean_data = df.groupby(['release_year'])['runtime'].mean()
fig = plt.figure(figsize=(14, 5))  # 设置画布大小
plt.plot(release_year_mean_data)
plt.ylabel('Mean popularity value')  # 设置 y 轴的标签
plt.title('Mean popularity Over Years')  # 设置标题
#从上图中可以发现,在 1980 年之前,电影的平均时长都是不定的,而 1980 年之后,趋向于稳定,差不多是 100 多分钟。

收藏集

将该列的中的name提取出来,并统计空缺

#先打印前5列进行观察
#enumerate在字典上是枚举、列举的意思.利用它可以同时获得索引和值
#如果对一个列表,既要遍历索引又要遍历元素时,用它
for i, e in enumerate(df['belongs_to_collection'][:5]):
    print(i, e)
    print(type(e))

#通过判断该列的值是否是字符串来判断是否存在值或为空值。
df['belongs_to_collection'].apply(
    lambda x: 1 if type(x) == str else 0).value_counts()
#在 3000 份数据中,该列的缺失值就有 2396。

#从该列中提取 name 属性。且创建一列保存是否缺失。
df['collection_name'] = df['belongs_to_collection'].apply(
    lambda x: eval(x)[0]['name'] if type(x) == str else 0)
df['has_collection'] = df['belongs_to_collection'].apply(
    lambda x: 1 if type(x) == str else 0)
df[['collection_name', 'has_collection']].head()

电影类型
同上面,处理genres 列

for i, e in enumerate(df['genres'][:5]):
    print(i, e)

#先提取类型名
list_of_genres = list(df['genres'].apply(lambda x:[i['name'] for i in eval(x)] if type(x) == str else []).values)
list_of_genres[:5]

#统计类型的数据
from collections import Counter
most_common_genres = Counter(
    [i for j in list_of_genres for i in j]).most_common()
most_common_genres

#绘制图片
fig = plt.figure(figsize=(10, 6))
data = dict(most_common_genres)
names = list(data.keys())
values = list(data.values())
#排序做柱状图
plt.barh(sorted(range(len(data)), reverse=True),
         values, tick_label=names, color='teal')
plt.xlabel('Count')
plt.title('Movie Genre Count')
plt.show()

词云图

#先安装 词云库 wordcloud 
!pip install wordcloud

from wordcloud import WordCloud

plt.figure(figsize=(12, 8))
text = ' '.join([i for j in list_of_genres for i in j])
# 设置参数
wordcloud = WordCloud(max_font_size=None, background_color='white', collocations=False,
                      width=1200, height=1000).generate(text)
plt.imshow(wordcloud)
plt.title('Top genres')
plt.axis("off")
plt.show()

将类型展开,类似One-Hot 编码

df['num_genres'] = df['genres'].apply(
    lambda x: len(eval(x)) if type(x) == str else 0)
df['all_genres'] = df['genres'].apply(lambda x: ' '.join(
    sorted([i['name'] for i in eval(x)])) if type(x) == str else '')
top_genres = [m[0] for m in Counter(
    [i for j in list_of_genres for i in j]).most_common(15)]
for g in top_genres:
    df['genre_' + g] = df['all_genres'].apply(lambda x: 1 if g in x else 0)
cols = [i for i in df.columns if 'genre_' in 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值