數據分析實踐!豆瓣高分電影推薦(上)
摘要
本次實踐案例有上下兩個部分,上部記錄了筆者整個分析報告製作的全過程;下部為最終的分析報告。整個分析分為7個步驟:「建立目標」,「理解數據」,「數據獲取」,「數據清洗」,「SQL數據信息查詢」,「數據信息可視化」,「輸出數據分析報告。
涉及到的語言和軟體包括:python3.6 ,mysql ,excel ,ppt。
建立目標
進行數據分析之前,重要的事情說三遍:明確目標!明確目標!明確目標!
原因1: 數據分析過程只有圍繞著在明確的目標進行,結論才能經得起推敲和檢驗。
原因2:明確了目標才能在數據獲取環節,不會因為多取了不相關的欄位浪費資源,亦不會因為少跑了欄位,需要重新跑數據做無用功。
這次分析的目標:通過分析豆瓣電影數據來給電影愛好者們推薦稱心滿意的優質電影。
在以此為一級目標的大前提下,將1級目標結構化的拆解為2、3的子目標,在根據子目標的需要確定下個環節數據獲取環節所需要的欄位。
分析目標的腦圖如下,一級目標分為:整體的描述性分析,電影詳情的推薦,推薦又分為三個3級子目標分別是按綜合評分推薦,按類型推薦,按導演推薦。
理解數據
明確了目標後,讓我們登錄豆瓣電影看一看為了我們需要獲取哪些欄位來進行數據分析。
筆者提取了「電影名」,「評分」,「星級」,「評論數」,「上映時間」,「類型」,「導演名」,「演員名」幾個欄位。
電影名(用於識別電影)
評分(作為評價影片好壞的標準)
星級(與評分具有相關性,用於對電影分類)
評論數(作為影片是否熱門的參考標準)
上映時間(用於時間分類)
類型(用於按類型推薦)
導演名(用於按導演推薦)
演員名(本次分析暫不涉及,日後備用)
數據獲取
該階段,筆者用python編寫了爬蟲,通過爬蟲爬取所有豆瓣電影的所有的電影類型的影片信息(共500頁,9555條)。豆瓣電影現在的反爬機制是限制IP的訪問最大次數。所以強烈建議採用爬蟲的朋友在代碼中加上動態更新的IP池。( 筆者的代碼反爬不算完美,效率較低,附上代碼僅供參考)。
import reimport requestsfrom bs4 import BeautifulSoupimport jsonimport xlwtimport randomimport timedef crawl_detail(id): url = https://movie.douban.com/subject/+str(id) headers = { Cookie:bid=ffj9By7aODA; gr_user_id=7c5f802e-4096-441e-ac02-69a0702d2374; viewed="26931905_26546914_26945530_2157554_25716088_25744600_3821157_3313897_3169342_6414998"; __yadk_uid=JOguGnq2iMsYSFCASKz7HY4BkJ8RU3Lw; ll="108288"; _pk_id.100001.4cf6=699c695ed88c575d.1528542899.2.1528547379.1528543815.; _pk_ses.100001.4cf6=*; __utma=30149280.778281764.1517258511.1528542900.1528547336.3; __utmb=30149280.0.10.1528547336; __utmc=30149280; __utmz=30149280.1517258511.1.1.utmcsr=sogou.com|utmccn=(referral)|utmcmd=referral|utmcct=/link; __utma=223695111.23105693.1528542900.1528542900.1528547336.2; __utmb=223695111.0.10.1528547336; __utmc=223695111; __utmz=223695111.1528542900.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); _vwo_uuid_v2=665097E77B7A2BBBDEC3230A6FBF8616|e65e4da5db4f4bb34b81b959e3bb8cdf, User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.4882.400 QQBrowser/9.7.13059.400, Host:movie.douban.com, Referer:https://movie.douban.com/tag/, Upgrade-Insecure-Requests:1 } req = requests.get(url,headers=headers) soup = BeautifulSoup(req.content,lxml) movie_votes = soup.find(span,attrs={property:v:votes}) movie_releasedata = soup.find(span,attrs={property:v:initialReleaseDate}) genre = soup.find_all(span,attrs={property:v:genre}) movie_genre= [ ] for g in genre : g1 = g.text movie_genre.append(g1) movie_all = { "評論數":movie_votes.text, "首映時間":movie_releasedata.text, "影片類型":movie_genre } return movie_alldef main(): headers = { Host:movie.douban.com, Referer:https://movie.douban.com/tag/, User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.4882.400 QQBrowser/9.7.13059.400, } movies = [ ] n = 0 for i in range (1,2): url = https://movie.douban.com/j/new_search_subjects?sort=T&range=0,10&tags=&start=+str(i*20) req = requests.get(url,headers=headers) result = req.json() page_positions = result [data] m=0 for movie in page_positions : movie_dict = { "電影名":movie[title], "導演名":movie[directors], "演員名":movie[casts], "評分": movie[rate], "星級": movie[star], "鏈接": movie[url] } id = movie[id] pass movie_detail = crawl_detail(id) movie_dict[評論數] = movie_detail[評論數] movie_dict[首映時間] = movie_detail[首映時間] movie_dict[影片類型] = movie_detail[影片類型] movies.append(movie_dict) a1 = random.randint(1,3) time.sleep(a1) m=m+1 print(movies) print(第+str(m+n*20)+個電影!) a2 = random.randint(15,25) time.sleep(a2) n=n+1 print(第+str(n)+頁完成) work = xlwt.Workbook() #創建excel sheet1 = work.add_sheet(sheet1,cell_overwrite_ok=True) #創建sheet head= [電影名,導演名,演員名,評分,星級,鏈接,評論數,首映時間,影片類型] y=0 for item in head: #編輯表頭 sheet1.write(0,y,item) y+=1 x=1 for item in movies: if isinstance(item,dict): for head_item in head: if head_item in item.keys(): y=head.index(head_item) sheet1.write(x,y,item[head_item]) x+=1 work.save(豆瓣電影1-2.xls) #保存 print(finish) if __name__ == __main__: main()
數據清洗
數據清洗過程,筆者進行了如下操作
- 刪除重複項(刪除了電影名重疊的影片)
- 填補缺失值(將一些列為空值的地方填補了「暫無數據」)
- 格式的統一
- 星級列 (每一列乘0.1。例如:爬取的數據為40,轉化為4.0)
- 上映日期 (只保留年信息,刪除月日信息)
- 方便SQL語言的編寫,表頭更換為英文
數據清洗結果
SQL數據信息查詢
將清洗後的表格導入SQL,按著下面的問題逐一跑出數據,在跑數據的過程中(注意:為了讓數據更加精準要記得微調2,3級子目標,加一些過濾條件,筆者認為只要保證1級目標不變,改動優化即為合理的。)
問題1:(1990-2018)每年各上映的電影各有多少部?
SELECT yr , COUNT(name) from sheet1
where yr BETWEEN 1990 and 2018
GROUP BY yr
ORDER BY yr
問題2:(1990-2018)電影按星級分布情況?
SELECT level , COUNT(name) from sheet1
GROUP BY `level`
ORDER BY `level`
問題3:(1990-2018)每年電影的平均得分
SELECT AVG(scrore) , AVG(`level`), COUNT(name) ,yr from sheet1
Whe re yr BETWEEN 1990 and 2018
GROUP BY yr
ORDER BY yr
問題4:綜合評分高的熱門和冷門電影(通過評論數表徵熱門還是冷門)
SELECT name ,scrore , COMMENT from sheet1
where scrore BETWEEN 9 and 10
ORDER BY CONVERT(comment,SIGNED);
問題5
一共有哪幾種類型的電影?每種類型的各有多少部?哪類的影片最多?
劇情 4788;喜劇 2768;動作 1881;愛情 2124;科幻 676
懸疑 858;驚悚 1515;恐怖 614;犯罪 1209;戰爭 370
奇幻 791;冒險 1000;災難 96; 武俠 99
問題6:各種類型的影片評分最高的10部?
SELECT name ,type, scrore from sheet1
where (type like %類型關鍵字% )and ( type not like %短片% )
ORDER BY scrore DESC
問題7:一共有多少位導演?每個導演各導演過多少部電影?
4802
問題8:電影平均得分最高的5位導演是誰?,以及他們最受歡迎的3部的作品?
SELECT DISTINCT director , COUNT(name), avg(scrore) from sheet1
GROUP BY director
ORDER BY AVG(scrore) DESC
通過SQL把我們需要的信息提取出來導入excel,接下來就可以進行數據可視化和數據分析報告PPT的製作。最終的報告請關注《數據分析實踐!豆瓣高分電影推薦(下) 》
數據信息可視化
通過以上步驟我們有了要展示的主題,並且提取了我們需要展示的數據。那麼如何把數據信息用恰當的圖表可視化的表現出來呢? 這裡筆者參考了(Andrew Abela依據他提出的比較、分布、構成和聯繫這四種關係類型,整理了一份圖表選擇指南,拜謝作者)。
本次數據主要採用以下幾類:
- 「條形圖」(用於展示類別數據)
- 「柱狀圖」(用於展示時間相關數據)
- 「表格」(用於承載推薦影片信息)
拓展與思考
目前的分析只是停留在基礎的「描述性分析」的層面上,只是描述歷史數據。 我們還可以將每部電影的各個元素與最終評分之間的相關性進行建模。例如:導演,演員,評論數,這些因素的權重最終影響到評分,然後用這些數據訓練模型通過機器學習調優權重配比,最終達到可以預測新片的目的。筆者會隨著技能的增長有機會會繼續實踐預測的部分的案例,敬請期待。
推薦閱讀:
※《阿修羅》吳磊梁家輝劉嘉玲演「三頭阿修羅王」
※付費影視資源終結者:90%的人都不知道的免費影視資源下載站
※香港電影一些有趣的幕後和細節 第二期 我命由我不由天——《太極張三丰》
※當虛擬世界植入真實臉孔 聊聊真人出演的是與非
※《狄仁傑》看了那麼多版改編,哪一個是讓你最驚喜的?