數(shù)據可視化&分析實戰(zhàn)
1.1 沈騰參演電影數(shù)據獲取
1.2 電影數(shù)據可視化分析
前言
大家好?,這里是bio??。點贊+關注不迷路。數(shù)據可視化在數(shù)據科學和數(shù)據分析中非常重要,例如論文中配色精美的結果圖、PPT匯報中突出數(shù)據差異數(shù)據分析圖等。通過可視化,我們可以直觀地觀察和理解數(shù)據的分布、趨勢、異常值等特征。通過圖表和圖形,我們可以更輕松地發(fā)現(xiàn)數(shù)據中的模式和關聯(lián)。
本文是對上一篇博客中獲取的數(shù)據利用python進行可視化分析(沈騰參演電影數(shù)據獲?。?,看完本文你將學會:
- 解決
matplotlib
不能繪制中文的問題 - 如何使用
matplotlib
包繪制柱狀圖、折線圖、箱線圖、餅圖等 - 填充na的方法
- 衡量變量之間的關系以及建模
- 圖(graph)可視化分析
本文所用的所有代碼都在Github倉庫,你可以下載在本地運行(提前安裝好相關包~)。感興趣的話可以star
我的主頁。
1. 數(shù)據認知
在可視化開始之前,我們先對數(shù)據有一個基礎的認識,了解我們的數(shù)據能做什么樣的可視化分析,分析之后能得到什么樣的結果。本文所用數(shù)據來源于博客沈騰參演電影數(shù)據獲取,也可以使用積分從CSDN資源庫下載下載鏈接。本文所用的全部代碼已notebook
的格式存儲在Github,建議下載使用。
首先讀入文件,讀入時記得使用gbk
編碼方式,因為我們的數(shù)據中具有中文字符。而后將Rating_value
轉換為浮點數(shù),Year
轉換為字符,便于后續(xù)繪圖。
# time: 2023.07.27
# author: bio大恐龍
import pandas as pd
film_details_df = pd.read_csv('/mnt/c/Users/bio_dinosaur/Desktop/films_info.csv', encoding='gbk')
film_details_df['Rating_value'] = [float(i) for i in film_details_df['Rating_value']]
film_details_df['Year'] = [str(i) for i in film_details_df['Year']]
film_details_df.head()
然后看一下數(shù)據包含的變量,思考如何進行可視化展示~
Film_name URL Year Director Actors Genre Rating_count Rating_value IMDb Description Interesting_count Watched_count
0 超能一家人 https://movie.douban.com/subject/35228789/ 2023 宋陽 '艾倫', '沈騰', '陶慧', '張琪', '韓彥博', '白麗娜', '康晞婭', '... '喜劇', '家庭', '奇幻' 52844 4.0 tt12787014 鄭前(艾倫 飾)新開發(fā)的APP被狡猾又誠實的反派乞乞科夫(沈騰 飾)盯上了。幸好鄭前一家人意... 54367.0 36868.0
1 滿江紅 https://movie.douban.com/subject/35766491/ 2023 張藝謀 '沈騰', '易烊千璽', '張譯', '雷佳音', '岳云鵬', '王佳怡', '潘斌龍'... '劇情', '喜劇', '懸疑', '古裝' 993333 7.0 tt21148018 南宋紹興年間,岳飛死后四年,秦檜率兵與金國會談。會談前夜,金國使者死在宰相駐地,所攜密信也不... 1085283.0 71428.0
2 獨行月球 https://movie.douban.com/subject/35183042/ 2022 張吃魚 '沈騰', '馬麗', '常遠', '李誠儒', '黃才倫', '李嘉琦', '郝瀚', '... '喜劇', '科幻' 677450 6.6 tt14557302 人類為抵御小行星的撞擊,拯救地球,在月球部署了月盾計劃。隕石提前來襲,全員緊急撤離時,維修工... 815477.0 40755.0
3 四海 https://movie.douban.com/subject/35337517/ 2022 韓寒 '劉昊然', '劉浩存', '沈騰', '尹正', '喬杉', '周奇', '張宥浩', '... '喜劇', '動作', '愛情' 250478 5.3 tt14509614 在碼頭做摩托車特技表演順便拉客的年輕人吳仁耀(劉昊然 飾),他多年不見的浪蕩父親吳仁騰(沈騰... NaN NaN
4 我和我的父輩 https://movie.douban.com/subject/35294995/ 2021 吳京 '吳京', '章子怡', '徐崢', '沈騰', '吳磊', '黃軒', '袁近輝', '任... '劇情' 265552 6.5 tt15465312 繼2019年《我和我的祖國》、2020年《我和我的家鄉(xiāng)》,國慶三部曲之《我和我的父輩》接棒定... NaN NaN
2. 數(shù)據可視化
2.1 解決matplotlib不能繪制中文字符的問題
如果我們沒有中文字體,使用matplotlib
繪圖時,中文字符將會以空方塊展示出來。為了解決這一問題,首先使用下面的代碼輸出當前你具有的字體。(如果你能夠繪制中文字符,請?zhí)?.2)
from matplotlib.font_manager import FontManager
mpl_fonts = set(f.name for f in FontManager().ttflist)
print('matplotlib.font_manager內的所有字體:')
for f in sorted(mpl_fonts):
print('\t' + f)
我的輸出結果如下,如果含有中文字體這可以通過拼音拼出來,顯然,我的字體庫里面并沒有中文字體(防止占用過多的篇幅,我刪除了部分字體的展示,不會影響理解)。
matplotlib.font_manager內的所有字體:
DejaVu Sans
DejaVu Sans Display
STIXGeneral
STIXSizeThreeSym
STIXSizeTwoSym
cmb10
沒有中文字體就需要去下載中文字體,推薦字體下載網站自由字體,里面有很多字體都是可以免費下載的,本文選擇的阿里媽媽東方大楷
,下載鏈接為阿里媽媽東方大楷。當然你也可以下載你喜歡的字體用于圖片繪制。
而后運行下列代碼,得到字體存儲路徑。
import matplotlib
print(matplotlib.matplotlib_fname())
結果如下,我們需要到返回結果的上級目錄,即/home/ouyangkang/software/anaconda3/envs/ML/lib/python3.9/site-packages/matplotlib/mpl-data/
,在該目錄下找到fonts
文件夾,然后進入fonts
文件夾找到ttf
文件夾,打開ttf
文件夾,我們能看到很多以.ttf
為后綴的字體文件。將我們下載阿里媽媽東方大楷
字體中以.ttf
結尾的文件移入ttf
文件夾中。
/home/bio_dinosaur/software/anaconda3/envs/ML/lib/python3.9/site-packages/matplotlib/mpl-data/matplotlibrc
而后運行下面的代碼,會返回一個目錄的路徑,在該目錄下找到緩存的fontlist-vxxx.json
文件(xxx是數(shù)字),將其刪除,而后重啟vscode
或者你使用的編譯器,會重新生成該文件。
matplotlib.get_cachedir()
最后再一次運行輸出所有字體的代碼。
from matplotlib.font_manager import FontManager
mpl_fonts = set(f.name for f in FontManager().ttflist)
print('matplotlib.font_manager內的所有字體:')
for f in sorted(mpl_fonts):
print('\t' + f)
結果如下(防止占用過多的篇幅,我刪除了部分字體的展示,不會影響理解),可以看到第一個便是阿里媽媽東方大楷
。
matplotlib.font_manager內的所有字體:
Alimama DongFangDaKai
DejaVu Sans
DejaVu Sans Display
DejaVu Sans Mono
DejaVu Serif
DejaVu Serif Display
STIXGeneral
STIXNonUnicode
STIXSizeFiveSym
2.2 折線圖
我們的數(shù)據中包括電影的名稱以及電影的評分,可以繪制折線圖或者柱狀圖來展示各個電影的評分,但是柱狀圖不適用于數(shù)據項過多的情況,當數(shù)據項過多時,柱狀圖可能會顯得擁擠,不利于數(shù)據的清晰表達。因此,在這里我們選擇折線圖來展示各個電影的評分。
plt.plot()
繪制折線圖,輸入數(shù)據為x軸數(shù)據, y軸數(shù)據,數(shù)據格式可以是DataFrame
或者List
plt.text()
繪制文本,即下圖中各個電影的分數(shù)。輸入數(shù)據x軸數(shù)據, y軸數(shù)據, lable信息。其中x軸數(shù)據, y軸數(shù)據用來對應,可視化lable信息。
可以看到如果我們不對數(shù)據進行任何處理,輸出折線圖波動較大,不利于觀察最大值與最小值(同時能夠發(fā)現(xiàn)囧媽的“囧”字沒有展示出來,說明阿里媽媽東方大楷中不包含這個字)。
import matplotlib.pyplot as plt
movie_score = film_details_df[['Film_name', 'Rating_value']]
labels = movie_score['Rating_value'].tolist()
# 圖片大小
plt.figure(figsize=(18, 6))
# 設置中文字體
plt.rc("font", family='Alimama DongFangDaKai')
plt.rcParams['font.size'] = 12
plt.plot(movie_score['Film_name'], movie_score['Rating_value'])
# 字體傾斜
plt.xticks(rotation=45)
# 繪制對應的分數(shù)
for i in range(len(movie_score['Film_name'].tolist())):
plt.text(movie_score['Film_name'].tolist()[i], movie_score['Rating_value'].tolist()[i], labels[i], ha='center', va='bottom')
為了解決這一問題,我們對數(shù)據進行排序,根據得分對數(shù)據進行升序排序。其結果更加平滑,能夠容易地發(fā)現(xiàn)《日不落酒店》是該批數(shù)據中評分最低的電影,《夏洛特煩惱》是該批數(shù)據中評分最高的電影。在這一步中,我們僅僅是使用sort_values()
就完成對數(shù)據框完成排序,不得不再次感嘆pandas的強大。
import matplotlib.pyplot as plt
movie_score = film_details_df[['Film_name', 'Rating_value']].sort_values(by='Rating_value')
labels = movie_score['Rating_value'].tolist()
plt.figure(figsize=(18, 6))
# 設置中文字體
plt.rc("font", family='Alimama DongFangDaKai')
plt.rcParams['font.size'] = 12
plt.plot(movie_score['Film_name'], movie_score['Rating_value'])
plt.xticks(rotation=45)
for i in range(len(movie_score['Film_name'].tolist())):
plt.text(movie_score['Film_name'].tolist()[i], movie_score['Rating_value'].tolist()[i], labels[i], ha='center', va='bottom')
2.3 柱狀圖繪制
數(shù)據當中包含年份信息,可以統(tǒng)計每年參演電影的數(shù)量以及電影的平均分,從而分析演員參演的電影的一般在什么水平。利用pandas
的groupby()
函數(shù)將相同年份的數(shù)據合并到同一個類別中,而后對同類別中的電影評分計算平均分,電影數(shù)量。
plt.bar()
繪制柱狀圖,輸入數(shù)據為x軸數(shù)據,這里是年份;y軸數(shù)據,這里是統(tǒng)計的電影數(shù)量。plt.plot()
繪制折線圖,同2.2。plt.legend()
繪制圖例,以plt.bar(), plt.plot()
中的label
為信息。plt.title()
繪制標題。
通過解讀圖片可知,2020年該演員參演電影數(shù)量最多,達到了5部。同時該演員的參演電影的平均評分為5.48。在2014、2015年,這兩年的電影平均分超過了7分。總體而言,該演員的參演的電影平均評分呈現(xiàn)下降的趨勢,數(shù)量上呈現(xiàn)上升的趨勢。
import matplotlib.pyplot as plt
year_analysis = film_details_df.groupby('Year').agg({'Rating_value':'mean', 'Film_name':'count'})
plt.bar(year_analysis.index, year_analysis['Film_name'], label='Film count', color='greenyellow')
plt.plot(year_analysis.index, year_analysis['Rating_value'], label='Averge score', color='orange')
# add score
for i in range(len(year_analysis.Rating_value)):
plt.text(year_analysis.index.tolist()[i], year_analysis['Rating_value'].tolist()[i], round(year_analysis['Rating_value'].tolist()[i], 2), ha='center', va='bottom')
# add legend
plt.legend()
# add title
plt.title('Averge Score And Count of Films Each Year')
2.4 箱線圖繪制
對電影的評分對電影劃分等級,按照五星檔 8.5-10分、四星檔 7-8.5分、三星檔 6-7分、二星檔 4.5-6分、一星檔 2-4.5分的標準分級。這部分代碼大部分是數(shù)據處理的代碼,如果有問題可以留言或私信~
箱線圖是一種用于顯示數(shù)據分布情況的統(tǒng)計圖表,它通過展示數(shù)據的中位數(shù)、四分位數(shù)、最大值和最小值等統(tǒng)計信息,幫助我們了解數(shù)據的集中趨勢、離散程度以及是否存在異常值。
plt.boxplot()
繪制箱線圖,輸入數(shù)據是分級數(shù)據,這里的數(shù)據格式是嵌套的列表,類似于[[level_1_1, level_1_2], [...]], [...]
。plt.plot()
繪制點圖,同2.2,這里選擇ro
,故不會連接且為紅色的圓,alpha
是透明度的設置。
從圖中可知,該演員沒有五星檔的電影,哪怕是人盡皆知的《夏洛特煩惱》也只有四星檔。同時在一星檔數(shù)據、二星檔數(shù)據中數(shù)據較為離散;三星檔數(shù)據、四星檔數(shù)據中數(shù)據較為集中。箱線圖上的透明圓點在三星檔最為富集,因此該演員參演的電影評分大部分位于三星檔。
def level_assignment(score):
if score >= 8.5:
return 'Five'
elif score >= 7:
return 'Four'
elif score >= 6:
return 'Three'
elif score >= 4.5:
return 'Two'
else:
return 'One'
film_details_df['Level'] = list(map(level_assignment, film_details_df['Rating_value'].tolist()))
# draw box figure
level_analysis = [film_details_df[film_details_df['Level'] == level]['Rating_value'].tolist() for level in ["One", "Two", "Three", "Four", "Five"]]
labels = ["One Star", "Two Star", "Three Star", "Four Star", "Five Star"]
colors = ['pink', 'lightblue', 'lightgreen', 'turquoise', 'mediumslateblue']
bplot = plt.boxplot(level_analysis, labels=labels, patch_artist=True, vert=True)
# fill color
for patch, color in zip(bplot['boxes'], colors):
patch.set_facecolor(color)
# add dots to box
for num, level in enumerate(["One", "Two", "Three", "Four", "Five"]):
plt.plot([num + 1]*len(film_details_df[film_details_df['Level'] == level]['Rating_value'].tolist()), film_details_df[film_details_df['Level'] == level]['Rating_value'].tolist(), 'ro', alpha=0.2)
2.5 餅圖
通過電影所屬類別可以判斷出該演員屬于什么類型的演員,例如動作演員、喜劇演員等等。這里采用餅圖來可視化。餅圖是一種用于展示分類數(shù)據占比關系的圖表,它通過將數(shù)據分成幾個扇形區(qū)域,每個扇形區(qū)域的大小表示對應類別在總體中的占比。
plt.subplots()
函數(shù)來創(chuàng)建一個具有特定大小和等寬等高比的子圖,參數(shù)figsize
設置圖片大小,參數(shù)subplot_kw
是傳遞給子圖的關鍵字參數(shù)。pli.pie()
繪制餅圖,輸入數(shù)據需要是一維數(shù)據。ax.legend()
為子圖添加圖例,輸入數(shù)據同樣為一維數(shù)據。
通過對餅圖的可視化可知,該演員參演的大部分電影類型為喜劇,其次分別是劇情和愛情?;讷@取的數(shù)據可以將該演員定義為喜劇演員。
import re
genre_dic = {}
total_num = 0
for i in film_details_df.Genre:
genre = re.sub('\'', '', i)
genre = [k.strip() for k in genre.split(',')]
for g in genre:
genre_dic[g] = genre_dic.get(g, 0) + 1
total_num += 1
fig, ax = plt.subplots(figsize=(12,6), subplot_kw=dict(aspect='equal'))
wages, text=plt.pie((pd.DataFrame(genre_dic.items(), columns=['Genre', 'Count']).Count / total_num).tolist(),
labels=pd.DataFrame(genre_dic.items(), columns=['Genre', 'Count']).Genre,
)
ax.legend(wages, pd.DataFrame(genre_dic.items(), columns=['Genre', 'Count']).Genre, loc='center left', bbox_to_anchor=(1, 0, 0.5, 1))
同時,本文還給出了繪制升級版餅圖的代碼,簡稱為餅圖plus(大餅)??梢宰约簢L試去解讀一下代碼~,遇到不會的可以print()
看看到底是什么妖魔鬼怪。餅圖plus參考連接。
import numpy as np
fig, ax = plt.subplots(figsize=(24, 12), subplot_kw=dict(aspect="equal"))
wedges, texts = ax.pie(pd.DataFrame(genre_dic.items(), columns=['Genre', 'Count']).Count.tolist(),
wedgeprops=dict(width=0.5), startangle=-40)
bbox_props = dict(boxstyle='square, pad=0.3', fc='w', ec='k', lw=0.72)
kw = dict(arrowprops=dict(arrowstyle='-'),
bbox=bbox_props,
zorder=0,
va='center')
for i, p in enumerate(wedges):
ang = (p.theta2 - p.theta1) / 2 + p.theta1
y = np.sin(np.deg2rad(ang))
x = np.cos(np.deg2rad(ang))
horizontalaligment = {-1:'right', 1:'left'}[int(np.sign(x))]
connectionstyle = f"angle, angleA=0, angleB={ang}"
kw['arrowprops'].update({'connectionstyle':connectionstyle})
ax.annotate(pd.DataFrame(genre_dic.items(), columns=['Genre', 'Count']).Genre.tolist()[i],
xy=(x, y),
xytext=(1.35*np.sign(x), 1.4*y),
horizontalalignment=horizontalaligment,
**kw)
plt.show()
3. Na值處理及相關性分析
3.1 相關性分析
在數(shù)據獲取階段,部分數(shù)據存在缺失的情況。如何處理缺失數(shù)據是數(shù)據處理一直一來面臨的問題,最簡單同時也是最容易的操作方法是將缺失值填充為平均數(shù)、中位數(shù)之類的數(shù)據。但是這種方式并沒有考慮不同變量之間的相關性,例如一部電影評分為9.0分,這部電影的評論人數(shù)為10萬,另一部電影的評分為6.0分,評論人數(shù)為5萬,但缺失評論人數(shù)的電影評分為5.3分,其評論人數(shù)填充為平均值7.5萬,顯然是不合理的操作。
因此,可以考慮使用模型預測缺失值。這里首先將數(shù)據轉換為浮點數(shù),便于后續(xù)模型的擬合與預測。同時將數(shù)據劃分為不含缺失值部分、含缺失值部分。使用seaborn
庫中的pairplot()
函數(shù)繪制不含缺失值部分數(shù)據兩兩變量之間的相關性。在本文中缺失的數(shù)據為Interesting_count
、Watched_count
。
從繪制的圖中可以看出Interesting_count
與Rating_count
、Rating_value
之間相關性較好;而Watched_count
與Rating_count
、Rating_value
之間相關性較差。因此可以考慮使用線性模型擬合Interesting_count
,用非線性模型擬合Watched_count
。
# data pre-procession
fit_data = film_details_df[['Rating_count', 'Rating_value', 'Interesting_count', 'Watched_count']]
# transform data format from str to float
fit_data['Rating_count'] = list(map(float, fit_data['Rating_count'].tolist()))
fit_data['Interesting_count'] = list(map(float, fit_data['Interesting_count'].tolist()))
fit_data['Watched_count'] = list(map(float, fit_data['Watched_count'].tolist()))
# split data by Na
known_data = fit_data.dropna(subset=['Interesting_count', 'Watched_count'])
unknown_data = fit_data[fit_data.isna().any(axis=1)]
# visualization
import seaborn as sns
# correlation analysis
sns.pairplot(known_data, kind="reg")
如果你對于上訴相關性的分析不是很了解,可以從下圖中更好了解兩兩變量之間的相關性。如Rating_value
與Interesting_count
之間的相關性是0.68,Rating_value
與Watched_count
之間的相關性僅為0.33。與上訴相關性描述一致。
這里首先使用pandas
中的corr()
計算變量之間的相關性,而后使用seaborn
的heatmap()
繪制熱圖。同時熱圖是一種很好展示相關性的可視化方法~
sns.heatmap(known_data.corr(), annot=True, fmt='.2f', cmap=sns.cubehelix_palette(as_cmap=True), center=0)
3.2 Na值處理
如3.1所述,本文使用線性模型擬合Interesting_count
,用非線性模型擬合Watched_count
。這里采用多元線性模型以及支持向量機模型分別擬合兩個變量。所采用的包為sklearn
,一個強大機器學習包,只需要簡單的使用fit()
、predict()
就可以完成數(shù)據的擬合與預測。這里就不多做介紹,感興趣的小伙伴可以關注或訂閱我的專欄機器學習(持續(xù)更新中~)。
#################### linear model ####################
from sklearn import linear_model
# interesting count model
reg_interesting = linear_model.LinearRegression()
reg_interesting.fit(known_data[['Rating_count', 'Rating_value']], known_data['Interesting_count'])
# slope
print(reg_interesting.coef_)
# intercept
print(reg_interesting.intercept_)
# fill na
unknown_data['Interesting_count'] = list(reg_interesting.predict(unknown_data[['Rating_count', 'Rating_value']]))
#################### svm model ####################
from sklearn.svm import SVR
# from sklearn.metrics import mean_squared_error
x_train = known_data[['Rating_count', 'Rating_value', 'Interesting_count']]
y_train = known_data['Watched_count']
svr_model = SVR(kernel='linear').fit(x_train, y_train)
# fill na
unknown_data['Watched_count'] = svr_model.predict(unknown_data[['Rating_count', 'Rating_value', 'Interesting_count']])
非線性模型不可以可視化,由于數(shù)據不多,不太好反映預測數(shù)據的準確性,當然這里這是將它作為一個示例來介紹使用模型預測缺失值的方法。但是線性模型可以可視化,將真實數(shù)據畫為點,預測數(shù)據繪制為線條,可視化透明區(qū)帶作為0.95的置信區(qū)間。從圖中可知僅僅只有兩個點在0.95置信區(qū)間之外,說明線性模型擬合的非常好~
#################### linear model visualization ####################
import numpy as np
import scipy.stats as stats
coef = reg_interesting.coef_
intercept = reg_interesting.intercept_
x_test = known_data[['Rating_count', 'Rating_value']]
y_pred = np.dot(x_test, coef) + intercept
y_test = known_data['Interesting_count']
# confidence area
confidence = 0.95
alpha = 1 - confidence
residuals = y_test - y_pred
std_err = np.std(residuals, ddof=1)
margin_of_error = std_err * stats.t.ppf(1 - alpha / 2, df=len(y_pred) - 1)
confidence_lower = y_pred - margin_of_error
confidence_upper = y_pred + margin_of_error
sorted_indices = np.argsort(y_pred)
y_pred_sorted = y_pred[sorted_indices]
confidence_lower_sorted = confidence_lower[sorted_indices]
confidence_upper_sorted = confidence_upper[sorted_indices]
plt.scatter(y_pred_sorted, np.array(y_test)[sorted_indices], color='blue', label='Actual')
plt.plot([min(y_pred_sorted), max(y_pred_sorted)], [min(y_test), max(y_test)], color='red', linestyle='--', linewidth=2, label='Predicted')
plt.fill_between(y_pred_sorted, confidence_lower_sorted, confidence_upper_sorted, color='blue', alpha=0.2, label='95% Confidence Interval')
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.legend()
plt.show()
4. 圖(graph)可視化分析
圖是指以圖(或網絡)的形式來表示和組織的數(shù)據,并不是我們平常所理解的圖片。在圖數(shù)據中,數(shù)據元素被表示為節(jié)點(vertices)和邊(edges),它們之間的關系用邊來連接。 圖數(shù)據能夠自然地表示實體之間的復雜關系,如社交網絡中的朋友關系、物流網絡中的運輸路徑等。
在本文中,使用Fruchterman-Reingold
算法來展示演員-(聯(lián)系)-演員
關系(軟件:Gephi
),使用Neo4j
可視化導演-(導演)>電影-(包括)>演員
,Fruchterman-Reingold
(簡稱FR)是一種用于圖布局的算法,用于在平面上繪制一個圖的節(jié)點和邊,以便節(jié)點之間的連接關系能夠以一種視覺上易于理解的方式呈現(xiàn)出來。
下面是數(shù)據處理的部分,處理方式比較單一,相當于為數(shù)據添加了一個唯一編號,這個編號就代表的這個數(shù)據。不詳細介紹~,如有問題可以留言或私信交流。
import pandas as pd
film_details_df = pd.read_csv('/mnt/c/Users/ouyangkang/Desktop/films_info.csv', encoding='gbk')
import re
import random
# set seed to reproduce result
random.seed(1026)
#################### actor procession ####################
actor_list = []
# remove blank and single quotes
for i in film_details_df.Actors:
actors = re.sub(r'\'', '', i).split(',')
actor_list += [i.strip(' ') for i in actors]
# remove duplication
actor_list = list(set(actor_list))
# create unicode
ac_dict = {}
uni_code = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
for actor in actor_list:
ac_dict[actor] = 'AC' + str(random.randint(100, 999)) + random.choice(uni_code) + str(random.randint(10, 99))
# checking whether unicodes are unique
print(len(set(ac_dict.values())) == len(actor_list))
# save
pd.DataFrame(ac_dict.items(), columns=['Actor', 'Unicode']).to_csv('/mnt/c/Users/ouyangkang/Desktop/actor_unicode.csv', index=None, encoding='gbk')
#################### director processiong ####################
dire_list = list(set(film_details_df.Director.tolist()))
random.seed(1026)
dire_dict = {}
# create unicode
for director in dire_list:
dire_dict[director] = 'DI' + str(random.randint(100, 999)) + random.choice(uni_code) + str(random.randint(10, 99))
# checking whether unicodes are unique
print(len(set(dire_dict.values())) == len(dire_list))
# save
pd.DataFrame(dire_dict.items(), columns=['Director', 'Unicode']).to_csv('/mnt/c/Users/ouyangkang/Desktop/director_unicode.csv', index=None, encoding='gbk')
#################### film processiong ####################
film_dict = {}
for film in film_details_df.Film_name.tolist():
film_dict[film] = 'Film' + str(random.randint(100, 999)) + random.choice(uni_code) + str(random.randint(10, 99))
print(len(set(film_dict.values())) == len(film_details_df.Film_name.tolist()))
pd.DataFrame(film_dict.items(), columns=['Film', 'Unicode']).to_csv('/mnt/c/Users/ouyangkang/Desktop/film_unicode.csv', index=None, encoding='gbk')
#################### connection between film, director and actor ####################
f_d_a_dict = {}
for film in film_details_df.iterrows():
actors = re.sub(r'\'', '', film[1].Actors).split(',')
actors = [i.strip(' ') for i in actors]
f_d_a_dict[film[1].Film_name] = {film[1].Director: actors}
flat_data = []
for film, term in f_d_a_dict.items():
for director, actor_list in term.items():
for actor in actor_list:
flat_data.append([film, director, actor])
f_d_a_df = pd.DataFrame(flat_data, columns=['Film', 'Director', 'Actors'])
f_d_a_df.to_csv('/mnt/c/Users/ouyangkang/Desktop/film_dir_ac.csv', index=None, encoding='gbk')
#################### connection between actors ####################
st_connection = []
for film in film_details_df.iterrows():
actors = re.sub('\'', '', film[1]['Actors']).split(',')
actors = [i.strip(' ') for i in actors]
for i in range(len(actors)):
for k in range(i+1, len(actors)):
st_connection.append([actors[i], actors[k]])
pd.DataFrame(st_connection, columns=['Actor_1', 'Actor_2']).to_csv('/mnt/c/Users/ouyangkang/Desktop/connection.csv', encoding='gbk', index=None)
在Neo4j Desktop
中使用下述Cypher
語言構建導演-(導演)>電影-(包括)>演員
關系圖譜。因為對Cypher
語言還不夠熟練,并沒有分析出具有意義的結果,見諒~
# NEO4J COMMAND
CREATE CONSTRAINT actor_unicode FOR (a:actor) REQUIRE a.unicode IS UNIQUE
CREATE CONSTRAINT director_unicode FOR (d:director) REQUIRE d.unicode IS UNIQUE
CREATE CONSTRAINT film_unicode FOR (f:film) REQUIRE f.unicode IS UNIQUE
LOAD CSV WITH HEADERS FROM 'file:///actor_unicode.csv' AS row MERGE (a:actor {name:row.Actor, unicode:row.Unicode})
LOAD CSV WITH HEADERS FROM 'file:///director_unicode.csv' AS row MERGE (d:director {name:row.Director, unicode:row.Unicode})
LOAD CSV WITH HEADERS FROM 'file:///film_unicode.csv' AS row MERGE (f:film {name:row.Film,unicode:row.Unicode})
LOAD CSV WITH HEADERS FROM 'file:///film_dir_ac.csv' AS row MERGE (d:director {name:row.Director}) MERGE (f:film {name:row.Film}) MERGE (d)-[r:Directs]->(f)
LOAD CSV WITH HEADERS FROM 'file:///film_dir_ac.csv' AS row MERGE (f:film {name:row.Film}) MERGE (a:actor {name:row.Actors}) MERGE (f)-[r:Including]->(a)
LOAD CSV WITH HEADERS FROM 'file:///connection.csv' AS row MERGE (a:actor {name:row.Actor_1}) MERGE (b:actor {name:row.Actor_2}) MERGE (a)-[r:cooperation]-(b)
同時,使用Gephi
對演員關系使用Fruchterman-Reingold
算法可視化,發(fā)現(xiàn)參演不同電影的演員被分成了一個有一個聚類群,而共同參演多部電影的演員在圖中間形成復雜的網絡結構,而主角沈騰則位于最中心,成為最紅的點,連接每一個演員。較粗的線條表示沈騰與該演員在多部電影中合作過,例如馬麗。
總結
本文對獲取的電影數(shù)據做了相關的可視化分析,包括柱狀圖、折線圖、箱線圖、餅圖以及相關性熱圖;使用模型預測Na值,包括線性模型、支持向量機模型;以及圖可視化工具分析導演-電影-演員,演員-演員之間的復雜網絡關系。希望看完本文你能夠學會如何對數(shù)據進行合理的可視化、使用模型預測Na值以及圖可視化復雜的網絡關系。文章來源:http://www.zghlxwxcb.cn/news/detail-653456.html
最后感謝大家的觀看,點點關注不迷路~。文章來源地址http://www.zghlxwxcb.cn/news/detail-653456.html
到了這里,關于電影數(shù)據可視化綜合分析的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!