R語言自學系列(4) - 資料清洗與探索性資料分析

Edward Tung
R 語言自學系列
10 min readJul 13, 2018

前言

資料清洗大概是每個資料分析員最痛苦的一件事,整個分析專案的時間大概一半以上都消耗在資料清洗的環節,當然現在的統計軟體對於這一塊的處理越來越強大,然而關於數據的花樣百出真的是開發員想也想不到的,光格式不對(比方說 “Inventory” 跟 “Inventory ” 不是一個東西)或是邏輯錯誤(比方說填入年收入時填了1000000(萬)而其他人都是100)就足夠令人崩潰,因此,我們不得不介紹在R語言中怎麼實現資料清洗以及其大致的流程。此外,我們也將談到一些簡單的探索性資料分析方法,幫助我們取得更加完善與可靠的資料集,有時也能給分析師一些意想不到的觀點。

在我們開始以前,必須先對資料做出整體的評估,也就是去判斷這筆資料到底是好是壞,哪些地方需要被清洗,哪些地方應該轉換一種方式對待?方法有很多種,不勝枚舉,初始一點的如清洗掉遺漏值,進階一點可能針對共線性資料做降維處理等等,本文將探討的範圍如下圖所示,而探索性資料分析與分模型資料愈處理(比方說特徵化、傅立葉轉換)等因為方法太多,會在之後的文章根據分析方法慢慢介紹。

資料清洗流程範例

資料清洗之一:處理遺漏值

遺漏值舉凡NA(Not Available)、0、"-" 這些值十分常發生在資料中,有些可能是因為沒有該項資料,但有些可能是在記錄或儲存時發生的偏差,一般而言,我們有很多種方式來處理該資料:

  1. 刪除列/欄:簡單來說出現遺漏的該筆資料就被忽略,通常這種情況必須小心處理,舉例來說,如果我們的資料來自於使用者填寫問卷,遺漏值的出現很可能讓那筆資料整個毀掉,然而若我們的資料來源於連續型的金融數字,直接刪除該筆資料可能使資料失去連續性(尤其通常NA值出現都不會一次只出現一個)。
  2. 填補值:填補值的方式有很多種,包括填補平均(當然你可以自由推廣成幾何平均或任何其他合理的方式)、填補最上/下的值(這對於許多原始資料而言非常重要),或透過mice來進行多重插補,比方說以前後五個值作為平均數來填補。當然其他還有,但下圖我們統一先展示這幾個。
處理NA值各種方法,以AAOI dataframe為例

R語言中的一些計算基本上支援一個na.rm=TRUE的參數,這個參數的用意在於計算時自動忽略NA值。而要另外說明的是,在Python之中可以使用.dropna()和.fillna()等方法來處理這些值,此外,也支援如ffill之類的方式來做到上下填補。

資料清洗之二:統一資料格式

資料格式的錯誤有很多種,舉例來說,有時候我們下載的金融資料會帶有貨幣符號比方說 $175.00,又或是日期的格式不一致,比方像是 2015–07–12跟 2015/07/12,又或者像是我們希望統一處理掉資料串裡面奇怪的符號,這個時候我們可以使用gsub(python有replace())來處理,可以快速替代掉字串中不需要的字元,也可以用來刪除,只要把取代對象設定成 "" 就好了。此外,R語言支援正規表達式(Regular Expression)的功能,這對於處理資料來說實在是不可多得的神器,建議大家多加練習:

gsub搭配正規表達式

如上,當學會了regex之後可以做更進階的處理,不僅能應用在資料萃取,現在流行的文字探勘(text mining)也能夠應用,當然網路爬蟲也可以用來處理HTML抓下來的可怕資料格式,以下一併附上regex表供參考:

資料來源: endmemo.com © 2016

資料清洗之三:邏輯處理

這一部分的做法就非常多元了,主要是在處理資料集裡頭某些資料的範疇(Scale)與合理性問題,前者的意思比方說單位錯誤,如有人沒看到資料以萬為單位而將自己的月薪資料填了22000;後者則是單純的資料邏輯錯誤,比方說月薪有人填了264000,一看就知道不合裡,這時候你就要決斷,比方說是要直接刪除,還是把這筆資料除以12(如果你認為使用者誤以為要填的是年收入),方法眾多,但以下還是介紹一些常用的方法:

盒形圖(Box Plot)可以幫助我們檢測過度離譜的資料,雖然在建模之前很有可能要重新看一次(因應統計模型需要),但如果能夠事先避免就先做做看吧!一般而言在統計習慣上,如果一筆資料是常態分配(這也是大多數取得自然二手資料,比方說抽樣調查1000人月收入分布時的分布狀況),我們會摘除超過三個四分位距(IQR)外的資料,也就是畫出箱型圖時候在線外的資料:

箱型圖示意(Box Plot)

上圖可以看到很明顯出現一個邊緣人,這通常是我們要清除的對象。但是要注意,必須先仔細思考過是不是可以這樣清除,假如你的資料過度連續比方說金融股價資料,可能就不適合剔除這些值,假設你很剛好切片到2014年中左右的南亞科股價,你的資料大概會長得像這樣:

