本篇目錄
前面幾篇,介紹了一些常用的資料探勘模型。
不過本篇內容比較不太一樣,比較著重在「資料預處理」(或者稱資料清洗)的手法上。
畢竟在資料分析的流程中,其實有60~70%的時間是在進行「資料預處理」。如果沒有好的資料,後續的分析其實就可能會有很大的偏誤。
在「資料預處理」時,我們時常會遇到很多問題需要解決。當然,也有有很多對應的小技巧,可以幫助我們處理這些問題。
而本篇內容,主要針對一個比較重要問題:遺漏值(Missing Value),進行處理!
在R裡面,遺漏值會被表現成NA(not available),而我們可以使用is.na()
的函式,確認資料中是否有遺漏值的存在:
tmp <- c(1,5,8,NA,5,NA,6)
is.na(tmp)
## [1] FALSE FALSE FALSE TRUE FALSE TRUE FALSE
# 計算遺漏值的個數
sum(is.na(tmp))
## [1] 2
在處理遺漏值時,大多數的人都會「直接移除資料」或是用「平均值來填補遺漏值」,但這樣的做法並不推薦:前者會讓資料減少,後者不會產生任何資訊。
因此在遺漏值處理的手法上,最推崇的就是「k-Nearest Neighbours」或「mice
套件」來填補遺漏值。其中,mice的全名為Multivariate Imputation via Chained Equations。
兩者的概念很簡單,都是先用資料探勘的方法「模擬遺漏值」後,再進行「填補(impute)」。詳情會在下面介紹。
我們先使用iris
的資料集,讓資料中隨機產生遺漏值,再來練習剛剛介紹的處理手法:
require(missForest) # prodNA() function
## Warning: package 'missForest' was built under R version 3.4.4
## Warning: package 'itertools' was built under R version 3.4.4
# 在iris資料內,隨機產生10%的遺漏值
data <- prodNA(iris, noNA = 0.1)
# 可以注意到,資料裡面有NA的存在,代表Not-Available(遺漏值)
head(data)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 <NA>
## 2 4.9 NA 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 <NA>
## 5 5.0 3.6 1.4 0.2 setosa
## 6 NA 3.9 1.7 0.4 setosa
接著介紹剛剛提及的四種處理遺漏值的手法:
1. 直接移除有遺漏值的資料
# 當一筆資料是完整的,回傳TRUE;當一筆資料有遺漏值,回傳FALSE
complete.cases(data)
## [1] FALSE FALSE TRUE FALSE TRUE FALSE TRUE TRUE FALSE TRUE FALSE
## [12] FALSE TRUE TRUE TRUE FALSE TRUE TRUE TRUE FALSE FALSE FALSE
## [23] FALSE FALSE TRUE TRUE FALSE TRUE FALSE TRUE TRUE TRUE TRUE
## [34] FALSE TRUE TRUE FALSE TRUE FALSE TRUE TRUE FALSE TRUE FALSE
## [45] TRUE TRUE FALSE FALSE TRUE TRUE TRUE TRUE FALSE FALSE TRUE
## [56] TRUE TRUE TRUE TRUE TRUE FALSE FALSE TRUE TRUE TRUE FALSE
## [67] FALSE TRUE TRUE TRUE FALSE TRUE TRUE TRUE FALSE FALSE FALSE
## [78] TRUE FALSE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE
## [89] TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE FALSE TRUE FALSE
## [100] TRUE FALSE FALSE TRUE TRUE FALSE TRUE TRUE TRUE FALSE TRUE
## [111] FALSE TRUE FALSE TRUE TRUE FALSE FALSE TRUE TRUE TRUE TRUE
## [122] TRUE FALSE TRUE TRUE TRUE TRUE FALSE FALSE TRUE FALSE TRUE
## [133] TRUE TRUE TRUE TRUE FALSE FALSE FALSE TRUE TRUE TRUE FALSE
## [144] FALSE TRUE FALSE FALSE TRUE FALSE FALSE
# 移除有遺漏值的資料
rm.data <- data[complete.cases(data), ]
可是這麼做不太好,因為會造成資訊損失(information loss)。
所以我們常會採取「填補遺漏值」的手法,也就是下面即將介紹的!
2. 用「平均數」、「第一四分位數」…來填補遺漏值
# 以下用平均數,來填補某一欄位的遺漏值
mean.data <- data
mean.1 <- mean(mean.data[, 1], na.rm = T) # 第一欄位的平均數
na.rows <- is.na(mean.data[, 1]) # 第一欄位中,有遺漏值存在的資料
# 用第一欄位的平均數,填補第一欄位的遺漏值
mean.data[na.rows, 1] <- mean.1
3. 用K-Nearest Neighbours填補遺漏值
K-Nearest Neighbours(KNN)運用在遺漏值填補上的想法很簡單:
現在有一群學生的成績,包含國文、數學、自然,但老師不小心弄丟小明的國文考卷,於是小明的「國文」分數是遺漏值。
如果在不重考的狀況下,我們要給小明一個分數,該怎麼做?
KNN的概念告訴我們,應該先看小明「數學和自然」的分數,看和哪些同學(K位)很相近,然後再拿那些同學(K位)的國文分數,取平均或加權平均(或是其他手法)後,當作小明的分數來填補。
一句話概括:「就是找和自己很像的K個鄰居,然後從他們身上複製自己所沒有的東西。」
這就是用KNN來填補遺漏值的想法。
require(DMwR)
## Warning: package 'DMwR' was built under R version 3.4.4
imputeData <- knnImputation(data)
head(imputeData)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.100000 3.500000 1.4 0.2 setosa
## 2 4.900000 3.241985 1.4 0.2 setosa
## 3 4.700000 3.200000 1.3 0.2 setosa
## 4 4.600000 3.100000 1.5 0.2 setosa
## 5 5.000000 3.600000 1.4 0.2 setosa
## 6 5.295674 3.900000 1.7 0.4 setosa
4. 用MICE填補遺漏值
在MICE裡面,提供了很多資料探勘的模型(linear regression, logistic regression, cart, random forest, boostrap……),來針對遺漏值進行預測!
概念很簡單:現在我們有欄位V1,V2,V3……Vn,每個欄位裡面都有遺漏值。
當我們要填補V1的遺漏值時,就先把V2,V3……Vn的欄位當作自變數(X),把V1當作應變數(Y),並且進行建模,然後用預測的結果來填補V1的遺漏值。
同理,針對V2,就用V1,V3……Vn建模,然後用預測的結果來填補V2的遺漏值。
(由於這個函式,背後有使用Gibbs sampling(一種抽樣手法)。所以,即使使用某個模型進行遺漏值填補,也會因為抽樣手法,造成最後填補的結果有些許不同)
require(mice)
## Warning: package 'mice' was built under R version 3.4.4
mice.data <- mice(data,
m = 3, # 產生三個被填補好的資料表
maxit = 50, # max iteration
method = "cart", # 使用CART決策樹,進行遺漏值預測
seed = 188) # set.seed(),令抽樣每次都一樣
# 原始資料(有遺漏值)
data
# 填補好的資料:因為m=3,所以會有三個填補好的資料集,可以用以下方式取出
complete(mice.data, 1) # 1st data
complete(mice.data, 2) # 2nd data
complete(mice.data, 3) # 3rd data
(由於上面資料集龐大,故在此不顯示出來!)
現在,我們可以任取其中一個「填補好的資料」,來進行後續的建模了!
# e.g. 拿第二個資料,作為我後續分析的資料
df <- complete(mice.data, 2)
head(df)
# 然後以df進行線性迴歸、類神經網路、主成份分析...等等
總結
在資料預處理時,「遺漏值處理」是很重要的步驟,最好還是選擇「填補遺漏值」的方式,才不會造成資訊損失。
在R裡面,其實有提供很多強大的套件,可以幫我們處理遺漏值!
本篇只簡單介紹mice
套件,網路上有神人整理出五種處理遺漏值的強大套件,裡面都有詳細的範例:Tutorial on 5 Powerful R Packages used for imputing missing values,有興趣的話可以參考!
It’s still a long way to go~