데이터셋 나누기
데이터셋 (Dataset)
- Train 데이터셋 (훈련/학습 데이터셋)
- 모델을 학습시킬 때 사용할 데이터셋.
- Validation 데이터셋 (검증 데이터셋)
- Train set으로 학습한 모델의 성능을 측정하기 위한 데이터셋
- Test 데이터셋 (평가 데이터셋)
- 모델의 성능을 최종적으로 측정하기 위한 데이터셋
- Test 데이터셋은 마지막에 모델의 성능을 측정하는 용도로 한번만 사용되야 한다.
- 학습과 평가를 반복하다 보면 모델이 검증때 사용한 데이터셋에 과적합되어 새로운 데이터에 대한 성능이 떨어진다.
그래서 데이터셋을 train 세트, validation 세터, test 세트로 나눠 train 세트와 validation 세트로 모델을 최적화 한 뒤 마지막에 test 세트로 최종 평가를 한다.
- 학습과 평가를 반복하다 보면 모델이 검증때 사용한 데이터셋에 과적합되어 새로운 데이터에 대한 성능이 떨어진다.
Hold Out
- 데이터셋을 Train set, Validation set, Test set으로 나눈다.
- sklearn.model_selection.train_test_split() 함수 사용
Hold Out 예시
# iris - train, validation, test dataset으로 분리
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier #모델-결정트리
from sklearn.metrics import accuracy_score # 모델 평가함수 -> 정확도
from sklearn.model_selection import train_test_split # 데이터셋을 나누는 함수.
iris_data = load_iris()
iris_data.keys()
X, y = iris_data.data, iris_data.target
X.shape, y.shape
import numpy as np
# train, test로 분리
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=0.2, #기본:0.25
stratify=y, #target의 class비율에 맞춰서 분리
random_state=1)
print(X_train.shape, y_train.shape, X_test.shape, y_test.shape)
print(np.unique(y_train, return_counts=True))
Train set을 Train/validation set으로 분리
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train,
test_size=0.2, stratify=y_train,
random_state=1)
X_train.shape, X_val.shape, X_test.shape
모델생성 및 평가
# 모델 생성
tree = DecisionTreeClassifier()
# 모델 학습 - train set
tree.fit(X_train, y_train)
# 예측 및 평가 - train/validation set
pred_train = tree.predict(X_train)
pred_val = tree.predict(X_val)
train_score = accuracy_score(y_train, pred_train)
val_score = accuracy_score(y_val, pred_val)
print("train set의 예측결과: {}, validation set의 예측결과: {}".format(train_score, val_score))
# ==> train set의 예측결과: 1.0, validation set의 예측결과: 0.9166666666666666
# 최종 평가 - test
pred_test = tree.predict(X_test)
test_score = accuracy_score(y_test, pred_test)
print("최종평가(test set): {}".format(test_score))
#==> 최종평가(test set): 0.9666666666666667
Holdout 방식의 단점
- train/test 셋이 어떻게 나눠 지냐에 따라 결과가 달라진다.
- 데이터가 충분히 많을때는 변동성이 흡수되 괜찮으나 수천건 정도로 적을 때는 문제가 발생할 수 있다.
- 데이테셋의 양이 적을 경우 학습을 위한 데이터 양이 너무 적어 학습이 제대로 안될 수 있다.
K-겹 교차검증 (K-Fold Cross Validation)
- 데이터셋을 K 개로 나눈 뒤 하나를 검증세트로 나머지를 훈련세트로 하여 모델을 학습시키고 평가한다. 나뉜 K개의 데이터셋이 한번씩 검증세트가 되도록 K번 반복하여 모델을 학습시킨 뒤 나온 평가지표들을 평균내서 모델의 성능을 평가한다.
- 종류
- K-Fold
- Stratified K-Fold
KFold
- 지정한 개수(K)만큼 분할한다.
from sklearn.model_selection import KFold
# K-Fold K-개수, fold 나눠진 데이터셋 - 5개
kfold = KFold(n_splits=5)
acc_train_list = [] # 평가지표들을 저장할 리스트
acc_test_list = []
ex = kfold.split(X)
print(type(ex))
next(ex) # 반복자의 다음 요소 구하기
# ==> (array([ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
# 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
# 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
# 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
# 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
# 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
# 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
# 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133,
# 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146,
# 147, 148, 149]),
# array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
# 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]))
for train_index, test_index in kfold.split(X):
# index를 이용해 훈련/검증 데이터셋 추출
X_train, y_train = X[train_index], y[train_index]
X_test, y_test = X[test_index], y[test_index]
# 모델생성
tree = DecisionTreeClassifier()
# 학습
tree.fit(X_train, y_train)
# 검증
pred_train = tree.predict(X_train)
pred_test = tree.predict(X_test)
acc_train = accuracy_score(y_train, pred_train)
acc_test = accuracy_score(y_test, pred_test)
acc_train_list.append(acc_train)
acc_test_list.append(acc_test)
acc_test_list, np.mean(acc_test_list)
# ==> ([1.0, 1.0, 0.8666666666666667, 0.9333333333333333, 0.8], 0.9199999999999999)
K-Fold의 문제점
- 원 데이터셋의 row 순서대로 분할하기 때문에 불균형 문제가 발생할 수 있다.
Stratified K 폴드
- 나뉜 fold 들에 label들이 같은(또는 거의 같은) 비율로 구성 되도록 나눈다.
from sklearn.model_selection import StratifiedKFold
s_fold = StratifiedKFold(n_splits=3)
acc_train_list = []
acc_test_list = []
ex = s_fold.split(X, y) #label의 class 별 동일한 분포로 나눈다.
type(ex)
for train_index, test_index in s_fold.split(X, y):
X_train, y_train = X[train_index], y[train_index]
X_test, y_test = X[test_index], y[test_index]
# 모델생성
tree = DecisionTreeClassifier()
# 학습
tree.fit(X_train, y_train)
# 검증
pred_train = tree.predict(X_train)
pred_test = tree.predict(X_test)
acc_train = accuracy_score(y_train, pred_train)
acc_test = accuracy_score(y_test, pred_test)
acc_train_list.append(acc_train)
acc_test_list.append(acc_test)
acc_train_list, np.mean(acc_train_list)
#==> [1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
acc_test_list, np.mean(acc_test_list)
#==> ([0.98, 0.92, 0.96, 0.98, 0.92, 0.96], 0.9533333333333333)
cross_val_score( )
- 데이터셋을 K개로 나누고 K번 반복하면서 평가하는 작업을 처리해 주는 함수
- 주요매개변수
- estimator: 학습할 평가모델객체
- X: feature
- y: label
- scoring: 평가지표
- cv: 나눌 개수 (K)
- 반환값: array - 각 반복마다의 평가점수
from sklearn.model_selection import cross_val_score
tree = DecisionTreeClassifier()
score_list = cross_val_score(tree, X, y, scoring='accuracy', cv=3)
score_list
#==> array([0.98, 0.94, 0.98])
np.mean(score_list)
# ==> 0.9666666666666667
728x90
반응형
'Data Analysis & ML > Machine Learning' 카테고리의 다른 글
[Machine Learning][머신러닝] 과적합과 해결방법(그리드서치/파이프라인) (0) | 2020.08.31 |
---|---|
[Machine Learning][머신러닝] Classification(분류) 평가지표 (0) | 2020.08.28 |
[Machine Learning][머신러닝] 데이터 전처리(범주형/연속형) (5) | 2020.08.27 |
[Machine Learning][머신러닝] IRIS 분석 (결정 트리 모델(Decision Tree)) (0) | 2020.08.26 |
[Machine Learning][머신러닝] 머신러닝 개요 (0) | 2020.08.26 |