羅德興老師的教學歷程檔案 - 107-1 資訊科技大數據分析 - 資料分析的第二步(以泡麵為例)
 

企業資訊與管理系
助理教授/日導
羅德興


歷程檔案 Portfolio

    資料分析的第二步(以泡麵為例)

    # 資料檔  datasets//ramen-ratings.csv [下載]

    # ex-dv2.r
    # 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)視覺化結果。
    全部共 0則留言
    登入帳號密碼代表遵守學術網路規範


    文章分類 Labels


    最新文章 Top10

    中華科技大學數位化學習歷程 - 意見反應