본 게시글은
서울대학교 데이터사이언스대학원 오민환 교수님의
데이터사이언스를 위한 머신러닝 및 딥러닝1 수업을
학습을 목적으로 재구성하였습니다
이번 시간과 다음시간까지는 resampling methods에 대해서 배우는데
그 중에서 이번 시간은 cross validation에 대해서 배운다
다음시간은 boostrap에 대해서 배운다고 한다
위에서 이번에 배우는게 Resampling methods라고 했는데
그럼 이게 정확하게 어떤 개념이냐?
우리가 모델을 학습시키려고 하면 training data가 필요한데
가지고 있는 training data를 최대한 잘 활용해서
training data에서 얻을 수 없는 것을 얻어보자는 것에 대한 내용이다
우리가 지금 갖고있는게 training data밖에 없다고 해보자
training data밖에 없는데 test dataset에서의 prediction을 알고싶다
그럼 이걸 어떻게 구할 수 있을까?
test dataset이 따로 마련이 되어있다면 여기서 prediction error를 구하면 되는데
만약 test dataset이 없다면 이걸 어떻게 구할 수가 있을까?
이전 수업시간에도 계속해서 강조되었지만
우리가 궁극적으로 하고자 하는 것은 test dataset에서의 performance를 높이는 것이다
즉, test error를 줄여야한다는 뜻이다
test error는 한번도 train되지않은 record에서의 performance이다
즉 우리가 학습시킨 모델을 활용해서
한 번도 본적 없는 데이터에 대한 prediction을 구하고
에러를 구하는 것이다
train error는 학습에 사용된 데이터에 대한 에러이다
train dataset에서는 우리가 모델 fit만 잘시키면
train error를 상대적으로 낮게 만드는 것이 가능하다
하지만 이렇게 되면 관측하지 못한 데이터에 대해서는
underestimate 하는 경향이 있다
모델의 complexity와 train, test dataset의 error를 살펴보자
가로축이 model complexity이다
model complexity가 작을수록 모델의 파라미터 개수가 적고
그렇다보니 Bias(편향)은 낮고 variance(변동성)은 작다
반대로 model complexity가 클수록 모델의 파라미터 개수는 많고
Bias는 낮아지고 variance는 높아진다
우리가 상식적으로 생각해보자
train dataset이 있고 우리가 사실 모델의 파라미터를
무한정으로 늘리면 train error를 0에 가까이도 만들 수 있다
하지만 test error는 그렇지 않다
모델 complexity를 키운다고해서 test error를 줄일수는 없다
이는 위 figure에서도 잘 나와있다
필요이상으로 model complexity를 키우면 어느 순간에서부터
test error가 증가하는 것을 확인할 수 있다
이렇게 되는 이유는 train data와는 달리
test data는 한 번도 보지 않은 데이터이기 때문에
model complexity를 늘린다고 이 데이터에 대해서
일반화된 모델을 만들기가 쉽지 않기 때문이다
bias가 높아지면 variance가 낮아지고
variance가 높아지면 bias가 낮아진다
bias가 높다는 뜻은 모델이 flexible하지 않은데
데이터가 조금 변한다고해서 모델이 확확 변하지않는다는 뜻이다
따라서 이 두 개를 적절히 balance할 필요가 있다
따라서 위 figure에서 model complexity가 오른쪽으로 갈수록
모델이 overfitting 되었을 확률이 높아지고
왼쪽으로 갈수록 underfitting 되었을 확률이 높아진다
그렇다면 이런 예시를 한 번 잘 들어보자
어떤 train data가 있다. 이 train data에 대해서 모델을 잘 학습시켰다
모델의 train error는 굉장히 작게 나왔다
그래서 이제 test를 위해서 다른 분포에 있는 데이터에서 test data를 뽑아와
test를 수행했더니 test error가 되게 높았다고 해보자
이걸 우리가 overfitting이라고 할 수 있을까?
정답은 그렇지 않다
그렇다면 뭐가 잘못된걸까?
잘못된 점은 "다른 분포"에 있는 데이터에서
test dataset을 뽑아왔다는 점이다
test data는 다른 분포에서 뽑아오면 안된다
우리가 학습시킨 모델은 train dataset의 분포에서 학습이 잘 된건데
이 데이터에서 한 번도 관측되지않은 어떤 orthogonal한 space에서
어떤 데이터를 뽑아와서 걔가 성능이 좋길 바라는 것부터가 말이 안되는 것이다
이건 그냥 data shift와 동일하다
overfitting은 동일한 분포에서 온 test dataset에서 못할 때를 의미한다
overfitting의 문제가 되는 이유는
training dataset을 잘 fit 시킨 것이 문제가 아니고
training dataset 안에 있는 noise까지 fit 시킨 점이 문제가 되는 것이다
보통 우리가 모델 학습을 수행하다보면
train set이 데이터의 양이 많지않은 경우가 많다
그래서 이 문제를 극복하기 위한 Cp statistic, AIC, BIC등
다른 metric들이 존재한다
위 방법들은 train error에서 나오는 RSS들을
model complexity랑 잘 버무려서 나오는 함수들이다
이 친구들은 test, validation error에서의 에러를 구하는게 아니고
train error를 잠깐 변형시켜서 여기에 model complexity를
수학적으로 잘 녹여서 나온 것이라고 한다
위 metric에 대한 내용은 나중에 더 자세하게 나오니
오늘은 일단 넘어가자
아무튼 우리가 아까 이 resampling method에서 하고싶은건
training dataset만을 가지고 training dataset에서는
얻을 수 없는 정보들을 얻는 것이었다
그 중에 한개가 test dataset이 없이 training dataset만 있을 때의
test error를 구하는 것이다
이걸 위해서 전체 우리가 갖고 있는 train dataset에서
이걸 일부러 다 쓰지않고 일부를 hold out을 한다
이 hold out 시킨 일부를 estimate set으로 사용하려고 하는 것이다
이게 오늘 우리가 배울 내용이다
이러한 estimate set의 가장 대표적인 예시가 바로
validation set이다
test dataset이 한 개도 없고
우리가 train dataset만 가지고 있다고 하면
일부는 모델 학습용으로도 사용하고
학습을 할 때 evaluate를 하기 위한 데이터셋으로 사용하는 것이다
참고로 validation set에서의 에러는
mean square error로도 구할 수 있고
아니면 다른 방법으로도 score를 구할 수 있다
그렇다면 validation set을 뽑아내기 위해서
train dataset에서 일부를 hold out한다고 했는데
이걸 어느 정도의 비율로 뽑아내면 좋을까?
크게 정답은 없고 적절한 사이즈로 뽑아내면 된다고 한다
50:50이든 20:80이든 크게 상관은 없다고 한다
만약 데이터가 N개 있다고 가정해보자
이 예제에서는 50:50으로 validation set을 split한다고 해보자
우리가 우선 가장 먼저 해야할 것은
뽑기 전에 데이터셋을 한 번 shuffling을 해야한다
그 다음 데이터를 split 해준다
따라서 위 ppt slide에서 왼쪽을 training set으로 오른쪽을 validation set으로 사용한다
다시 한 번 강조하지만 validation을 하는 이유는
test dataset이 없을 때 우리가 test error를 구하기 위함이다
위 예시를 한 번 잘 살펴보자
polynomial degree가 증가한다는 것은 model complexity가 증가한다는 뜻이다
우리가 임의로 train dataset에서 validation set을 뽑아서 에러를 측정했다
왼쪽은 그걸 1번만 수행한 것이고
오른쪽은 random으로 validation set을 뽑는 과정을 여러번 수행한 것이다
그럼 오른쪽 그래프를 보면서 당연히 드는 생각이 있을 것이다
값들이 다 왜이렇게 차이가 많이 나는것일까?
split이 다를 때마다 값들의 차이가 확연하게 나타나는 것을 볼 수 있다
이런 validation error가 상당히 variance가 크다는 것을 알 수 있다
그렇다면 우리가 validation set을 뽑은 다음
거기서 error를 측정한다고 하자
이 validation error는 실제로 변동성이 굉장히 크다
그럼 validation error가 과연 실제 test error보다 높게 나올까 낮게 나올까?
정답은 높게 나오는 경향이 있다는 것이다
왜그럴까?
왜냐면 우리가 지금 train에서 사용하는 데이터의 양이
전체 데이터의 반밖에 사용되지 않았기 때문이다
적은 데이터만을 학습시켰기 때문에 prediction error가 더 크고
당연히 덜 accurate할 수밖에 없다
데이터를 적게 사용해서 over esitmate할 경향이 있다
이제부터 본격적으로 이번 시간에 배울
cross-validation이 무엇인지 배워보자
k-fold cross validation은 데이터를 k개의 partition으로 구분한다
이 파티션들은 서로 겹치는 부분이 있어서는 안되고
되도록이면 equal size로 나누는 것이 좋다
그래서 각 partition마다 k번 validation error들을 구한 다음
이들을 평균을 내는 것이다
데이터의 총 개수가 N개라고 해보자
그렇다면 가장 먼저 이 N개의 데이터들을 shuffling 해야한다
그런 다음 k개의 fold로 나누는데
아까도 말했듯이 이 fold들은 서로 disjoint하고
union으로 합치면 전체 N개의 데이터가 다 나와야한다
위 ppt slide에서는 fold가 5개이고 k=5인 것이다
따라서 5-fold cross-validation이 되는 것이다
첫 번째를 한 번 살펴보자
오렌지색으로 되어있는 부분이 validation set이다
이 부분을 제외하고 나머지 파란색만 우선 학습시킨다
그런 다음 validation set에서 error를 구한다
두번째도 마찬가지고 세번째도 마찬가지다
그래서 결국 이걸 K번(5번)을 반복한다
그런 다음 이 validation error를 평균을 내면 되는 것이다
각각의 k-fold set을 C1, C2 .. Ck라고 하자
그렇다면 각각의 fold set에서 나오는 MSE를
weighted sum을 해주면 된다
nk는 k번째 fold에 들어가있는 data의 개수이다
그렇다면 우리가 k-fold cross validation을 수행할 때
k를 몇 개정도로 하면 좋을까?
만약 예를 들어서 k가 그냥 데이터 전체의 개수 N과 같다고 하자
special case이긴 하지만 이런 상황이 있다고 하자
그럼 validation set에 들어가있는 데이터는 총 몇개가 될까?
1개가 되어버린다
이걸 leave-one out cross-validation(LOOCV)이라고 한다
바로 이런 경우가 leave-one out cross-validation(LOOCV)이다
이게 가장 extreme한 경우이다
사실상 이런 경우는 data를 shuffling 할 필요도 없다
어차피 모든 데이터가 한 번씩 validation set이 되기 때문이다
그렇다면 이게 좋은 방법일까?
우선 이 방법의 장점을 알아보자
이 방식은 우선 data fit을 할 때 training data를 최대한 많이 사용할 수 있다
그렇다면 단점은 무엇일까?
데이터포인트가 예를 들어 10000개가 있다고 하자
그렇다면 모델을 총 10000번을 fit 시켜줘야한다
이제 결과를 한 번 살펴보자
왼쪽이 LOOCV이고 오른쪽은 fold를 10개로 나눴을 때의 결과이다
오른쪽에서 각각의 색상은 각 fold를 나타낸다
fold별로 차수에 따라서 MSE를 측정한 값을 그린 결과이다
아까 앞의 random으로 validation set을 뽑아서
수행했을 때에 비해서 확실히 variance가 작아진 것을 확인할 수 있다
보통 사람들이 k-fold cross validation을 수행할 때
10-fold를 가장 적당하다고 하는데
이게 가장 안정적인 성능을 보이기 때문이다
위 차트에서는 blue line이 MSE를 한 결과이고(true test MSE)
black line이 LOOCV이고
orange line이 10-fold CV를 수행한 결과이다
3개가 각각 다 다른 데이터셋이고
다른 데이터셋에 대해서 동일하게 실험을 해본 결과라고 한다
cross validation으로 얻는 validation error들도
결국 estimate 값이기 때문에 variance가 당연히 어느정도 존재한다
위 세개의 서로 다른 데이터셋 중에서
가장 linear한 관계인 것을 뽑으라고 한다면
flexibiliy = complexity가 높을 수록 test error가 증가하는
가운데 데이터셋이 될 것이고
가장 non-linear한 데이터셋을 찾으라고 한다면
가장 오른쪽 데이터셋이 될 것이다
아무튼 k-fold cross validation으로 측정한 error가
어느정도 true test error에 유사함을 알 수 있다
하지만 그렇다고 해서 k-fold cross validation이 무조건 좋은 것은 아니다
앞에서도 말했지만 train data에서 일부를 뽑아내
validation data로 사용한 것부터
실제로 학습을 시킬 수 있는 데이터는 줄어드는 것이다
따라서 실제로 train 할 때와 cross validation을 해서
얻는 error rate는 당연히 validation을 수행할 때가 더 높다
이렇게 되면 모델의 bias가 큰 것이 된다
그럼 최대한 학습 데이터를 살리는 방향으로 validation을 해볼까?
그게 우리가 앞에서 배운 LOOCV다
이게 가장 bias를 줄일 수 있는 방식으로 validation을 하는 것이다
하지만 그럼 또 variance가 늘어나게 된다
따라서 이 bias-variance 관계는 trade off에 있고
이 balance를 잘 맞추는 것이 중요하다
K가 5 혹은 10이 가장 좋은 balance를 준다고 한다
앞에서 10-fold cross validation이 가장 추천된다고 했는데
단순히 계산량이 적기 때문에 추천되는 것이 아니다
LOOCV에 비해서 계산량이 적은 것도 사실이지만
test error에 대한 bias와 variance가 적절하기 때문이기도 하다
그렇다면 이번에는 classification problem에서
cross validation error을 어떻게 계산하는지 살펴보자
아까 classification이 아닌 것에서는 그냥 MSE를 평균내는 방식으로 수행했는데
classification은 그냥 각각의 fold에서 나오는
mis classification error를 구한 다음 평균을 내면 된다
위는 classification error를 구한 예시이다
실제 데이터를 가지고 계산한 값이다
logistic regression을 degree 각각 1, 2, 3, 4로 해서
계산을 해서 비교한 결과이다
검정색 선이 logistic regression의 decision boundary이다
그렇다면 logistic regression의 decision boundary는
linear일까 아닐까?
정답은 linear이다
위 ppt slide에서도 degree가 1일 때
decision boundary가 직선인 것을 확인할 수 있다
실제로 우리가 one dimension에서의
sigmoid 함수를 잘 살펴보면
sigmoid 함수에서 그 0.5에서 자르면 되니까
당연히 linear 함수일 것이다
그런데 여기서 고차항을 추가하게 된다면?
고차항을 추가하면 decision boundary는
linear가 아닌 non-linear boundary가 나올 수 있다고한다
위 ppt slide에서도 2, 3, 4차항일 경우는
non-linear decision boundary가 나오는 것을 확인할 수 있다
위 차트에서 보라색이 true decision boundary이고
각각 degree별로 test error rate은
0.201, 0.197, 0.160, 0.162라고 한다
그리고 True decision boundary로 test error rate를 계산하면
0.133이 나온다고 한다
하지만 실제 상황에서는 우리는 true test error rate은 알 수가 없다
위의 ppt slide에서 노란색은 test error
파란색은 training error
검은색은 10-fold CV error이다
왼쪽 차트는 logistic regression으로 수행한 모델이고
오른쪽은 k-nearest neighbors로 수행한 모델이라고한다
k-nearest neighbors는 우리 수업시간에 다루지는 않은 모델인데
하나의 데이터 포인트에서 바라볼 때
이 데이터 포인트에 대한 prediction을 수행하면서
주변에 이웃하는 데이터포인트를 바라보며 prediction을 수행하는 모델이다
k가 작으면 작을수록(k는 주변 이웃들 개수) 더 smooth한 함수가 되고
k가 많을수록 더 Random한 Prediction이 된다
잘 쓰진 않으므로 참고만 하면 된다고 한다
아무튼 여기까지가 우리가 배운 cross-validation의 내용이다
다시 한 번 강조하지만 cross-validation의 가장 첫 번째 목적은
test dataset이 없을 때 test error를 estimate하기 위함이다
하지만 우리가 실제 상황에서 사실
train, val, test dataset이 다 있을 수도 있다
그런데 test dataset이 있을 때도 있는데
이럴 때도 validation dataset을 사용해야할까?
당연히 사용하면 좋다
그 이유는 여전히 마찬가지
test dataset이 없어도 우리의 모델이
얼마나 잘하고 있는지를 알고싶은 것이다
모델을 학습시키면서 cross-validation을 통해서
validation error를 구한다
이건 해당 모델에서 test error가 얼마나 나올지 알고싶은 것이다
예를 들어서 모델이 3개가 있다고 하자
각 3개의 모델을 학습시키면서 validation error를 구했다
그래서 2번째 모델의 validation이 가장 작다고 하자
그래서 우린 해당 모델을 가장 학습이 잘된 모델로 선택할 예정이다
2번째 모델이 test dataset에서 가장 성능이 좋을 것이라고 선정한 것이다
그래서 실제 test error를 계산해보려면?
해당 모델들에서 test dataset을 갖고 실제로 test error를 계산해보면된다
그런데 잘 한 번 생각해보자
사실 train dataset이 많을수록 모델의 bias가 작아지면서 좋은 것이다
가장 이상적인건 최대한 train dataset을 많이 쓰는 것이긴 하다
따라서 validation을 하지않고 그냥 train을 전부 다 시킨 뒤
test error를 바로 계산해서 test error가 가장 작은 모델을 선정했다
그럼 이게 괜찮은 방식일까?
정답은 그렇지 않다
왜냐하면 모델을 선정하는 과정에서
test error가 들어갔기 때문이다
다른 test dataset을 사용하면 우리가 선택한 모델의
test error가 작을 수가 있다
따라서 모델 selection 과정에서 test dataset이 들어가면 안되기 때문에
우리는 validation set으로 모델 selection을 수행하는 것이다
따라서 대부분의 경우
model selection, hyper parameter 튜닝은 전부 validation으로 수행한다
자 그러고 마지막으로 위 ppt slide의 글을 잘 살펴보자
5000개의 predictor가 있고 총 데이터개수가 50개인 상황을 가정해보자
그 중에서 우리가 y값과 가장 연관이 있을 것 같은 100개의 predictor를 선별한다
그런 다음 100개의 predictor만 활용해서 logistic regression model을 만들었다
뭐 모델이 학습이 되긴 할 것이다
학습을 하면서 test error를 estimate하고 싶어서
10-fold cross validation을 수행했다고 가정해보자
이게 어떻게 될까?
위와 같은 상황은 문제가 있다고 한다
우리가 100개의 predictor들을 추려냈을 때
y와 가장 관련이 있을 것 같다고 가정해서 추려냈는데
이 추려내는 과정 자체가 이미 y값들을 보고 결정을 한 것이다
따라서 cross validation을 수행하더라도 이미 y값을 본 애들인 것이다
즉, 정보의 leakage가 존재하는 것이다
만약에 우리가 5000개의 feature를 가진
50개의 dataset을 matrix로 만들어서
프로그래밍으로 랜덤하게 이 50개의 dataset을 만든다고해보자
그럼 이게 x와 y간에 연관되는 함수가 있을까?
아마 없을 것이다
그래서 얘를 어떻게는 y값이랑 연관이 있는 애들만
선별하고 선별해서 5000개 중에 100개만 선정했다고 한다
그래서 이걸 이용해서 학습을 시켰다고해보자
그럼 error rate는 사실상 거의 0이 나올 것이다
왜냐하면 x를 고를 때 y값을 보고 골랐고
그 친구들을 이용해서 학습을 시키니까 error rate는 0에 가까이 나오는 것이다
이런식으로 x를 selection하면 거의 정확도는 99%가 나온다
따라서 이런식으로 수행하면 안되는 것이다
그럼 앞의 상황을 잘 해결하려면 어떻게 했어야할까?
y에 있는 정보가 x로 절대 들어가게해서는 안된다
따라서 cross validation을 1번 step에서부터 수행해야한다
'강의 > machine learning & deep learning' 카테고리의 다른 글
[ML] Classification 2편 (LDA, QDA, Naive Bayes) (1) | 2025.09.16 |
---|---|
[ML] Classification 1편 (Logistic Regression) (1) | 2025.09.15 |
[ML] Linear Regression 2편 (F-statistics, categorical predictors, interactions) (0) | 2025.09.09 |
[ML] Linear Regression 1편 (single & multiple linear regression) (0) | 2025.09.08 |
[ML] Overview of Machine Learning (3) | 2025.09.02 |