Cross validation
- 모델의 일반화 성능 (새로운 데이터에서 대한 예측 또는 분류)
Holdout cross-validation
- 모델의 성능을 높이기 위해 hyper-parameter 튜닝을 통해 모델 선택 과정을 거쳐야 한다. 이때, train, validation, test 3 개로 나눈다.
- validation dataset으로 모델 선택에 사용한다.
- 다만, train dataset을 나누는 방법에 따라 성능 추정이 민감하다는 단점이 있다.
- data의 양이 매우 많을 때 사용하는 것을 권장한다.
k-fold cross-validation
1) 개요
- train_test_split을 여러 번 수행하는 것과 같은 방식으로 holdout방식에 비해 많은 computing power가 요구된다.
- holdout 방법에 비해 train dataset split에 덜 민감하다.
- train data가 충분하지 않다면 fold 개수를 늘리는 것이 좋다.
- fold 개수가 터무니없이 크다면 train fold가 비슷해져 분산이 높아질 수 있다.
- 경험적으로 좋은 k 기본값은 10이며, 대규모 dataset의 경우 5이다.
2) 과정
(1) 중복을 허락하지 않고 train dataset을 k개의 fold로 랜덤하게 나눈다.
(2) k - 1개의 fold로 훈련하고 나머지 하나의 fold로 성능을 평가한다.
(k번 반복 -> k개의 모델과 성능 추정을 얻음)
(3) k개의 성능 추정으로 모델의 평균 성능 계산
(4) 최적의 hyper-parameter로 전체 train dataset으로 훈련하고 test dataset을 사용해 최종 성능추정
3) LOOCV (Leave-One-Out Cross-Validation)
- fold 개수 k가 train sample 개수 n과 같다. (k = n)
- 매우 작은 dataset에 사용된다.
4) Stratified k-fold cross-validation
- 각 fold에서 class label 비율이 전체 dataset에서의 비율을 대표하도록 유지한다.
5) 코드 예시
'''작동 원리 코드'''
import numpy as np
from sklearn.model_selection import StratifiedKFold
kfold = StratifiedKFold(n_splits = 10, random_state = 1, shuffle = True).split(X_train, y_train)
scores = []
for k, (train, test) in enumerate(kfold):
pipe_lr.fit(X_train[train], y_train[train])
score = pipe_lr.score(X_train[test], y_train[test])
scores.append(score)
print(f"폴드: {k+1}, 클래스 분포: {np.bincount(y_train[train])}, 정확도: {round(score, 3)}")
print(f"CV 정확도: {np.mean(scores)} +/- {np.std(scores)}")
'''sklearn kfold cv'''
from sklearn.model_selection import cross_val_score
scores = cross_val_score(estimator = pipe_lr, X = X_train,
y = y_train, cv = 10, n_jobs = -1)
print(f"CV 정확도 점수 : {scores}")
print(f"CV 정확도: {np.mean(scores)} +/- {np.std(scores)}")
'''평가 지표 설정 후 train, test 데이터 점수'''
from sklearn.model_selection import cross_validate
scores = cross_validate(estimator = pipe_lr, X = X_train,
y = y_train, scoring = ['accuracy'],
cv = 10, n_jobs = -1, return_train_score = False)
print(f"CV 정확도 점수 : {scores['test_accuracy']}")
print(f"CV 정확도: {np.mean(scores['test_accuracy'])} +/- {np.std(scores['test_accuracy'])}")
학습곡선
- 그래프를 통해 분산과 편향의 문제점을 시각적으로 확인할 수 있다.
import matplotlib.pyplot as plt
from sklearn.model_selection import learning_curve
pipe_lr = make_pipeline(StandardScaler(),
LogisticRegression(solver = 'liblinear',
penalty = 'l2',
random_state = 1))
train_sizes, train_scores, test_scores = learning_curve(estimator = pipe_lr,
X = X_train,
y = y_train,
# linspace로 일정간격 훈련세트의 비율선택
train_sizes = np.linspace(
0.1, 1.0, 10),
cv = 10,
n_jobs = 1)
train_mean = np.mean(train_scores, axis = 1)
train_std = np.std(train_scores, axis = 1)
test_mean = np.mean(test_scores, axis = 1)
test_std = np.std(test_scores, axis = 1)
plt.plot(train_sizes, train_mean,
color = 'blue', marker = 'o',
markersize = 5, label = 'training accuracy')
plt.fill_between(train_sizes,
train_mean + train_std,
train_mean - train_std,
alpha = 0.15, color = 'blue')
plt.plot(train_sizes, test_mean,
color = 'green', linestyle = '--',
marker = 's', markersize = 5,
label = 'validation accuracy')
plt.fill_between(train_sizes,
test_mean + test_std,
test_mean - test_std,
alpha = 0.15, color = 'green')
plt.grid()
plt.xlabel('Number of training samples')
plt.ylabel('Accuracy')
plt.legend(loc = 'lower right')
plt.ylim([0.8, 1.03])
plt.tight_layout()
plt.show()
검증곡선
- 학습곡선과 다르게 모델 parameter 값의 함수로 그린다.
# logistic regression's hyper-parameter : C
from sklearn.model_selection import validation_curve
param_range = [0.0001, 0.001, 0.01, 0.1, 1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0]
trian_scores, test_scores = validation_curve(estimator = pipe_lr,
X = X_train,
y = y_train,
param_name = 'logisticregression__C',
param_range = param_range,
cv = 10)
train_mean = np.mean(train_scores, axis = 1)
train_std = np.std(train_scores, axis = 1)
test_mean = np.mean(test_scores, axis = 1)
test_std = np.std(test_scores, axis = 1)
plt.plot(param_range, train_mean,
color = 'blue', marker = 'o',
markersize = 5, label = 'training accuracy')
plt.fill_between(param_range,
train_mean + train_std,
train_mean - train_std,
alpha = 0.15, color = 'blue')
plt.plot(param_range, test_mean,
color = 'green', linestyle = '--',
marker = 's', markersize = 5,
label = 'validation accuracy')
plt.fill_between(param_range,
test_mean + test_std,
test_mean - test_std,
alpha = 0.15, color = 'green')
plt.grid()
plt.xlabel('Parameter C')
plt.ylabel('Accuracy')
plt.xscale('log')
plt.legend(loc = 'lower right')
plt.ylim([0.8, 1.0])
plt.tight_layout()
plt.show()
Gridsearch
- 최적의 hyper parameter를 찾기 위해 사용한다.
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
pipe_svc = make_pipeline(StandardScaler(),
SVC(random_state = 1))
param_range = [0.0001, 0.001, 0.01, 0.1, 1.0, 10.0, 100.0, 1000.0]
param_grid = [{'svc__C':param_range,
'svc__kernel':['linear']},
{'svc__C':param_range,
'svc__gamma':param_range,
'svc__kernel':['rbf']}]
gs = GridSearchCV(estimator = pipe_svc,
param_grid = param_grid,
scoring = 'accuracy',
cv = 10,
n_jobs = -1)
gs = gs.fit(X_train, y_train)
print(gs.best_score_)
print(gs.best_params_)
'''위에서 나온 최적의 parameter로 바로 학습가능'''
clf = gs.best_estimator_
clf.fit(X_train, y_train)
print(f"테스트 정확도 : {round(clf.score(X_test, y_test), 3)}")
Randomizedserach
- gridsearch의 계산 비용이 매우 크기 때문에 제한된 횟수 안에서 샘플링 분포로부터 랜덤한 매개변수 조합을 찾는다. (n_iter 매개변수를 통해 횟수를 설정할 수 있다.)
중첩 교차 검증 (nesting cross validation)
- Gridsearch와 kfold cv를 함께 사용하여 여러 종류의 머신러닝 알고리즘을 비교할 수 있다.
'''SVM'''
gs = GridSearchCV(estimator = pipe_svc,
param_grid = param_grid,
scoring = 'accuracy',
cv = 2)
scores = cross_val_score(gs, X_train, y_train,
scoring = 'accuracy', cv = 5)
print("cv 정확도 : ", np.mean(scores), np.std(scores))
'''Decision Tree'''
from sklearn.tree import DecisionTreeClassifier
gs = GridSearchCV(estimator = DecisionTreeClassifier(random_state = 0),
param_grid = [{'max_depth': [1, 2, 3, 4, 5, 6, 7, None]}],
scoring = 'accuracy',
cv = 2)
scores = cross_val_score(gs, X_train, y_train,
scoring = 'accuracy', cv = 5)
print("cv 정확도 : ", np.mean(scores), np.std(scores))
참고
머신러닝 교과서 (길벗)
'AI > Machine Learning' 카테고리의 다른 글
Ensemble (Voting, Bagging, Boosting) (0) | 2021.02.24 |
---|---|
Model evaluation metrics (0) | 2021.02.23 |
Model pipeline (0) | 2021.02.22 |
Regularization (0) | 2021.02.19 |
Random Forest (0) | 2021.02.19 |