R을 이용한 데이터 이상치 검출법 정리
/*
* http://sosal.kr/
* made by so_Sal
*/
- 이상치
통계에서는 데이터 샘플에서 관찰된 한 값이 다른 관측값과 거리가 있을 때 이상치(outlier)라고 한다. 측정에 있어서 데이터들의 가변성, 변동성(variability) 때문일 수 있고 실제로 잘못된 실험에 의한 에러일 수 있다. 후자의 경우에는 분명히 데이터 분석 이전에 outlier를 제거를 해야한다.
이 포스팅에서는 이상치를 검출하는 알고리즘들을 R프로그래밍의 패키지를 이용하여 알아보고자 한다.
0. Data sampling
다양한 이상치 검출 테스트를 하기 전에, 이상치가 포함된 데이터를 만들고자 한다.
1) 데이터 생성
normal distribution에 속하는 데이터를 100개 생성하고, 매우 작은 데이터와 매우 큰 데이터를 추가한다.
> data <- rnorm(100, mean=100, sd=10) # 정규분포 평균100, 표준편차10을 가지는 데이터 100개 생성
> data[101] = 50
> data[102] = 150
2) 분포 visualization
> hist(data, breaks=20, probability=TRUE, col=21)
> lines(density(data), col=2, lwd=2)
랜덤샘플링으로 생성하는 데이터이기 때문에, 매번 실행마다 데이터들의 값은 달라진다.
따라서 이 포스팅에서 사용하는 데이터와 다를 수 있다.
위의 histogram 만으로도 outlier가 대충 어떤것이 될 것인지는 쉽게 관찰할 수 있지만, 이것은 강제로 outlier를 생성했기 때문에 관찰하기 쉬운것이며 실제 데이터에서는 그렇지 않다. 그러므로 아래의 다양한 이상치 검출 방법들을 설명하고자 한다.
1. IQR Rule for Outliers [Interquartile Range]
IQR Rule을 이용한 Outlier detection은 이전에 정리했던 포스팅이 있다. http://sosal.kr/840
흔히 boxplot을 그렸을 때, 점으로 나오는 샘플들이 바로 IQR Rule에서 말하는 outlier 들이다.
데이터들이 정규분포를 그린다고 가정하였을 때 사용할 수 있다.
1) Quantile value 구하기
- summary 함수로 quantile 정보를 볼 수 있다.
> summary(data)
Min. 1st Qu. Median Mean 3rd Qu. Max.
50.00 94.12 100.30 100.60 107.90 150.00
- quantile 함수로도 볼 수 있다.
> quantile(data)
0% 25% 50% 75% 100%
50.00000 94.12115 100.25768 107.91892 150.00000
- fivenum 함수로도 볼 수 있다.
> fivenum(data)
[1] 50.00000 94.01472 100.25768 107.99167 150.00000
2) IQR (Interquartile range) 값 구하기
Quantile에서 25%에 대한 데이터와 75%에 대한 데이터에 대한 명칭이 있다.
Upper quantile: 75% quantile
Lower quantile: 25% quantile
IQR은 바로 Upper quantile - Lower quantile 값을 뜻한다.
> UpperQ = fivenum(data)[4]
> LowerQ = fivenum(data)[2]
> IQR = UpperQ - LowerQ
> IQR
[1] 12.96757 (물론 샘플링시마다 달라짐)
IQR Rule에서 이상치(Outlier)는 다음과 같이 정의된다.
Outlier > UpperQ + IQR*1.5
Outlier < LowerQ - IQR*1.5
3) R에서 IQR Rule을 이용한 이상치 검출방법
> upperOutlier = data[ which( data > UpperQ+IQR*1.5) ]
> lowerOutlier =data[ which( data < LowerQ-IQR*1.5) ]
> upperOutlier
# [1] 150
> lowerOutlier
# [1] 50
2. Grubb's Test
이 방법은 측정된 데이터의 분산에 따라서 결정되는 방법이다. 따라서 'Maximum normed residual test' 이라고 불리며, extreme studentized deviate test라고도 불린다. Grubbs' test 역시 데이터들이 정규분포를 그릴 때 사용된다.
1) Grubb's test의 가설
Grubbs' test hypothesis
H0: There are no outliers in the data set
Ha: There is at least one outlier in the data set
2) Grubb's test의 원리
Normal population에서 N개의 데이터를 가져온다면 우리는 평균과 각 샘플들의 값을 비교하여 편차를 구할 수 있다. 편차의 절대값에서 표준편차를 나눈 값을 T라고 정의하며, Grubbs에 의해 정의된 표에 의한 검정 수준에 따라서 outlier를 결정할 수 있다. T를 수식으로 나타내면 다음과 같다.
위 식을 절대값으로 두지 않고, 편차의 최대값과 최소값으로 따로 본다면 가설검정시 two-sided test로, 그렇지 않다면 one-sided test를 사용하면 된다.
위의 식은 two-sided test로, tα/(2N),N−2는 N-2 자유도에서 t분포의 upper critical value이며, 유의수준이 α/(2N). 일 때를 나타낸다. α/ (2N)를 α/N로 대체하면 one sided-test가 된다.
Table은 다음의 url에서 확인할 수 있다.
http://www.sediment.uni-goettingen.de/staff/dunkl/software/pep-grubbs.pdf
http://www.graphpad.com/quickcalcs/Grubbs1.cfm
3) R에서 Grubb's Test를 이용한 이상치 검출방법
install.packages("outliers")
library(outliers)
grubbs.flag <- function(x) {
outliers <- NULL
test <- x
grubbs.result <- grubbs.test(test)
pv <- grubbs.result$p.value
while(pv < 0.05) {
outliers <- c(outliers,as.numeric(strsplit(grubbs.result$alternative," ")[[1]][3]))
test <- x[!x %in% outliers]
grubbs.result <- grubbs.test(test)
pv <- grubbs.result$p.value
}
return(data.frame(X=x,Outlier=(x %in% outliers)))
}
grubbs.flag(data)
#결과
X Outlier
1 99.60395 FALSE
2 87.47919 FALSE
3 92.54784 FALSE
4 103.91780 FALSE
5 114.14166 FALSE
6 95.34952 FALSE
# <중략>
96 111.77436 FALSE
97 102.77389 FALSE
98 106.07939 FALSE
99 116.38479 FALSE
100 101.26973 FALSE
101 50.00000 TRUE
102 150.00000 TRUE
3. Robust Tests
1) MAD: Median absolute deviation
MAD는 중간값과 Xi 값의 편차를 뜻한다. Order statistics를 기반으로 한 다양한 통계기법이 있는데, 그중에 MAD를 이용하는 것들이 가장 대표적인 Order statistics다. 정규분포에서는 MAD는 표준편차와 관계가 있고, Interquartile distance와도 관계가 있다.
[Wilcox, Rand R. Statistics for the social sciences. Academic Press, 1996.]
2) Robust Test의 원리
MAD ≒ 0.6748σ, 즉 σ≒1.4826MAD이며, Interquartile distance ≒ 2MAD 라고 한다.
따라서 다음과 같이 Outlier의 Threshold를 지정할 수 있다.
- Lower outlier
- Upper outlier
3) R에서 Robust Test를 이용한 이상치 검출방법
> library(stats)
> data[which(0.6748*(data-median(data))/mad(data) < -1.28)]
# [1] 75.79036 72.75131 50.00000
> data[which(0.6748*(data-median(data))/mad(data) > 1.28)]
# 121.6102 124.9713 121.2256 150.0000