해당 포스트는
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 의 비율로 분할하기 위해서는 두번의 분할을 나누어 수행해야 합니다.
train
:(valid+test)
= 6:4(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 기계학습 : 사례 - 도요타 중고차 가격 예측