어떤 데이터든 실무에서는 결측치에 대한 전략이 있어야 한다. 그리고 이에대한 적절한 처리 후 데이터 분석에 들어 가야 한다.
물론 다양한 결측치 채우기 전략이 있을 수 있는데, 여기서는 간단하게 중앙값, 평균, 그리고 모드(mode)를 이용하고, 적절하게 숫자형, 범주형데이터를 모두 처리한다.
해당 리스트에서 결측치가 존재할 경우 정규성 테스트를 한 이후 0.05유의 수준에 따라 정규분포를 하고 있다면 평균값을 구해 그 값으로 결측치를 채우고 아니라면 중앙값으로 채운다.
중앙값으로 채우는 이유는 샘플이 정규분포를 하지 않는다면 평균이 대표성을 띄기 어렵기 때문이다.
그리고 factor라고 불리우는 범주형 값들에는 가장 많은 빈도수를 가지는 값을 넣어주면 될 것이다.
아래는 Weka의 Soybean 데이터를 가지고 결측치를 채우는 예제이다.
#Weka에 있는 Soybean 예제를 읽어 온다. soybean <- read.arff("c:/program files/Weka-3-6/data/soybean.arff") #getCentral 함수로 숫자형 벡터일 경우 shapiro test를 거쳐 normality 테스트 후 샘플이 정규분포 #를 하고 있다면 평균값을 구하고 그렇지 않다면 중앙값을 구한다. #만일 범주형 factor 값이라면 가장 빈번한 값인 mode를 구해서 이를 대표값으로 리턴한다. getCentral <- function(vec){ if(is.numeric(vec)){ if(shapiro.test(vec)$p.value > 0.05){ median(vec, na.rm=TRUE) }else mean(vec, na.rm=TRUE) }else if(is.factor(vec)){ vectab <- table(vec) vecmode <- names(which(vectab == max(vectab))) if(length(vecmode)){ return(vecmode[1]) } }else{ warning("check vec type!") } } #soybean$`seed-tmt`변수의 결측치들을 대표값으로 채운다. soybean[is.na(soybean$`seed-tmt`), "seed-tmt"] <- getCentral(soybean$`seed-tmt`)
Created by Pretty R at inside-R.org
샘플의 개수가 5000개가 넘어가면 shapiro test는 신뢰성 있는 값을 넘겨주지 못하니 주의를 요한다.
이 방법 이외에 가장 비슷한 경향을 가지는 변수를 기반으로 결측치를 예측하는 방법도 있고, 가장 비슷한 레코드를 가져와 그 레코드의 값으로 채우는 방법도 있다.
모두 장,단점이 있으니 이것저것 사용해보고 상황에 맞는 취사 선택이 필요할 것이다.