main topic:
1. 데이터셋 분할 (train_test_split)
2. K-Fold
3. stratify
이번 챕터부터는 모델링이다.
준비된 데이터로 '사망' or '생존'을 예측하는 모델을 학습시켜야한다.
이를 지도학습이라고 한다.
학습관련된 이야기는 앞에서 다뤘으니 가볍게 리마인드하자면,
훈련데이터라는 정답이 있는 기출문제로 모델을 학습시키고 시험을 보게 하는 것이다.
따라서 기출문제가 좋을 수록, 모델이 좋을 수록, 공부방법이 좋을 수록 성적이 좋을 것이다.
지금까지 했던 데이터 전처리 및 특성 엔지니어링이 기출문제를 준비하는 과정이었다면,
이제는 기출문제로 모델을 학습할 차례이다.
여기서 모델을 학습시킬 때 중요한 개념이 있다.바로 데이터셋 분할인데, 이게 왜 필요할까?바로 성능 평가를 위해서 필요하다.
만약 1400개의 모든 승객 데이터로 모델을 학습시켰다고 하자.
이 모델의 성능을 어떻게 평가할 것인가?
일단 예측하고 죽는지 사는지 볼 것인가?
방법은 여러가지 있겠지만 가장 단순한 방법은 내가 가진 기출문제중에서 내 실력을 검증하는데 사용할만큼의 양을 따로 빼놓는 것이다.
마치 시험 직전용 모의고사처럼..!
총 기출문제 = (내가 공부할 기출문제) + (시험 직전용 모의고사)
근데 정말 치밀하게 준비하기 위해 검증용 모의고사를 2개 준비하는 경우도 있을 것이다.
총 기출문제 = (내가 공부할 기출문제) + (평소 실력 검증용 모의고사) + (시험 직전용 모의고사)
그림으로 보면
이와 같다.
A는 시험 직전용 모의고사(test)만 따로 빼놓는 것이고,
B는 평소 실력 검증용 모의고사(validation)와 시험 직전용 모의고사(test)까지 따로 빼놓는 것이다.
비유는 여기까지.
이제 test set과 Validation set에 대해 명확히 알아보자.
언뜻보기에는 똑같은 목적을 가진 것으로 보이지만 다르다.
test set은 단 한번.
완성된 단 한개의 모델을 정말 마지막에 단 한번 평가하기 위해 남겨 놓는 데이터 셋이다.
반대로 validation set은 여러개의 모델을 여러번 평가하는데에 얼마든지 써도 괜찮다.
핵심을 말하자면 "객관적인 성능"을 판가름하기 위한 데이터가 test set이고,
모델을 수정했을 때 성능이 올라갔는지 확인하거나, 1번 모델 성능이 좋은지 2번모델 성능이 좋은지 판단하기 위한 데이터가 validation set이다.
따라서 validation set은 모델링에 관여되므로
validation set으로 구한 성능이 정확하다고 할 수 없다.
(예를 들어 처음 validation set에서 정확도 80%가 나왔다고 가정하자.
이후에 성능을 올리기위해 특성을 마구잡이로 만들고, 이상치를 제거하는 등 수많은 엔지니어링을 거쳐서
validation set에서 정확도 100%를 만들었다.
이 모델이 과연 좋은 모델일까?
당연히 아닐 것이다. 오버피팅 100%일 것이니까
하지만 그 근거는?
test set이 없으면 확인할 수 없다.
모르는 데이터 조합 즉, 안풀어본 기출문제가 없으니까..!
이제 test set과 validation set이 각각 필요한 이유를 이해했다.
하지만 그로 인한 문제도 알 수 있었다.
validation set에 대한 overfitting.
위에서 말한 예시처럼 validation set에서의 성능을 올리기위해 온갖 방법을 동원한다면 결국 일반화를 놓치게 된다.
그럼 이를 해결할 방법은 뭐가 있을까?
validation set을 바꿔가면서 성능을 평가하면 되는 것아닌가?
이 아이디어로 나온 방법이 교차검증 (Cross-validation)이다.
그 중에서도 대표적인 방법인 K-Fold Cross Validation을 알아보자.
먼저 전체 데이터셋을 훈련 데이터와 test 데이터로 분할한다.
이후에 training data를 k(5)개의 fold로 나눈다.
총 5개의 fold중 첫번째 fold부터 마지막 fold까지 한번씩 validation set으로 지정해서 각 split마다 성능 평가
(* 색때문에 헷갈릴 수 있으나 맨위의 test set과 각 단계의 validation set은 별개임)
성능 평가를 통해 성능향상을 마친 후 남아있던 test data에 최종 성능 평가.
=> 오버피팅 될 가능성이 낮고, 일반화 정도를 확인하기 좋음
ex) 특정 split에서만 성능이 매우 높거나 낮음 -> 일반화 안된 것
여기까지 데이터 분할 (train/test/validation)에 대한 기본적인 설명이었다.
여기서 조금만 더 깊게 들어가보자.
우리의 target value는 '생존' or '사망'이다.
만약 train set의 모든 승객이 '생존'한 승객이라면?
모델은 '사망'에 대한 학습을 할 수 없다.
이 상황에 test set에 '사망'한 승객이 대부분이라면?
모델 성능은 거의 0%일 것이다.
그렇다면 모델은 '생존'한 승객과 '사망'한 승객을 골고루 학습할 수 있어야하고,
성능을 평가할 때도 골고루 평가할 수 있어야 한다.
이를 위한 방법은 데이터셋을 분할 할때 target변수의 클래스 비율에 맞춰서 데이터를 분할하는 것이다.
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test= \
train_test_split(X_train, y_train, test_size=0.3, random_state=0, stratify=target)
이 코드에서 눈여겨 볼 부분은 stratify=target이라는 파라미터이다.
생략되어있지만 target은 목표변수인 'Survived'열이다.
이렇게 하면 목표 변수의 클래스인 '생존', '사망'의 비율이 train set과 test set에서 동일하게 유지된채로 분할된다.
예를 들어 총 1000명 중 생존이 300명 사망이 700명이고 train set이 전체 데이터의 60%, test set이 40%라고 하면,
train_set의 총 인원수 : 1000 * 60 / 100=600
train_set의 생존자 수 : 600명 * (300/1000)
train_set의 사망자 수 : 600명 * (700 /1000)
test_set의 총 인원수 : 1000 * 40 / 100 = 400
test_set의 생존자 수 : 400명 * (300/1000)
test_set의 사망자 수 : 400명 * (700 /1000)
이 된다.
교차검증에서도 동일한 이유로 Stratified K-Fold를 사용한다.
각 split에서의 test set과 validation set의 비율을 맞춰주는 것..!
(맨 처음 데이터셋에서 train set과 test set을 분할할 때 stratify로 나누고, 그 이후에 stratified K-Fold를 사용하는 것..)
from sklearn.model_selection import StratifiedKFold
cv=StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
코드는 위와 같다!
이번 포스트에서는 데이터셋 분할에 대해 알아보았다.
중점
1. 데이터셋 분할이 왜 필요한가?
2. test set과 validation set의 차이는 무엇인가?
3. Cross-validation (K-Fold)
4. train_test_split (stratify= target)
4. stratifiedKFold
다음포스트에서는 마지막으로 모델링을 다루고 타이타닉 문제를 마칠 예정이다!
화이팅!