使用MATLAB數據分析工具鏈進行實戰: 看電影真的是男女有別
來自專欄 MATLAB
這篇文章主要是介紹live script和table相關函數的使用, 還不涉及到機器學習.
記者: live script+table給你什麼樣的感覺? 相比比較流行的python數據工具鏈呢?
菡姐: live script + table給我的感覺呢?感覺比jupyter notebook + pandas好多了!
MATLAB有workspace, jupyter notebook沒有, 就好比汽車沒有碼速表一樣!spyder也有workspace, 但是它不能顯示所有的數據類型, 而且數據量一大, 容易卡死.哎呦, 我超喜歡玩MATLAB的!
我之前寫過:
菡姐:MATLAB的數據分析工具鏈
現在就用上面提到的數據分析工具鏈進行實戰.
使用的例子是《利用Python進行數據分析》 麥金尼 (Wes McKinney), 唐學韜, 等【摘要 書評 試讀】圖書 裡面第二章的第二個例子.
(沒看過這本書的讀者不需要買這本書, 除非你想用python進行數據分析)
之所以使用這個例子, 是因為:
1 我對這個例子比較熟悉, 之前學pandas時, 好好研究過這個例子.
2 網上能夠下載到數據.
3 可以做對照, 確保我用MATLAB做出的結果與用pandas做出的結果是一致的, 防止出錯.
這個例子所需要的數據可以在這下載:
wesm/pydata-bookOK, 正式開始了.
"README"文件對數據進行了描述, 其中概述為:
"These files contain 1,000,209 anonymous ratings of approximately 3,900 movies
made by 6,040 MovieLens users who joined MovieLens in 2000."
其中, 裡面提到了三個樣本量, 可以用來判斷數據是否被正確的讀入.
數據分成了三個文件"users.dat", "ratings.dat", "movies.dat".
分別是觀眾相關的數據, 打分相關的數據, 電影相關的數據.
很顯然, "打分"連接了"觀眾"與"電影", 沒有"打分", "觀眾"與"電影"是不相干的.
認識到這一點很重要, 因為分別讀入了這三個數據, 需要將這三者合併起來.
如何合併? 這就需要對"數據集之間的聯繫"有正確的認識.
先給live script的截圖, 方便讀者直接看到運行結果
再給轉化為普通script的程序, 方便讀者在自己電腦上運行.
數據下載完後, 應該可以直接運行了, 使用R2017b以上的版本.
%% 觀眾對電影打分的數據分析% "README"文件對數據進行了描述, 其中概述為:% % "These files contain 1,000,209 anonymous ratings of approximately 3,900 % movies % % made by 6,040 MovieLens users who joined MovieLens in 2000."% % 其中, 裡面提到了三個樣本量, 可以用來判斷數據是否被正確的讀入.% % 數據分成了三個文件"users.dat", "ratings.dat", "movies.dat".% % 分別是觀眾相關的數據, 打分相關的數據, 電影相關的數據.% % 很顯然, "打分"連接了"觀眾"與"電影", 沒有"打分", "觀眾"與"電影"是不相干的.% % 認識到這一點很重要, 因為分別讀入了這三個數據, 需要將這三者合併起來.% % 如何合併? 這就需要對"數據集之間的聯繫"有正確的認識.%% 讀入觀眾數據%%unames = {user_id, gender, age, occupation, zip};users = readtable(users.dat, Delimiter, {::});users = rmmissing(users);users.Properties.VariableNames = unames;users.gender = categorical(users.gender);users.occupation = categorical(users.occupation);height(users)%% % 觀眾數量與"README"一致head(users, 5)%% 讀入打分數據%%rnames = {user_id, movie_id, rating, timestamp};ratings = readtable(ratings.dat, Delimiter, {::});ratings = rmmissing(ratings);ratings.Properties.VariableNames = rnames;height(ratings)%% % 打分數量與"README"一致head(ratings, 5)%% 讀入電影數據%%mnames = {movie_id, title, genres};movies = readtable(movies.dat, Delimiter, {::});movies = rmmissing(movies);movies.Properties.VariableNames = mnames;height(movies)%% % 電影數量與"README"一致head(movies, 5)%% key變數% 很顯然, "user_id"和"movie_id"的可以作為合併數據集的key變數.% % 這些id, 相當於身份證, 姓名, 電影名有可能出現重名, 但是身份證是獨一無二的.% % 不放心的話, 可以編程確認一下%%assert(length(unique(users.user_id)) == length(users.user_id))assert(length(unique(movies.movie_id)) == length(movies.movie_id))%% % 沒有報錯的話, 就是獨一無二, 沒有重複的.%% 合併三個數據集%%data = join(join(ratings, users), movies);height(data)%% % 與打分數據的樣本個數相同head(data, 5)%% 每部電影的平均打分(按照觀眾性別分組計算)%%mean_ratings = groupsummary(data, {title, gender}, mean, rating);% 去除那個計數列(第3列)mean_ratings = mean_ratings(:, [1, 2, 4]);mean_ratings = unstack(mean_ratings, mean_rating, gender)%% 過濾掉冷門電影% 上面生成的平均分是有缺陷的, 比如有些電影的總共打分數據過少了, 那麼平均分的參考性不足% % 因此, 我們需要將那些冷門電影(打分數據個數少於250的電影)過濾掉.%%num_rating = groupsummary(data, title)mean_ratings = mean_ratings(num_rating.GroupCount >= 250, %% % 從原先的3706部電影, 過濾到1216部電影了.%% 最受女性觀眾歡迎的10部電影有哪些?%%[~, idx] = maxk(mean_ratings.F, 10);top_female_ratings = mean_ratings(idx, %% 最受男性觀眾歡迎的10部電影有哪些?%%[~, idx] = maxk(mean_ratings.M, 10);top_male_ratings = mean_ratings(idx, %% % 很明顯, 男女觀眾的口味是有差別的.%% 那麼問題就來了: 哪些電影男女分歧最大呢?%%% 新增一列, 女性觀眾與男性觀眾平均打分的差值, 作為分歧變數% 正的, 表示更受女性歡迎, 負的, 表示更受男性歡迎.mean_ratings.diff = mean_ratings.F - mean_ratings.M;[~, idx] = maxk(mean_ratings.diff, 15);mean_ratings(idx, %% % 該表格為分歧最大的15部電影(更受女性歡迎)[~, idx] = mink(mean_ratings.diff, 15);mean_ratings(idx, %% % 該表格為分歧最大的15部電影(更受男性歡迎)
最後給個maxk使用方法的鏈接:
菡姐:MATLAB R2017b新函數介紹之mink, maxk推薦閱讀:
※Matlab 2018a 比2017b有哪些改進?
※matlab中z=(x+y).^2和v=x.^2+y.^2+2*x*y畫出的圖差距好大?
※4種執行函數方法的速度大PK
※MATLAB Graph Object(2): 建立關係網
※MATLAB腳本中的局部函數