羅德興老師的教學歷程檔案 - 107-1 資訊科技大數據分析 - 資料分析的第二步(以泡麵為例) |
|
|
資料分析的第二步(以泡麵為例)# https://leemeng.tw/data-visualization-from-matplotlib-to-ggplot2.html # for R-3.5.1 # B4 # 資料下載處 https://www.kaggle.com/residentmario/ramen-ratings # R VISUALIZATION GGPLOT2 資料視覺化 # 這篇主要描述自己以往在利用 Python 做資料視覺化 (data visualization) 時常犯的思維瑕疵, # 而該思維如何在接觸 R 的 ggplot2 以後得到改善。 # 本文會試著說明資料視覺化的本質為何,以及在設計視覺化時,概念上應該包含什麼要素以及步驟。 # 最後展示如何透過 ggplot2 活用前述的概念,來實際做資料視覺化。 # 目錄 # 資料視覺化是資料與圖的直接映射? # 資料視覺化應該是 .. # ggplot2 實踐 # 結語 # References # 資料視覺化是資料與圖的直接映射? # 就一個 Python 起家的資料科學家,在做資料視覺化的時候, # 我很自然地使用 Python ecosystem 裡像是 matplotlib 以及 seaborn 等繪圖 packages。 # 針對手中的資料,我會想辦法找到一個「對應」的圖然後把資料塞進去。 # 舉例來說,當我們手上有三個變數 x, y, z 且其各自的資料型態為: # x: 定量變數 (quantitative) # y: 定量變數 # z: 定性變數(categorical) # 我們想要進行資料視覺化的時候有幾種選擇: # 想分析 x, y -> 都是定量資料 -> 散佈圖 (scatter plot) # 想分析 x, z -> 一定量一定性 -> 長條圖 (bar chart) # 在這,「資料視覺化」的定義是一種映射關係 (mapping): # 也就是如何將資料直接對應到某個「特定」圖表形式(折線圖、散佈圖 etc.)。 # 基本上這種映射關係在做簡單的分析的時候沒有什麼問題, # 但是當想要同時分析/呈現的變數超過兩個 (例: x & y & z )的時候就不容易找到適合的圖。 # 一個折衷的方法是我們把變數兩兩畫圖做比較,但這樣會侷限我們能分析的資料維度數目,錯過一些有趣的洞見。 # 資料視覺化應該是 .. 先確認觀眾及目的 # 在完成一些 ggplot2 的 tutorials 後,可以發現資料視覺化一般依用途可以分為兩種: # 探索、了解資料特性 # 說故事:將探索過後得到的洞見 (insight) 傳達給其他人 # Image Credit : 搞清楚資料視覺化的目的以及觀眾是重要的第一步 # B4-1 資料視覺化的第一步是 ( ) # B4-2 資料視覺化的用途有二:(1) ( ),(2) ( ) # 依照目的以及觀眾的不同,資料視覺化的方式會有所不同。 # 一個常見的例子是當我們第一次接觸某個資料集。 # 這時候資料視覺化的觀眾是自己,目的是在最短的時間了解資料特性。 # 則這時我們在做圖的時候的要求就可以很寬鬆,像是不加上標題,或是只要能做出自己能理解的視覺化即可。 # 正式定義 # 在確認觀眾及目的以後,我們終於可以開始進行資料視覺化了! # 資料視覺化的定義因人而異,而這邊我想給出一個非常直觀的定義: # 資料視覺化是將資料中的變數映射到視覺變數上,進而有效且有意義地呈現資料的樣貌 # 一些常見且肉眼容易識別的視覺變數 / 刻度(visual variables / scales)包含: # 位置(x / y axis) # 顏色(color) # 大小(size) # 透明程度(alpha) # 填滿(fill) # 形狀(shape) # 用更口語的方式來解釋:在做資料視覺化的時候,我們希望能將 # 肉眼難以分析的資料 # 對應到: # 肉眼容易解讀的視覺元素 # 透過這個映射關係,我們可以將原本的變數的數值變化也映射到視覺變數的變化。 # 而因為人類容易區別視覺變數的變化(位置差異、大小長度變化 etc), # 我們能更容易地理解原始資料的樣貌、變化以及模式。 # 舉例來說,我們可以: # 把不同捷運路線(文湖線、板南線)對應到不同顏色 # 把各國的 GDP 對應到點的大小 # 把某個資料的年份對應到 X 軸,越右邊代表越接近現代 # 一個簡單例子 # 事實上,我們可能平常每天都在做資料視覺化而不自知。比方說我們有一個數列 y: # y = [-2.055, -1.132, -0.522, -1.229, 0.013 .. ] # 光是看這個數字,肉眼無法看出什麼模式,但我們可以簡單畫個圖: # 這邊我們利用視覺變數「Y軸位置」來呈現數值的變化, # 可以馬上看出數列裡頭的值都落在 -3 到 3 之間,而這是因為我們肉眼很容易辨別「位置」這個視覺變數的變化。 # 圖像的分層文法 # 在 A Layered Grammar of Graphics 裡頭,Hadley Wickham 闡述所謂的圖像(包含由資料視覺化產生的圖像) # 實際上如同我們平常使用的語言,是有文法的。而其文法可以拆成 7 個部分(層)。 # 前述的 # 原始資料 = 資料層(Data) # 視覺變數層(Visual variables = Aesthetics) # 則恰好是這個架構裡頭最底下的兩層。 # 視覺變數是作者為了方便理解建立的名詞,在原文以及 ggplot2 裡頭被稱作 Aesthetics。 # (中文翻作「美學」,當初看好久也無法理解啊 (╯°Д°)╯ ┻━┻) # Image Credit : 圖像的分層文法 # 看到這你一定會「哇靠那我每次畫個圖都要實作七層?」。 # 實際上不需要, # 上面幾層像是主題(Theme)比較像是裝飾品,給我們更大的自由與彈性來訂製(customize)視覺化結果。 # 在下一節我們會看到,ggplot2 會自動幫我們設定合適的主題或座標。(如果沒特別指定的話) # 但一般而言,一個圖像最基本的組成是底下三層。也就是除了前述的兩層(資料、視覺變數)以外還需要加上 # 幾何圖形層(Geometries) # 為何還要這層?假如我們有了資料,決定了視覺變數 # (第二層,例:把資料中的變數 A 對應到 X 軸;變數 B 對應到 Y 軸)後, # 實際上就可以畫一個充滿點(point)的散佈圖了不是嗎? # 這樣的思維如同資料視覺化是資料與圖的直接映射?部分所提到的,有所瑕疵。 # 如果變數 A 是分類型變數(Categorical)的話,單純以點為圖形的散佈圖就會變得十分難以理解(下圖左); # 這時候以長條為圖形(下圖右)的方式會比較清楚: # 獨立幾何圖形層 : # 讓資料視覺化不再侷限於「我要畫什麼圖」,而是「我想要怎麼畫」 # 將「幾何圖形」這個選擇獨立出來一層讓我們在資料視覺化的時候有更大的彈性。 # 有了這些基本概念以後,我們可以開始嘗試使用 ggplot2 來實際做一些資料視覺化。 # ggplot2 實踐 # 在這個章節裡頭我們將使用 Kaggle 的 Ramen Ratings 來做資料視覺化。 # 這資料集紀錄了各國泡麵所得到的星星數。 # 首先我們要先載入這次的主角:R 語言裡頭最著名的視覺化 package ggplot2。 # dplyr 則是 R 語言用來處理資料的 package。 setwd("d:/temp0922") getwd() # 載入 packages library(ggplot2) library(dplyr) # 值得一提的是它們都是同屬於 TidyVerse 的一員。 # TidyVerse 是 R 裡頭常被用來做資料科學的 packages 的集合, # 以 Python 來說大概就像是 Pandas + Matplotlib + Numpy 的感覺吧。 # 載入資料 + 簡單資料處理 # 如下註解所示,這邊將資料集讀入, # 做一些簡單的資料型態轉變後選擇一部分的資料集(subset)來做之後的視覺化: # 資料下載處 https://www.kaggle.com/residentmario/ramen-ratings # 將 CSV 檔案載入成資料框架(dataframe) ramen_all <- read.csv("datasets//ramen-ratings.csv") summary(ramen_all) # 將「星星數」轉成定量資料 ramen_all$Stars <- as.numeric(ramen_all$Stars) summary(ramen_all) # B4-3: 將「星星數」轉成定量資料的指令為: as.( ) # Subset 資料,選擇 Ramen(拉麵)數量前幾多的國家方便 demo install.packages('tidyverse') library(tidyverse) ramen <- ramen_all %>% filter(Country %in% count(ramen_all, Country, sort = TRUE)[1:6, 1, drop=TRUE]) %>% filter(Style %in% count(ramen_all, Style, sort = TRUE)[1:4, 1 , drop=TRUE]) # 除了我們使用 dplyr 的 filter 依照條件 subset 資料集以外, # 值得一提的是 pipe 運算子 %>%。它是前面提到的 TidyVerse 裡頭的 packages 共享的介面(interface), # 將前一個函示的輸出當作下一個函式的輸入,讓我們可以把運算全部串(chain)在一起。 # 在 Linux 裡頭就是如同 | 的存在。 # 而實際我們的資料長這樣: head(ramen) # 簡單資料視覺化 # 有了資料,讓我們再確定一下資料視覺化的目的及觀眾: # 目的:探索資料 # 觀眾:我們自己 # 這樣的條件讓我們知道視覺化的條件是快速做出結果,不需調整如標題、主題的設定。 # 現在讓我們問一些簡單的問題。像是 # 泡麵的包裝(碗裝、袋裝等)各佔多少比例? # 不同國家各有多少泡麵在資料集裡頭? # 不同包裝的泡麵所得到的星星總數,在不同國家有什麼差異嗎? # 其中一種能解決第一個問題的資料視覺化是: ggplot(ramen, aes(x = Style)) + geom_bar() # 在 ggplot(ramen, aes(x = Style)) + geom_bar() # 裡頭,我們實際上已經建構了圖表最基礎的三層元素: # (1) 資料層: ramen 告訴 ggplot2 使用此資料框架 # (2) 視覺變數層: aes(x = Style) 告訴 ggplot2 我們將使用「 X 軸位置」這個視覺變數來反映泡麵包裝 Style 這個變數的變化 # 因為包裝的值有四種可能,你可以想像 ggplot2 已經準備好要幫你在 X 軸上的四個位置畫圖 # aes 是我們前面提到 aesthetics 的縮寫 # (3) 幾何圖形層: geom_bar() 告訴 ggplot 去計算對應到 x 視覺變數的變數裡頭,所有值的出現次數後將結果以長條來呈現 # 我們通常透過 + 來疊加不同層的結果。 # 基本層數缺一不可 # 上面的例子很簡單,但假如我們沒有指定幾何圖形層的話,圖會長什麼樣子呢? ggplot(ramen, aes(x = Style)) # 就像我們剛剛所說的,雖然 ggplot2 已經知道要用什麼資料框架、要用什麼視覺變數, # 不知道要用什麼圖形表示的話就會是空白一張圖。 # 另個簡單例子 # 讓我們依樣畫葫蘆,來解決第二個問題: # 不同國家各有多少泡麵在資料集裡頭? ggplot(ramen, aes(x = Country, fill = Style)) + geom_bar() + coord_flip() # 這邊有兩個值得注意的地方: # 除了基本的三層以外,我們透過 + coord_flip() 額外對座標層(Coordinates)做操作, # 請 ggplot2 把 x, y 軸互換。 # 透過 aes(..., fill = Style) 裡頭的 fill = Style , # 我們告訴 ggplot2 將長條圖裡頭的填滿空間(fill)這個視覺變數,依照泡麵包裝(Style)做變化 # 第二點是在做資料視覺化的時候,想辦法增加資料墨水量(Data Ink Ratio)的例子。 # 透過增加顯示在同張圖上的變數數目,進而提高該圖能傳達的訊息量。 # 舉例而言,我們可以很明顯地看到, # 在這資料集裡頭,台灣的杯裝泡麵(Cup)沒有被記錄到多少; # 而日本被記錄到的泡麵量最多,且袋裝(Pack)數目最多。 # 這些是在我們沒有用「填滿」這個視覺變數時無法察覺的。而在 ggplot2 裡,要實現這種視覺化非常容易。 # 複雜例子 # 讓我們解決最後一個問題: # 不同包裝的泡麵所得到的星星總數,在不同國家有什麼差異嗎? # 資料視覺化一個有趣的地方就是:同個問題不同的人會有不同的做法。而針對這問題其中一種做法是: # 將包裝 Style 對應到 X 軸、星星數 Stars 對應到 Y 軸,然後使用長條 geom_bar 顯示數值 # 依照每個國家重複步驟一 # 而 ggplot2 的實作為: ggplot(ramen, aes(x = Style, y = Stars)) + geom_bar(stat = "identity") + facet_wrap( ~ Country) # 實際上在上面的程式碼裡頭,我們多操作了額外兩層: # 統計層(Statistics):專門負責匯總資料 # 小平面層(Facets):依照選定的變數分別畫圖,如上述的步驟二 # 首先 ggplot2 的 geom_bar 預設只需要 x 視覺變數,因 # 為匯總資料的統計層會把 x 依照不同的值分別計數(也就是各個包裝的數量), # 然後讓 geom_bar 顯示。但我們並不希望 geom_bar 使用這個數值, # 因此使用 geom_bar 裡頭的 stat = "identity" 是告訴統計層不要分別計數,而是使用我們給定的星星數 y 。 # 而 facet_wrap( ~ Country) 則是告訴小平面層依照 Country 這個變數重複畫 ggplot(ramen, aes(x = Style, y = Stars)) + geom_bar(stat = "identity") # 注意所有的圖的 x, y 軸都是一致的,方便我們做比較。 # 結語 # 資料視覺化需要統計知識以及設計美感,涵蓋範圍非常廣大。 # 資料視覺化感覺都可以打個系列文了。但最後再次重申資料視覺化的定義: # 資料視覺化是將資料中的變數映射到視覺變數上,進而有效且有意義地呈現資料的樣貌 # 總之先確認你的觀眾與目的,選好你想要觀察的變數,選擇適當的視覺變數做可視化吧! # References # DataCamp - Data Visualization with ggplot2 (Part 1) # r-statistics.co - ggplot2 tutorial # Safari - Data Visualization in R With ggplot2 # Post Tags R visualization ggplot2 資料視覺化 # B4-4 圖像的分層文法將圖像元素拆成 7 個部分(層): # 以泡麵的包裝(碗裝、袋裝等)各佔多少比例? ggplot(ramen, aes(x = Style)) + geom_bar() 程式碼為例 # (1) ( )層:原始資料(Data),ramen 告訴 ggplot2 使用此資料框架 # (2) ( )層:(Visual variables = Aesthetics) # aes(x = Style) 告訴 ggplot2 我們將使用「 X 軸位置」這個視覺變數來反映泡麵包裝 Style 這個變數的變化 # (3) ( )層:Geometries, geom_bar() 告訴 ggplot 去計算對應到 x 視覺變數的變數裡頭, # 所有值的出現次數後將結果以長條來呈現 # 再以不同包裝的泡麵所得到的星星總數,在不同國家有什麼差異嗎?程式碼如下: # ggplot(ramen, aes(x = Style, y = Stars)) + geom_bar(stat = "identity") + # facet_wrap( ~ Country) # # (4) ( )層:Facets, 依照選定的變數分別畫圖,如 facet_wrap( ~ Country) 是告訴本層 # 依照 Country 這個變數重複畫 # (5) ( )層:Statistics, 專門負責匯總資料,如使用 geom_bar 裡頭的 stat = "identity" # 是告訴統計層不要分別計數,而是使用我們給定的星星數 y 。 # # 最後以不同國家各有多少泡麵在資料集裡頭? # ggplot(ramen, aes(x = Country, fill = Style)) + geom_bar() + # coord_flip() # (6) ( )層:Coordinates, 透過 + coord_flip() 額外對座標層(Coordinates)做操作, # 請 ggplot2 把 x, y 軸互換。 # (7) ( )層:Theme,主題(Theme)比較像是裝飾品,給我們更大的自由與彈性來訂製(customize)視覺化結果。
|
|
中華科技大學數位化學習歷程 - 意見反應 |