1. 程式人生 > 其它 >MathorCup 高校數學建模挑戰賽——大資料競賽

MathorCup 高校數學建模挑戰賽——大資料競賽

MathorCup 高校數學建模挑戰賽——大資料競賽

練習題:觀影大資料分析

王 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。


資料清洗

匯入資料

 

 

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用來顯示中文
plt.rcParams['axes.unicode_minus'] = False  # 用來正常顯示負號

import json

import warnings

warnings.filterwarnings('ignore')

pd.set_option('display.width', 1000)  # 加了這一行那表格的一行就不會分段出現了

# 顯示所有列
pd.set_option('display.max_columns', None)
# 顯示所有行
pd.set_option('display.max_rows', None)

movies = pd.read_csv('D:\\installed\\python\\document\\tmdb_5000_movies.csv', encoding='utf_8')
credits = pd.read_csv('D:\\installed\\python\\document\\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()

 

 

 

 

 

 

 

 

 

 

 

缺失值處理

 

缺失記錄僅 3條,採取網上搜索,補全資訊。

2.1 補全 release_date

 

查詢release_date是空

print("查詢缺失值記錄-release_date +++++++++++++++++++++++++++++++")
n = df[df.release_date.isnull()]
print(n)

 

 

 

 

 

 

 

 

 

 

 

缺失記錄的電影標題為《 America Is Still the Place》,日期為  2014-06-01。

2.2 補全 runtime

 

查詢runtime是空的資料

 

n2 = df[df.runtime.isnull()]
print(n2)

 

 

 

 

 

 

 

 

 

 

缺失記錄的電影 runtime 分別為 94min 和 240min。

重複值處理

 

 

print("重複值處理+++++++++++++++++++++++++++++++")
n3 = len(df.id.unique())
print(n3)

 

 

 

 

執行結果:有 4803個不重複的 id,可以認為沒有重複資料。


日期值處理

 

將 release_date 列轉換為日期型別:

print("release_date 列轉換為日期型別+++++++++++++++++++++++++++++++++")
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()

篩選資料

 

使用資料分析師最喜歡的一個語法:

n4 = df.describe()
print(n4)

票房、預算、受歡迎程度、評分為 0的資料應該去除;

評分人數過低的電影,評分不具有統計意義,篩選評分人數大於 50的資料。

df = df[(df.vote_count >= 50) & (df.budget * df.revenue * df.popularity * df.vote_average !=0)].reset_index(drop = 'True')
df.info()

此時剩餘 2961條資料,包含 19個欄位。

json 資料轉換

 

**說明:**genres,keywords,production_companies,production_countries,cast,crew 這 6 列都是

json 資料,需要處理為列表進行分析。處理方法:

json 本身為字串型別,先轉換為字典列表,再將字典列表轉換為,以’,'分割的字串

print("+++++++++++++++++++++++++pppppppppppppp")
json_column = ['genres', 'keywords', 'production_companies', 'production_countries', 'cast', 'crew']

# 1-json本身為字串型別,先轉換為字典列表
for i in json_column:
    df[i] = df[i].apply(json.loads)

# 2-將字典列表轉換為以','分割的字串
def get_name(x):
    return ','.join([i['name'] for i in x])

df['cast'] = df['cast'].apply(get_name)

# 3.提取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()

df.head(5)


資料備份

 

print("++++++++++++++++++++++++++++++++")
# 備份原始資料框original_df
org_df = df.copy()
df.reset_index().to_csv("TMDB_5000_Movie_Dataset_Cleaned.csv")
df.info()

 

 

 

 

 

 

 

 

 

 

 

資料分析

 

5.1 why

 

想要探索影響票房的因素,從電影市場趨勢,觀眾喜好型別,電影導演,發行時間,評分與關鍵詞等維度著手,給從業者提供合適的建議。

5.2 what

5.2.1 電影型別:定義一個集合,獲取所有的電影型別

genre = set()
for i in df['genres'].str.split(','):  # 去掉字串之間的分隔符,得到單個電影型別
    genre = set().union(i, genre)  # 集合求並集
    # genre.update(i) #或者使用update方法
print(genre)

注意到集合中存在多餘的元素:空的單引號,所以需要去除。

genre.discard('')
print("去除多餘的元素")
print(genre)


5.2.1.1 電影型別數量(繪製條形圖)

# 將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']
genre_df.head(5)


# 計算得到每種型別的電影總數目,並降序排列
grnre_sum = genre_df.sum().sort_values(ascending=False)

# 視覺化
colors = ['cyan', 'red']
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用來顯示中文
grnre_sum.plot(kind='bar', label='genres', color=colors, 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()

5.2.1.2 電影型別佔比(繪製餅圖)

5.2.1.3 電影型別變化趨勢(繪製折線圖)