Source:Yahoo Finance

莫慌,請三思而後行即可。

探索性資料分析(Exploratory Data Analysis,EDA)

EDA絕對是每個資料分析師必定會做的環節,可以應用的面向太廣一時也難以條條列舉,但大致上常出現的有以下幾個目的:

單純觀察 — 別小看這個步驟,這通常會決定了你接下來的分析方式,舉例來說是不是把資料分成兩群或是多群來看,又或者是針對某一時期做特別性分析,比方說以下這種資料:

鳶尾花花瓣長度與寬度資料

通常而言,我們看到這樣子的資料分布我們就會自動地認為資料應該是很明顯的兩個種類(當然需要一些數學驗證,但通常這麼懸殊的分布直覺上估計都可以肯定了)。一般來說觀察資料最簡便的方式就是視覺化,雖然之後會提到更多的方式,在這個網頁裡面介紹了很多最基本的畫圖方法,從基本的折線圖、長條圖到複雜的熱點圖都有,雖然作圖功能並不多而且不如ggplot等套件那樣好看,但用來做EDA綽綽有餘,複雜的圖表繪製就之後介紹:

作圖方法:https://www.statmethods.net/graphs/creating.html

資料分配 — 實際上這是一個非常需要數學功底的環節,如果有需要大量處理資料的朋友建議先把機率論看熟,尤其是聯合分布、隨機變數與各種分配的pdf/pmf、cdf/cmf 推廣等等。但如果不是需要大量且底層的資料處理,還是有一些簡單的方法來觀察資料分配,最簡單的方法就是透過長條圖與折線圖兩者,前者是對於離散資料(如月平均價格)而後者則是針對連續型資料而言(如股票日內交易價格走勢)。作圖方式可以由上述連結觀察,這邊稍微介紹幾種兩種最常看到的分布圖形:

Nomal Distribution,Source:Wikipedia
Lognormal Distribution,Source:Wikipedia

對數常態分配基本上很常見於金融資料,我們今後的時間序列分析也會經常見到他,而常態分配就不用說了,不知道多少資料分析人員武斷地把自己的資料當作常態分布來處理,但良心建議,還是看一下分布圖形吧!哪怕你不打算用數學公式來確認這件事。至於其他的卡方分布與Beta分布等比較奇妙的分布圖形,或是你想知道多變量的分布(比方說X1,X2,X3...是不是符合常態聯合分配),就建議還是乖乖回去看機率論囉!

不過在這邊我們對於常態分布可以著墨的多一點,介紹兩種方式分別去更有依據地檢驗我們的資料是不是符合常態分布,包含單變量的Q-Q Plot,以及雙變量的聯合分布情形(我們用等高圖來觀察):

Q-Q Plot為常態機率圖,全稱是Quantile - Quantile Plot,提供另一種方式處理單變量的資料,核心思想是當我們將樣本照X分位數(一般常用10)來切割的時候,是不是跟常態(Z分配圖形或T分配)的理論分位數的散布圖能形成一條直線(也就是幾乎完全相關,這邊可以想像成相關係數近似於1),我們可以觀察到的是,如果資料呈現某側傾斜(也就是skewness),資料點就會往斜線的某側偏凹,以下是數學式子跟R語言實作:

AAOI股價的QQ圖與密度圖,可以很明顯看出右偏分布

等高線圖則是用來測試雙變數的方法之一,基本上近似常態分布的資料在繪圖上應該是一個橢圓(或是圓,但太少見),這邊我們載入ggplot2來做等高線圖,圖的X軸與Y軸分別是股票的最高價與最低價,代碼如下,其中geom_contour()是指定圖表類型:

可以看出明顯的高峰值出現在右上角,如果把那些值刪除則資料近似常態,但很顯然沒辦法刪除,因此這兩個變數不符合聯合常態分配(這很正常畢竟兩者並非獨立同分配),一般情況下蒐集到的資料也很難符合聯合常態分配。而至於其他的分配,我們未來進行資料處理時如果遇到再同步說明。

敘述統計—EDA的最後一個重點就是敘述統計,而作為強大的統計軟體,R語言自然支援敘述統計的方法,很簡單,只需要一行代碼就可以:

非常輕鬆地可以得到敘述統計的資料,但我們可以看到,資料量有點少,峰度、偏態等資料幾乎都沒有,這時候我們可以使用psych套件包:

這樣一來,我們要的敘述統計資料幾乎都包含在其中了!

總結

這一篇好長,但下一篇好像也會這麼長...總之,下一篇我們將正式進入討論時間序列,並且去分別檢測資料的一些相關性質,如果你喜歡我的文章,也請不吝幫忙下面按個Clap喔!

備註:AAOI(Applied Optoelectronic Inc. 應用光電公司) — 垂直光纖網路商品供應商,在美國休士頓有半導體生產工廠。

--

--

Edward Tung
R 語言自學系列

Columbia Student || 2 yrs of data scientist and 1 yr of business consultant experience