机器学习系列(2)_数据分析之Kaggle电影TMDB5000
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                机器学习系列(2)_数据分析之Kaggle电影TMDB5000
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                文章目錄
- 一、數據整理
- 1、合并+處理缺失值
- 2、對于json格式的數據進行分割提取
 
- 二、 電影類型隨時間變化怎么樣?
- 三、 電影類型與利潤的關系
- 四、 Universal和Paramount兩家影視公司的對比情況如何?
- 五、 改編電影和原創電影以及評分情況如何
- 六、 電影時長與電影票房以及評分的關系
- 七、 分析電影關鍵字
- 1、根據jieba生成詞頻計算
- 2、根據pkuseg生成詞頻計算
 
- 八、分析演員的關聯度(社會網絡計算)
一、數據整理
1、合并+處理缺失值
# tmdb_5000_movies.csv budget :電影成本 genres:風格列表,按|分隔,最多5種風格 homepage:電影首頁URL id :電影ID keywords:電影關鍵詞,按|分隔,最多5種關鍵詞 original_language:原始語言 original_title :電影名稱 overview:劇情摘要 popularity:熱度 production_companies:制作商 production_countries:制作地區 release_date:首次上映日期 revenue :收入 runtime :電影時長 spoken_languages:語言 status:是否發布 tagline:一句話說明一部電影(往往是海報上面的) title :電影名稱 vote_average:平均分 vote_count:投票人數 # tmdb_5000_credits.csv movie_id:電影ID title:電影名稱 cast:演員表 crew:制作團隊(分析那些人經常出現在高票房的電影里面) import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt %matplotlib inline plt.style.use('ggplot') import json import warnings warnings.filterwarnings('ignore')#忽略警告credits_file='D:/S072003Python/05DataMineML/tmdb_5000_credits.csv' movies_file='D:/S072003Python/05DataMineML/tmdb_5000_movies.csv' credits=pd.read_csv(credits_file) movies=pd.read_csv(movies_file)
 
2、對于json格式的數據進行分割提取
# 如何從json的數據格式提取需要的數據 # 提取電影風格數據genres moviesdf['genreslist']=moviesdf['genres'].apply(json.loads) moviesdf.head(1) moviesdf['castlist']=moviesdf['cast'].apply(json.loads) moviesdf['countries']=moviesdf['production_countries'].apply(json.loads) # json.loads()將str類型的數據轉換為dict類型 moviesdf['companies']=moviesdf['production_companies'].apply(json.loads) moviesdf['crewslist']=moviesdf['crew'].apply(json.loads) moviesdf.head(1)定義函數處理genres:
# 每一個genres [{"id": 28, "name": "Action"}, {"id": 12, "name": "Adventure"}, {"id": 14, "name": "Fantasy"}, {"id": 878, "name": "Science Fiction"}] #等于json格式的數據進行分割提取,通過自定義函數 def decode(column):z=[]for i in column:z.append(i['name'])return ' '.join(z) # 獲取dict中第一個元素的name值 def decode1(column):z=[]for i in column:z.append(i['name'])return ''.join(z[0:1]) #切片,只輸出第一個分隔 moviesdf['genresls']=moviesdf['genreslist'].apply(decode1)二、 電影類型隨時間變化怎么樣?
# 電影類型與時間的關系 genres_list=set() # 獲取所有的電影風格 for i in moviesdf['genresls'].str.split(' '):genres_list=set().union(i,genres_list) # 集合(set)是一個無序的不重復元素序列。可以使用大括號 { } 或者 set() 函數創建集合。genres_list=list(genres_list)genres_listgenres_list.remove('') # 去除空的元素 print(genres_list)moviesdf['releaseyear']=pd.to_datetime(moviesdf['release_date']).dt.year moviesdf.head(3) moviesdf.to_excel('moviesdfv3.xlsx',index=False)得到的所有電影的風格genres_list:
['Movie', 'Documentary', 'Comedy', 'Crime', 'Fantasy', 'History', 'Drama', 'Horror', 'Action', 'War', 'Foreign', 'Thriller', 'Fiction', 'Animation', 'Science', 'Music', 'Western', 'Romance', 'Family', 'TV', 'Mystery', 'Adventure']目的:由于每部電影不只一種風格,則為每種風格添加一個字段,如果該電影包含這種風格則填1,否則填0。
for genre in genres_list:moviesdf[genre]=moviesdf['genresls'].str.contains(genre).apply(lambda x:1 if x else 0)moviesdf[genre].tail() moviesdf.head(2) genre_year=moviesdf.loc[:,genres_list] genre_year.index=moviesdf['releaseyear'] genresdf=genre_year.groupby('releaseyear').sum() genresdf genresdf.plot(figsize=(16,10))
 
