library(tidyverse)패키지를 이용해서 SMOTE와 ROSE가 어떻게 계산되는지 알아보겠습니다. 먼저 예제 데이터 생성을 위해 iris 데이터에서 Species를 “setosa”, “versicolor”만 필터링하겠습니다.
X <- iris[, c(1, 2, 5)] %>%
filter(Species %in% c("setosa", "versicolor") & row_number() %in% c(1:20, 51:100)) %>%
mutate(Species = factor(Species, labels = c("No", "Yes")))ROSE
N : ROSE를 통해 늘리고 싶은 sample size
- default : Y의 길이
p : minority class가 뽑힐 확률
set.seed(1)
result <- ROSE::ROSE(Species~., p = 0.3, data = X)
result$data$Species %>% table().
Yes No
50 20
X$Species %>% table().
No Yes
20 50
X %>% str()'data.frame': 70 obs. of 3 variables:
$ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
$ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
$ Species : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 1 1 1 1 1 ...
result <- ROSE::ROSE(Species~., p = 0.3, N = 200, data = X)
result$data$Species %>% table().
Yes No
139 61
SMOTE
per.over : oversampling을 조절하기 위한 parameter (200 : default)
- \(\text{minority class의 수} + \frac{per.over}{100} \times \text{minority class의 수}\)
per.under : undersampling을 조절하기 위한 parameter (200 : default)
- \(\frac{per.under}{100} \times \text{minority class에 대해 oversampling으로 추가된 샘플의 수}\)
k : 이웃의 수(5 : default)
set.seed(1)
smote_result <- DMwR::SMOTE(Species~.,
perc.over = 100,
perc.under = 0,
data = X)Registered S3 method overwritten by 'quantmod':
method from
as.zoo.data.frame zoo
X$Species %>% table().
No Yes
20 50
smote_result$Species %>% table().
No Yes
40 0
per.over = 100일 때, 20(minority class No의 개수) + 1x20 = 40개가 oversampling되는 것을 확인할 수 있습니다.
set.seed(1)
smote_result <- DMwR::SMOTE(Species~.,
perc.over = 200,
perc.under = 0,
data = X)
X$Species %>% table().
No Yes
20 50
smote_result$Species %>% table().
No Yes
60 0
per.over = 200일 때, 20(minority class No의 개수) + 2x20 = 60개가 oversampling되는 것을 확인할 수 있습니다.
set.seed(1)
smote_result <- DMwR::SMOTE(Species~.,
perc.over = 100,
perc.under = 100,
data = X)
X$Species %>% table().
No Yes
20 50
smote_result$Species %>% table().
No Yes
40 20
per.over = 100일 때, minority class에 대해 20개 만큼 oversampling 되었습니다. per.under = 100일 때, 이전 oversampling한 샘플의 수 \(20 \times \frac{per.under}{100} = 20\)이므로, \(20\)개 만큼 undersampling된 것을 확인할 수 있습니다.
set.seed(1)
smote_result <- DMwR::SMOTE(Species~.,
perc.over = 100,
perc.under = 200,
data = X)
X$Species %>% table().
No Yes
20 50
smote_result$Species %>% table().
No Yes
40 40
per.under = 200일 때, 이전 oversampling한 샘플의 수 \(20 \times \frac{per.under}{100} = 40\)이므로, \(40\)개 만큼 undersampling된 것을 확인할 수 있습니다.
Citation
@online{don2023,
author = {Don, Don and Don, Don},
title = {ROSE \& {SMOTE} {패키지} {관련}},
date = {2023-02-16},
url = {https://dondonkim.netlify.app/posts/2023-03-10-smote-rose/smoterose.html},
langid = {en}
}