[R] R에서 반응 변수 비율에 맞춰 데이터셋 분할하기 (15회 ADP 실기 기출)

해당 포스트는 R에서 효율적인 데이터셋 분할 방법 을 설명하는 글입니다.
'15회 데이터 분석 전문가(ADP) 실기시험'에 데이터 마이닝 과목 세부 문제로 출제되었습니다.

지난 ADP 15회 실기시험 의 데이터 마이닝 과목 1번 문제는 종속 변수의 비율이 train:valid:test = 6:2:2 가 되도록 데이터셋을 분할하는 문제였습니다. 시험에서는 caret::createDatapartition 함수 사용에 실수가 있어 sample()함수로 해결하였으나 복기하다보니 문제가 해결되어 정리하였습니다.

1. sample() 함수 접근

아래와 흔히 sample() 함수를 이용하는 매 시행에 랜덤 추출이 적용되며, 데이터 셋이 동일한 비율로 분할되지만 종속 변수의 비율이 일정하지 않습니다.

데이터 분할 및 확인

data(iris)

set.seed(2020)

idx <- sample(1:3, size=nrow(iris), prob=c(0.6,0.2,0.2), replace = TRUE)

train <- iris[idx==1,]
valid <- iris[idx==2,]
test <- iris[idx==3,]

length(iris$Species)
# [1] 150

length(train$Species)
# [1] 92

length(valid$Species)
# [1] 29

length(test$Species)
# [1] 29

분할 데이터셋 종속 변수 확인

table(iris$Species)
# setosa versicolor  virginica 
# 50         50         50 

table(train$Species)
# setosa versicolor  virginica 
# 28         35         29 

table(valid$Species)
# setosa versicolor  virginica 
# 12          6         11 

table(test$Species)
# setosa versicolor  virginica 
# 10          9         10 

2. caret::createDatapartition() 함수 접근

일반적으로 데이터셋을 분할할 때에는 caret패키지의 createDatapartition() 함수를 많이 사용하며, 문제의 의도에 맞춰 정해진 비율의 종속 변수를 가지는 데이터셋으로 분할이 가능합니다.

createDatapartition() 함수는 2분할을 지원하는 함수이기에 문제 의도에 맞춰 train:valid:test = 6:2:2 의 비율로 분할하기 위해서는 두번의 분할을 나누어 수행해야 합니다.

  1. train:(valid+test) = 6:4
  2. (valid+test) -> valid:test = 5:5

1. train:(valid+test) = 6:4

library(caret)

data(iris)

idx <- createDataPartition(iris$Species, p = c(0.6, 0.4), list = FALSE)

train <- iris[idx,]
valid_test <- iris[-idx,] 

length(train$Species)
# 90

length(valid_test$Species) 
# 60

table(train$Species)
# setosa versicolor  virginica 
# 30         30         30 

table(valid_test$Species)
# setosa versicolor  virginica 
# 20         20         20

2. (valid+test) -> valid:test = 5:5

idx2 <- createDataPartition(valid_test$Species, p = c(0.5, 0.5), list = FALSE)

valid <- valid_test[idx2,]
test <- valid_test[-idx2,] 

length(valid$Species)
# 29

length(test$Species)
# 29

3. 결과 검토

아래 결과를 보면 문제에서 제시한 바와 같이, 데이터 셋의 종속 변수 비율이 train:valid:test = 6:2:2 로 잘 분할된 것을 확인할 수 있습니다.

nrow(train)/nrow(iris)
# 0.6

nrow(valid)/nrow(iris)
# 0.2

nrow(test)/nrow(iris)
# 0.2

table(train$Species)
# setosa versicolor  virginica 
# 30         30         30 

table(valid$Species)
# setosa versicolor  virginica 
# 10         10         10 

table(test$Species)
# setosa versicolor  virginica 
# 10         10         10 

3. 정리

데이터셋 분할은 데이터 마이닝이나 기계 학습 과목에서 항상 출제되고 있는 문제입니다. 다양한 해결책이 있을 수 있으나 개인적으로는 위에서 설명드린 caret::createDatapartition() 함수를 활용하는 것을 추천드립니다.

4. 참고

[1] xwMOOC 기계학습 : 사례 - 도요타 중고차 가격 예측


banner-request-analysis