genresdfsum:拿到從1916到2017年所有風格電影數據的總和
Drama 2297 Comedy 1722 Thriller 1274 Action 1154 Romance 894 Adventure 790 Crime 696 Fiction 535 Science 535 Horror 519 Family 513 Fantasy 424 Mystery 348 Animation 234 History 197 Music 185 War 144 Documentary 110 Western 82 Foreign 34 TV 8 Movie 8 dtype: int64 genresdfsum.sort_values().plot(kind='barh',label='genres') # 如果是kind='bar'則橫縱坐標交換 plt.rcParams['font.sans-serif']=['Microsoft YaHei'] # 使用微軟雅黑的字體 plt.title('電影類型數量排名統計圖') plt.xlabel('電影數量') plt.ylabel('電影類型') plt.show() # 計算電影類型的餅圖 genres_pie=genresdfsum/genresdfsum.sum() others=0.01 genres_pie_otr=genres_pie[genres_pie>=others] genres_pie_otr['other']=genres_pie[genres_pie<others].sum()explode=(genres_pie_otr<=0.02)/10+0.04 genres_pie_otr.plot(kind='pie',label='',startangle=50,shadow=False,figsize=(10,10),autopct='%1.1f%%',explode=explode) # 電影類型和時間關系的分析 plt.figure(figsize=(16,10)) plt.plot(genresdf,label=genresdf.columns) plt.xticks(range(1905,2021,5)) plt.legend(genresdf) plt.title('電影類型與時間',fontsize=15) plt.xlabel('年份',fontsize=15) plt.ylabel('%ddir影數量',fontsize=15) plt.show()三、 電影類型與利潤的關系
# 電影類型與利潤的關系 mean_genre_profit=pd.DataFrame(index=genres_list) mean_genre_profit.head() newarray=[] for genre in genres_list: # moviesdf.groupby('War',as_index=True)['profit'].mean() # 使得War得到兩組數據,第一組為0,即不是War類型的平均值,無意義,因此下面只取第二組1newarray.append(moviesdf.groupby(genre,as_index=True)['profit'].mean())newarray2=[] for i in range(len(genres_list)):newarray2.append(newarray[i][1]) # 這里取的是第二個數據, mean_genre_profit['mean_profit']=newarray2 mean_genre_profit.head(17)得到的mean_profit:
mean_profit Movie -1.150000e+06 Documentary 7.185600e+06 Comedy 4.597608e+07 Crime 3.830085e+07 Fantasy 1.297936e+08 History 2.762010e+07 Drama 3.143791e+07 Horror 2.897105e+07 Action 8.970235e+07 War 4.887342e+07 Foreign -2.934369e+05 Thriller 4.907608e+07 Fiction 1.005910e+08 Animation 1.592271e+08 Science 1.005910e+08 Music 3.254800e+07 Western 1.916726e+07 Romance 3.969103e+07 Family 1.116260e+08 TV -1.150000e+06 Mystery 4.755644e+07 Adventure 1.423333e+08 # 繪制電影類型與平均利潤的關系 mean_genre_profit.sort_values(by='mean_profit').plot(kind='barh') plt.xlabel('平均利潤') plt.ylabel('電影類型') plt.title('電影類型與平均利潤的關系')四、 Universal和Paramount兩家影視公司的對比情況如何?
# 對比兩家電影公司的電影發行情況 # 對電影公司的數據進行整理 moviesdf['prodcompanies']=moviesdf['production_companies'].apply(json.loads) moviesdf['prodcompany']=moviesdf['prodcompanies'].apply(decode) # 用到上面定義的函數 moviesdf.head() moviesdf['Universal']=moviesdf['prodcompany'].str.contains('Universal Pictures').apply(lambda x:i if x else 0) moviesdf['Paramount']=moviesdf['prodcompany'].str.contains('Paramount Pictures').apply(lambda x:i if x else 0) moviesdf.tail() a=moviesdf['Universal'].sum() b=moviesdf['Paramount'].sum() dict_companies={'Universal':a,'Paramount':b} dict_companies companies_number=pd.Series(dict_companies) companies_number.plot(kind='pie',label='',autopct='%11.1f%%') company=moviesdf[['Universal','Paramount']] company.index=moviesdf['releaseyear'] companydf=company.groupby('releaseyear').sum() companydf.head()plt.figure(figsize=(10,7)) plt.plot(companydf,label=companydf.columns)五、 改編電影和原創電影以及評分情況如何
# 通過keywords字段,分割改編電影與原創電影的對比 # 分析:在keywords字段中,如果存在based on novel 則說明電影改編自小說 moviesdf['keywds']=moviesdf['keywords'].apply(json.loads) moviesdf['keywds2']=moviesdf['keywds'].apply(decode)# 標注是否為基于小說改編的電影 a='based on novel' moviesdf['if_original']=moviesdf['keywds2'].str.contains(a).apply(lambda x:'no original' if x else 'original') moviesdf['if_original'].value_counts() # moviesdf.head(2)original_profit=moviesdf[['if_original','budget','revenue','profit']] original_profit_mean=original_profit.groupby(by='if_original').mean() original_profit_mean.head() plt.figure(figsize=(12,9)) original_profit_mean.plot(kind='bar') plt.title('原創電影與改編電影的預算,收入,利潤比較') plt.xlabel('原創與改編') plt.ylabel('現金流') plt.xticks(rotation=0)六、 電影時長與電影票房以及評分的關系
# 電影的runtime與票房,評分之間的關系 moviesdf.plot(kind='scatter',x='runtime',y='revenue',figsize=(10,7)) plt.title('電影時長與票房的關系',fontsize=15) plt.xlabel('時長(分鐘)',fontsize=15) plt.ylabel('票房收入',fontsize=15) # 電影的時長與評分之間的關系 moviesdf.plot(kind='scatter',x='runtime',y='vote_average',figsize=(10,7)) plt.title('電影時長與評分之間的關系',fontsize=15) plt.xlabel('時長(分鐘)',fontsize=15) plt.ylabel('評分',fontsize=15)七、 分析電影關鍵字
1、根據jieba生成詞頻計算
# 電影關鍵字詞頻計算和詞云生成 keywords_list=[] for i in moviesdf['keywds2']:keywords_list.append(i) # keywords_list=list(keywords_list) lis=''.join(keywords_list) lis.replace('\'s','') lis # 根據電影關鍵詞生成詞頻計算 import jieba words=jieba.lcut(lis) counts={} mytext_list=[] for word in words:if len(word)==1: # 單個分詞不需要continue else:counts[word]=counts.get(word,0)+1mytext_list.append(word.replace(" ","")) cloud_text=','.join(mytext_list) # print(cloud_text) items=list(counts.items()) items.sort(key=lambda x:x[1],reverse=True) for i in range(100):word,countsnt=items[i]print("{0:<10}{1:>5}".format(word,count))
 
