11.24每日总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
import matplotlib as matplotlib
 
import numpy as np
 
import pandas as pd
import seaborn as sns
from pandas import DataFrame, Series
 
# 可视化显示在界面
 
# matplotlib inline
 
import matplotlib
 
import matplotlib.pyplot as plt
from wordcloud import STOPWORDS, WordCloud
 
plt.rcParams['font.sans-serif'] = ['SimHei'# 用来显示中文
 
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
 
# 学习seaborn参考:https://www.jianshu.com/p/c26bc5ccf604
 
 
import json
 
import warnings
 
warnings.filterwarnings('ignore')
 
# 设置显示的最大列、宽等参数,消掉打印不完全中间的省略号
 
# pd.set_option('display.max_columns', 1000)
 
pd.set_option('display.width', 1000# 加了这一行那表格的一行就不会分段出现了
 
# pd.set_option('display.max_colwidth', 1000)
 
# pd.set_option('display.height', 1000)
 
# 显示所有列
 
pd.set_option('display.max_columns', None)
 
# 显示所有行
 
pd.set_option('display.max_rows', None)
 
movies = pd.read_csv(
    'tmdb_5000_movies.csv',
    encoding='utf_8')
 
credits = pd.read_csv(
    'tmdb_5000_credits.csv',
    encoding='utf_8')
 
movies.info()  # 查看信息
 
credits.info()
 
# 两个数据框都有title列,以及movies.riginal_title
 
# 以上三个数据列重复,删除两个
 
del credits['title']
 
del movies['original_title']
 
# 连接两个csv文件
 
merged = pd.merge(movies, credits, left_on='id', right_on='movie_id', how='left')
 
# 删除不需要分析的列
 
df = merged.drop(['homepage', 'overview', 'spoken_languages', 'status', 'tagline', 'movie_id'], axis=1)
 
df.info()
 
# 查找缺失值记录-release_date
var = df[df.release_date.isnull()]
print(var.title)
# 查找缺失值记录-runtime
var = df[df.runtime.isnull()]
print(var.title)
 
df['release_date'] = df['release_date'].fillna('2014-06-01')
df.loc[2656] = df.loc[2656].fillna('94, limit=1')
df.loc[4140] = df.loc[4140].fillna('240, limit=1')
df.info()
 
print(len(df.id.unique()))
 
df['release_year'] = pd.to_datetime(df.release_date, format='%Y-%m-%d', errors='coerce').dt.year
df['release_month'] = pd.to_datetime(df.release_date).apply(lambda x: x.month)
df['release_day'] = pd.to_datetime(df.release_date).apply(lambda x: x.day)
df.info()
print(df['release_year'], df['release_month'], df['release_day'])
 
df = df[(df.vote_count >= 50) & (df.budget * df.revenue * df.popularity * df.vote_average != 0)].reset_index(
    drop='True')
df.info()
 
# Json格式处理
json_column = ['genres', 'keywords', 'production_companies', 'production_countries', 'cast', 'crew']
 
# 1-json本身为字符串类型,先转换为字典列表
for i in json_column:
    df[i] = df[i].apply(json.loads)
 
 
# 提取name
# 2-将字典列表转换为以','分割的字符串
def get_name(x):
    return ','.join([i['name'] for i in x])
 
 
df['cast'] = df['cast'].apply(get_name)
 
 
# 提取derector
def get_director(x):
    for i in x:
        if i['job'] == 'Director':
            return i['name']
 
 
df['crew'] = df['crew'].apply(get_director)
 
for j in json_column[0:4]:
    df[j] = df[j].apply(get_name)
 
# 重命名
rename_dict = {'cast': 'actor', 'crew': 'director'}
df.rename(columns=rename_dict, inplace=True)
df.info()
print(df.head(5).genres)
print(df.head(5).keywords)
print(df.head(5).production_companies)
print(df.head(5).production_countries)
print(df.head(5).actor)
print(df.head(5).director)
 
# 数据备份
org_df = df.copy()
df.reset_index().to_csv("TMDB_5000_Movie_Dataset_Cleaned.csv")
 
# 定义一个集合,获取所有的电影类型
genre = set()
for i in df['genres'].str.split(','):  # 去掉字符串之间的分隔符,得到单个电影类型
    genre = set().union(i, genre)  # 集合求并集
    # genre.update(i) #或者使用update方法
 
print(genre)
 
# 将genre转变成列表
genre_list = list(genre)
 
# 创建数据框-电影类型
genre_df = pd.DataFrame()
 
# 对电影类型进行one-hot编码
for i in genre_list:
    # 如果包含类型 i,则编码为1,否则编码为0
    genre_df[i] = df['genres'].str.contains(i).apply(lambda x: 1 if x else 0)
 
# 将数据框的索引变为年份
genre_df.index = df['release_year']
 
# 计算得到每种类型的电影总数目,并降序排列
grnre_sum = genre_df.sum().sort_values(ascending=False)
# 可视化
plt.rcParams['font.sans-serif'] = ['SimHei'# 用来显示中文
grnre_sum.plot(kind='bar', label='genres', figsize=(12, 9))
plt.title('电影类型数量', fontsize=20)
plt.xticks(rotation=60)
plt.xlabel('类型', fontsize=16)
plt.ylabel('数量', fontsize=16)
plt.grid(False)
plt.savefig("电影类型数量-条形图.png", dpi=300# 在 plt.show() 之前调用 plt.savefig()
plt.show()
 
# 绘制饼图
gen_shares = grnre_sum / grnre_sum.sum()
# 设置other类,当电影类型所占比例小于%1时,全部归到other类中
others = 0.01
gen_pie = gen_shares[gen_shares >= others]
gen_pie['others'] = gen_shares[gen_shares < others].sum()
 
# 设置分裂属性
# 所占比例小于或等于%2时,增大每块饼片边缘偏离半径的百分比
explode = (gen_pie <= 0.02) / 10
 
gen_pie.plot(kind='pie', label='', explode=explode, startangle=0, shadow=False, autopct='%3.1f%%', figsize=(8, 8))
 
plt.title('电影类型占比', fontsize=20)
plt.savefig("电影类型占比-饼图.png", dpi=300)
plt.show()
 
gen_year_sum = genre_df.sort_index(ascending=False).groupby('release_year').sum()
gen_year_sum_sub = gen_year_sum[
    ['Drama', 'Comedy', 'Thriller', 'Action', 'Adventure', 'Crime', 'Romance', 'Science Fiction']]
gen_year_sum_sub.plot(figsize=(12, 9))
plt.legend(gen_year_sum_sub.columns)
plt.xticks(range(1915, 2018, 10))
plt.xlabel('年份', fontsize=16)
plt.ylabel('数量', fontsize=16)
plt.title('电影类型变化趋势', fontsize=20)
 
plt.grid(False)
plt.savefig("电影类型变化趋势-折线图.png", dpi=600)
plt.show()
 
# Step1-创建profit_dataframe
profit_df = pd.DataFrame()
profit_df = pd.concat([genre_df.reset_index(), df['revenue']], axis=1)
# Step2-创建profit_series,横坐标为genre
profit_s = pd.Series(index=genre_list)
# Step3-求出每种genre对应的利润均值
for i in genre_list:
    profit_s.loc[i] = profit_df.loc[:, [i, 'revenue']].groupby(i, as_index=False).mean().loc[1, 'revenue']
profit_s = profit_s.sort_values(ascending=True)
# 计算不同类型电影的budget
# Step1-创建profit_dataframe
budget_df = pd.DataFrame()
budget_df = pd.concat([genre_df.reset_index(), df['budget']], axis=1)
# Step2-创建budget_series,横坐标为genre
budget_s = pd.Series(index=genre_list)
# Step3-求出每种genre对应的预算均值
for j in genre_list:
    budget_s.loc[j] = budget_df.loc[:, [j, 'budget']].groupby(j, as_index=False).mean().loc[1, 'budget']
profit_budget = pd.concat([profit_s, budget_s], axis=1)
profit_budget.columns = ['revenue', 'budget']
profit_budget['rate'] = (profit_budget['revenue'] / profit_budget['budget']) * 100
profit_budget_sort = profit_budget.sort_values(by='budget', ascending=False)
# 绘制不同类型电影平均预算和利润率(组合图)
x = profit_budget_sort.index
y1 = profit_budget_sort.budget
y2 = profit_budget_sort.rate
# 返回profit_budget的行数
length = profit_budget_sort.shape[0]
 
fig = plt.figure(figsize=(12, 9))
# 左轴
ax1 = fig.add_subplot(1, 1, 1)
plt.bar(range(0, length), y1, color='b', label='平均预算')
plt.xticks(range(0, length), x, rotation=90, fontsize=12# 更改横坐标轴名称
ax1.set_xlabel('年份'# 设置x轴label ,y轴label
ax1.set_ylabel('平均预算', fontsize=16)
ax1.legend(loc=2, fontsize=12)
 
# 右轴
# 共享x轴,生成次坐标轴
ax2 = ax1.twinx()
ax2.plot(range(0, length), y2, 'ro-.')
ax2.set_ylabel('平均利润率', fontsize=16)
ax2.legend(loc=1, fontsize=12)
 
# 将利润率坐标轴以百分比格式显示
import matplotlib.ticker as mtick
 
fmt = '%.1f%%'
yticks = mtick.FormatStrFormatter(fmt)
ax2.yaxis.set_major_formatter(yticks)
 
# 设置图片title
ax1.set_title('电影类型的平均预算和利润率', fontsize=20)
ax1.grid(False)
ax2.grid(False)
plt.savefig("电影类型的平均预算和利润率-组合图.png", dpi=300)
plt.show()
 
# 绘制不同类型电影预算和收入(条形图)
profit_budget_sort.iloc[:, 0:2].plot(kind='bar', figsize=(12, 9), color=['darkorange', 'b'])
plt.title('平均预算(budget)与平均收入(revenue)', fontsize=20)
plt.xlabel('len', fontsize=16)
plt.grid(False)
plt.savefig('电影类型的平均预算和平均收入-条形图.png', dpi=300)
plt.show()
 
# keywords关键词分析
keywords_list = []
for i in df['keywords']:
    keywords_list.append(i)
# print(keywords_list)
# 把字符串列表连接成一个长字符串
lis = ''.join(keywords_list)
lis.replace('\'s', '')
# 设置停用词
stopwords = set(STOPWORDS)
stopwords.add('film')
stopwords.add('based')
wordcloud = WordCloud(
    background_color='black',
    random_state=9# 设置一个随机种子,用于随机着色
    stopwords=stopwords,
    max_words=3000,
    scale=1).generate(lis)
plt.figure(figsize=(10, 6))
plt.imshow(wordcloud)
plt.axis('off')
plt.savefig('词云图.png', dpi=300)
plt.show()
 
 
print(df.runtime.head(5))
df.runtime = df.runtime.astype(float)
print(df.runtime.head(5))
 
 
 
sns.snsset_style('white')
sns.distplot(df.runtime, bins=20)
sns.despine(left=True# 使用despine()方法来移除坐标轴,默认移除顶部和右侧坐标轴
plt.xticks(range(50, 360, 20))
plt.savefig('电影时长直方图.png', dpi=300)
plt.show()
 
fig = plt.figure(figsize=(8, 6))
 
x = list(range(1, 13))
y1 = df.groupby('release_month').revenue.size()
y2 = df.groupby('release_month').revenue.mean()  # 每月单片平均票房
 
# 左轴
ax1 = fig.add_subplot(1, 1, 1)
plt.bar(x, y1, color='b', label='电影数量')
plt.grid(False)
ax1.set_xlabel(u'月份'# 设置x轴label ,y轴label
ax1.set_ylabel(u'每月电影数量', fontsize=16)
ax1.legend(loc=2, fontsize=12)
 
# 右轴
ax2 = ax1.twinx()
plt.plot(x, y2, 'ro--', label=u'单片平均票房')
ax2.set_ylabel(u'每月单片平均票房', fontsize=16)
ax2.legend(loc=1, fontsize=12)
 
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.savefig('每月电影数量和单片平均票房.png', dpi=300)
plt.rc("font", family="SimHei", size="15")
plt.show()
 
 
 
#票房分布及票房Top10的导演
# 创建数据框 - 导演
director_df = pd.DataFrame()
 
director_df = df[['director','revenue','budget','vote_average']]
director_df['profit'] = (director_df['revenue']-director_df['budget'])
 
director_df = director_df.groupby(by = 'director').mean().sort_values(by='revenue',ascending = False) # 取均值
director_df.info()
 
# 绘制票房分布直方图
director_df['revenue'].plot.hist(bins=100, figsize=(8,6))
plt.xlabel('票房')
plt.ylabel('频数')
plt.title('导演的票房分布直方图')
plt.savefig('导演的票房分布直方图.png',dpi = 300)
plt.show()
 
# 票房均值Top10的导演
director_df.revenue.sort_values(ascending = True).tail(10).plot(kind='barh',figsize=(8,6))
plt.xlabel('票房',fontsize = 16)
plt.ylabel('导演',fontsize = 16)
plt.title('票房排名Top10的导演',fontsize = 20)
plt.savefig('票房排名Top10的导演.png',dpi = 300)
plt.show()
 
 
 
#评分分布及评分Top10的导演
# 绘制导演评分直方图
director_df['vote_average'].plot.hist(bins=18, figsize=(8,6))
plt.xlabel('评分')
plt.ylabel('频数')
plt.title('导演的评分分布直方图')
plt.savefig('导演的评分分布直方图.png',dpi = 300)
plt.show()
 
# 评分均值Top10的导演
director_df.vote_average.sort_values(ascending = True).tail(10).plot(kind='barh',figsize=(8,6))
plt.xlabel('评分',fontsize = 16)
plt.ylabel('导演',fontsize = 16)
plt.title('评分排名Top10的导演',fontsize = 20)
plt.savefig('评分排名Top10的导演.png',dpi = 300)
plt.show()
 
 
#原创 VS 改编占比(饼图)
# 创建数据框
original_df = pd.DataFrame()
original_df['keywords'] = df['keywords'].str.contains('based on').map(lambda x: 1 if x else 0)
original_df['profit'] = df['revenue'] - df['budget']
original_df['budget'] = df['budget']
 
# 计算
novel_cnt = original_df['keywords'].sum() # 改编作品数量
original_cnt = original_df['keywords'].count() - original_df['keywords'].sum() # 原创作品数量
# 按照 是否原创 分组
original_df = original_df.groupby('keywords', as_index = False).mean() # 注意此处计算的是利润和预算的平均值
# 增加计数列
original_df['count'] = [original_cnt, novel_cnt]
# 计算利润率
original_df['profit_rate'] = (original_df['profit'] / original_df['budget'])*100
 
# 修改index
original_df.index = ['original', 'based_on_novel']
# 计算百分比
original_pie = original_df['count'] / original_df['count'].sum()
 
# 绘制饼图
original_pie.plot(kind='pie',label='',startangle=90,shadow=False,autopct='%2.1f%%',figsize=(8,8))
plt.title('改编 VS 原创',fontsize=20)
plt.legend(loc=2,fontsize=10)
plt.savefig('改编VS原创-饼图.png',dpi=300)
plt.show()
 
 
 
#原创VS改编 预算/利润率(组合图)
x = original_df.index
y1 = original_df.budget
y2 = original_df.profit_rate
 
fig= plt.figure(figsize = (8,6))
 
# 左轴
ax1 = fig.add_subplot(1,1,1)
plt.bar(x,y1,color='b',label='平均预算',width=0.25)
plt.xticks(rotation=0, fontsize=12# 更改横坐标轴名称
ax1.set_xlabel('原创 VS 改编')                   # 设置x轴label ,y轴label
ax1.set_ylabel('平均预算',fontsize=16)
ax1.legend(loc=2,fontsize=10)
 
#右轴
# 共享x轴,生成次坐标轴
ax2 = ax1.twinx()
ax2.plot(x,y2,color='r',label='平均利润率')
ax2.set_ylabel('平均利润率',fontsize=16)
ax2.legend(loc=1,fontsize=10) # loc=1,2,3,4分别表示四个角,和四象限顺序一致
 
# 将利润率坐标轴以百分比格式显示
import matplotlib.ticker as mtick
fmt='%.1f%%'
yticks = mtick.FormatStrFormatter(fmt)
ax2.yaxis.set_major_formatter(yticks)
 
plt.savefig('改编VS原创的预算以及利润率-组合图.png',dpi=300)
plt.show()
 
 
 
revenue_corr = df[['runtime','popularity','vote_average','vote_count','budget','revenue']].corr()
 
sns.heatmap(
            revenue_corr,
            annot=True, # 在每个单元格内显示标注
            cmap="Blues", # 设置填充颜色:黄色,绿色,蓝色
            cbar=True# 显示color bar
            linewidths=0.5, # 在单元格之间加入小间隔,方便数据阅读
           )
plt.savefig('票房相关系数矩阵.png',dpi=300)
plt.show()
 
 
fig = plt.figure(figsize=(17,5))
 
ax1 = plt.subplot(1,3,1)
ax1 = sns.regplot(x='budget', y='revenue', data=df, x_jitter=.1,color='r',marker='x')
# marker: 'x','o','v','^','<'
# jitter:抖动项,表示抖动程度
ax1.text(1.6e8,2.2e9,'r=0.7',fontsize=16)
plt.title('budget-revenue-scatter',fontsize=20)
plt.xlabel('budget',fontsize=16)
plt.ylabel('revenue',fontsize=16)
 
ax2 = plt.subplot(1,3,2)
ax2 = sns.regplot(x='popularity', y='revenue', data=df, x_jitter=.1,color='g',marker='o')
ax2.text(500,3e9,'r=0.59',fontsize=16)
plt.title('popularity-revenue-scatter',fontsize=18)
plt.xlabel('popularity',fontsize=16)
plt.ylabel('revenue',fontsize=16)
 
ax3 = plt.subplot(1,3,3)
ax3 = sns.regplot(x='vote_count', y='revenue', data=df, x_jitter=.1,color='b',marker='v')
ax3.text(7000,2e9,'r=0.75',fontsize=16)
plt.title('voteCount-revenue-scatter',fontsize=20)
plt.xlabel('vote_count',fontsize=16)
plt.ylabel('revenue',fontsize=16)
plt.savefig('revenue.png',dpi=300)
plt.show()

今天进行了大数据测试

练习题:观影大数据分析

王 S 聪想要在海外开拓万 D 电影的市场,这次他在考虑:怎么拍商业电影才能赚钱?毕竟一些制作成本超过 1 亿美元的大型电影也会失败。这个问题对电影业来说比以往任何时候都更加重要。 所以,他就请来了你(数据分析师)来帮他解决问题,给出一些建议,根据数据分析一下商业电影的成功是否存在统一公式?以帮助他更好地进行决策。

解决的终极问题是:电影票房的影响因素有哪些?接下来我们就分不同的维度分析: • 观众喜欢什么电影类型?有什么主题关键词? • 电影风格随时间是如何变化的? • 电影预算高低是否影响票房? • 高票房或者高评分的导演有哪些? • 电影的发行时间最好选在啥时候? • 拍原创电影好还是改编电影好?本次使用的数据来自于 Kaggle 平台(TMDb 5000 Movie Database)。收录了美国地区 1916-2017 年近 5000 部电影的数据,包含预算、导演、票房、电影评分等信息。原始数据集包含 2 个文件:

• tmdb_5000_movies:电影基本信息,包含 20 个变量 • tmdb_5000_credits:演职员信息,包含 4 个变量

请使用 Python 编程,完成下列问题:

(1)    使用附件中的 tmdb_5000_movies.csv 和 tmdb_5000_credits.csv 数据集,进行数据清洗、数据挖掘、数据分析和数据可视化等,研究电影票房的影响因素有哪些?从不同的维度分析电影,讨论并分析你的结果。

(2)    附件 tmdb_1000_predict.csv 中包含 1000 部电影的基本信息,请你选择合适的指标,进行特征提取,建立机器学习的预测模型,预测 1000 部电影的 vote_average 和 vote_count,并保存为 tmdb_1000_predicted.csv。

 

posted @   漏网鲨鱼  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示