이번에 살펴볼 개념은 Validation Set Approach라는 것입니다. 흔히 machine learning에서는 단순히 현재 training data에 대해서만 최적화 하는 것이 아니기 때문에 반드시 test data에 대한 성능이 중요한데요, 우리에게 test data가 주어진 것이 아니기 때문에 현재 가지고 있는 데이터의 일부를 쪼개서 test data로 활용하는 방법을 Cross-validation이라고 합니다. Cross-validation에도 여러가지 방법들이 있는데요, 그 중에서 가장 간단하게 활용되곤 하는 방법이 validation set approach입니다.

validation-set-approach

위와 같이 랜덤하게 dataset을 이등분하여 training set과 test set으로 활용하는 것입니다. 보통 비율은 50~75%까지 다양하게 선택하곤 합니다. 그럼 이제 R 코드로 어떻게 쪼개면 되는지 알아봅시다. 먼저 Auto 데이터를 사용하기 위해서 ISLR library를 포함시켜 줍니다.

library(ISLR)

다음으로 set.seed(number) 명령은 같은 코드를 실행할 때에 동일한 난수 패턴을 얻기 위해서(reproducible) 사용됩니다. 지금은 seed로 1을 사용해 봅시다.

set.seed(1) #random의 seed를 임의의 자연수로 설정해 줌으로써 실행할 때마다 동일한 난수 패턴을 얻습니다.

이제 sample()함수를 사용하여서 1부터 392까지의 자연수 중 196개를 임의로 뽑아봅시다.(50%의 데이터를 추출하기 위함입니다.)

train=sample(392, 196) #1~392까지 중 196개의 수를 임의로 뽑습니다.
head(train)
## [1] 105 146 224 354  79 348

결과를 보시면 아시겠지만, 순서가 섞여있고 1부터 392까지의 수 중 196개가 임의로 뽑혀있음을 확인할 수 있습니다. 그럼 이제 이 뽑힌 index들을 바탕으로 그들만 사용하여서 linear model을 만들어 보겠습니다.(참고 : linear model 만들기)

#subset=train으로 설정함으로써 위에서 뽑은 임의의 196개의 sample에 대해서만 linear model을 만듭니다.
lm.fit = lm(mpg~horsepower, data=Auto, subset=train)

만들어진 linear model을 바탕으로 test data에서 예측을 하려고 합니다. -train은 “train에 포함된 index를 제외한”이라는 의미입니다. 결국 test index들을 의미하겠죠? MSE(Mean Squared Error)를 아래와 같이 구해봅시다.

#원본 Auto데이터셋의 mpg항목에서 예측된 mpg를 뺀 값의 
#train index를 제외한 부분의 제곱의 평균을 구합니다.(MSE)
mean((Auto$mpg-predict(lm.fit, Auto))[-train]^2)
## [1] 26.14142

이제는 각각 2차함수와 3차함수를 fitting해서 MSE를 비교해봅시다. poly함수를 사용하면 되겠죠?

lm.fit2=lm(mpg~poly(horsepower,2), data=Auto, subset=train)
mean((Auto$mpg-predict(lm.fit2,Auto))[-train]^2)
## [1] 19.82259
lm.fit3=lm(mpg~poly(horsepower,3), data=Auto, subset=train)
mean((Auto$mpg-predict(lm.fit3,Auto))[-train]^2)
## [1] 19.78252

결과를 보시면 3차함수의 test MSE가 2차함수를 fitting했을 때보다 조금 더 낮게 나오네요 :) 그런데 여기서 validation set approach의 맹점이 있습니다. 위와 같이 차이가 조금 나는 경우 이것이 정말 model의 성능이 차이가 나서가 아닌 단순히 dataset이 섞인 우연(?)에 의해 발생되는 경우일 수도 있습니다. 그것을 확인하기 위해 이번엔 seed를 2로 설정해서 같은 작업을 반복해봅시다.

set.seed(2) #seed number가 다르면 전혀 다른 난수 패턴을 얻습니다.
train=sample(392, 196)
head(train)
## [1]  73 275 224  66 367 366

이번엔 seed가 다르기 때문에 전혀 다른 순서로 등장하죠? 그리고 MSE값도 차이가 나구요. 이제 2차와 3차함수를 fitting해보면,

lm.fit = lm(mpg~horsepower, data=Auto, subset=train)
mean((Auto$mpg-predict(lm.fit, Auto))[-train]^2)
## [1] 23.29559
lm.fit2=lm(mpg~poly(horsepower,2), data=Auto, subset=train)
mean((Auto$mpg-predict(lm.fit2,Auto))[-train]^2)
## [1] 18.90124
lm.fit3=lm(mpg~poly(horsepower,3), data=Auto, subset=train)
mean((Auto$mpg-predict(lm.fit3,Auto))[-train]^2)
## [1] 19.2574

이번에는 2차함수를 fitting했을 때가 MSE가 더 낮게 나왔네요. 하지만 기본적으로 1차함수들보다는 2차나 3차함수가 MSE가 낮은 것은 일관되었다는 것을 확인할 수 있는데요. 결국 validation set approach는 간단하고, 계산이 빠르다는 장점은 있지만, 정교한 model 비교는 힘들다는 것을 아실 수 있을 것입니다. 그럼에도 불구하고 많이 사용되는 방법이니 익혀두시는 게 좋습니다 :)