2、根據pkuseg生成詞頻計算
# 安裝pkuseg !pip install pkuseg #調用北大算法和jieba算法得到的結果對于英文來說基本相同,但對于中文來說pkuseg會更加準確 #根據電影關鍵詞生成詞頻計算 北大算法pkuseg # 根據電影關鍵詞生成詞頻計算 import pkuseg seg=pkuseg.pkuseg()words=seg.cut(lis) # 與jieba的區別主要是調用的算法不同counts={} mytext_list=[] for word in words:if len(word)==1: # 單個分詞不需要continue else:counts[word]=counts.get(word,0)+1mytext_list.append(word.replace(" ","")) cloud_text=','.join(mytext_list) # print(cloud_text) items=list(counts.items()) items.sort(key=lambda x:x[1],reverse=True) for i in range(100):word,count=items[i]print("{0:<20}{1:>5}".format(word,count))八、分析演員的關聯度(社會網絡計算)
# 分析演員的關聯度(社會網絡計算) moviesdf['actorsls'] actors_list=[] actorsforcut=[]# 將每部電影的演員放在列表當中 for i in moviesdf['actorsls']:actors_list.append(i.split(','))# 將演員列表中的對象放置到為分割而設置的另一個列表 for k in range(0,len(actors_list)):for j in range(len(actors_list[k])):actorsforcut.append(actors_list[k][j])actors_list=''.join(actorsforcut) actors_list此時生成的actors_list[0:100]:
 
此時生成的詞云是不完整的
 
 改進方法:變換詞云的結構:
此時生成的actors_list[0:100]:
 
 
 將演員中間的空格去除,并合并為一個整體
 思路:如果我們按照actorsdf去尋找movieactorsdfv2,只要在電影里面找到了演員的名字,則在對應的actorsdf上面加一,就能知道哪些演員演過的電影最多。并且還可以將不同演員之間建立關系,最后使用pyechart進行可視化。
總結
以上是生活随笔為你收集整理的机器学习系列(2)_数据分析之Kaggle电影TMDB5000的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: BCNet实现PLC数据采集解决方案,B
- 下一篇: TMDB数据导入elasticsearc
