교차검증(cross_val_score ), 하이퍼파라미터 (GridSearchCV, RandomizedSearchCV) 간단하게 이해하기
ㄱ데이터를 훈련/검증/테스트 세트로 나누어 평가를 하다보면 그 테스트 데이터에만 최적화된 과적합 학습 모델이 만들어집니다.
모의고사를 만점맞았는데 정작 수능은 저조한 평가를 받는다고 보면 쉽습니다.
이를 방지하기 위해 수능을 보기 전 여러번 모의고사를 치르는 방법을 생각할 수 있는데, 이를 교차검증이라고 합니다.
검증세트의 크기가 작은 경우에도 사용이 가능합니다.
K폴드 교차 검증( k-fold cross-validation(CV))
예를들어, 데이터를 3등분으로 나누고 검증(1/3)과 훈련세트(2/3)를 총 세번 바꾸어가며 검증하는 것은 3-fold CV 입니다.
교차검증 모델의 종류
- 일반 K 폴드 - 가장 보편적인 교차검증기법입니다.
- stratifiedKFold - 일반 K 폴드보다 stratifiedKFold가 불균형한 분포를 가진 분류 레이블 데이터에 사용이 가능합니다. (단, 회귀/시계열데이터는 연속값이므로 지원하지 않습니다.)
- cross_val_score - 폴드세트 추출, 학습/예측, 평가를 한번에 수행합니다. 교차검증을 보다 편리하게 수행할 수 있습니다.
교차검증세트 3개를 사용한 cross_val_score() 예시를 보도록 하겠습니다.
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score, cross_validate
from sklearn.datasets import load_iris
iris_data =load_iris()
dt_clf = DecisionTreeClassifier(random_state = 156)
data = iris_data.data
label = iris_data.target
# 성능 지표는 정확도(accuracy), 교차 검증세트는3개
scores = cross_val_score(dt_clf, data, label, scoring = 'accuracy', cv =3)
np.round(scores, 4) # 검증별 정확도
np.round(np.mean(scores),4) # 평균 검증 정확도
>>> 0.9804 0.9216 0.9792
0.9604
|
cs |
하이퍼파라미터 튜닝
머신러닝 모델을 만들때 중요한 이슈는 최적화(optimization)와 일반화(generalization) 입니다.
- 최적화는 훈련 데이터로 더 좋은 성능을 얻기 위해 모델을 조정하는 과정이며,
- 일반화는 학습된 모델이 처음 본 데이터에서 얼마나 좋은 성능을 내는지를 이야기 합니다.
GridSearchCV: 검증하고 싶은 하이퍼파라미터들의 수치를 정해주고 그 조합을 모두 검증합니다.
cv세트가 3이면 * 파라미터 순차적용횟수 6 = 18번
2 imputation n cols 3 alphas * 3 cv = 1386 tasks (너무 많습니다. 이런 경우 시간이 상대적으로 오래 걸립니다.)
Randomized Search CV: 검증하려는 하이퍼파라미터들의 값 범위를 지정해주면 무작위로 값을 지정해 그 조합을 모두 검증합니다.
n_iter(=50) * 3 교차검증 = 150 tasks
그리드서치 (GridSearchCV )
교차검증을 기반으로 최적 하이퍼파라미터 집합을 만들어 이를 순차적으로 적용하여 최적의 파라미터를 찾을 수 있습니다.
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.metrics import accuracy_score
# 데이터를 로딩하고 학습데이터와 테스트 데이터 분리
iris = load_iris()
X_train, X_test, y_train, y_test = train_test_split(iris_data.data, iris_data.target,
test_size=0.2, random_state=121)
dtree = DecisionTreeClassifier()
### parameter 들을 dictionary 형태로 설정
parameters = {'max_depth':[1, 2, 3], 'min_samples_split':[2,3]}
|
cs |
import pandas as pd
# param_grid의 하이퍼 파라미터들을 3개의 train, test set fold 로 나누어서 테스트 수행 설정
### refit=True 가 default 임. True이면 가장 좋은 파라미터 설정으로 재 학습 시킴
grid_dtree = GridSearchCV(dtree, param_grid=parameters, cv=3, refit=True, return_train_score=True)
# 붓꽃 Train 데이터로 param_grid의 하이퍼 파라미터들을 순차적으로 학습/평가
grid_dtree.fit(X_train, y_train)
# GridSearchCV 결과는 cv_results_ 라는 딕셔너리로 저장됨. 이를 DataFrame으로 변환
scores_df = pd.DataFrame(grid_dtree.cv_results_)
scores_df[['params', 'mean_test_score', 'rank_test_score',
'split0_test_score', 'split1_test_score', 'split2_test_score']]
|
cs |
print('GridSearchCV 최적 파라미터:', grid_dtree.best_params_)
print('GridSearchCV 최고 정확도: {0:.4f}'.format(grid_dtree.best_score_))
# refit=True로 설정된 GridSearchCV 객체가 fit()을 수행 시 학습이 완료된 Estimator를 내포하고 있으므로 predict()를 통해 예측도 가능.
pred = grid_dtree.predict(X_test)
print('테스트 데이터 세트 정확도: {0:.4f}'.format(accuracy_score(y_test,pred)))
|
cs |
>>>
GridSearchCV 최적 파라미터: {'max_depth': 3, 'min_samples_split': 2}
GridSearchCV 최고 정확도: 0.9667
테스트 데이터 세트 정확도: 0.9667
*잠깐!*
Estimator란 : 지도학습의 모든 알고리즘(classifier, Regressor 등)을 구현한 클래스로 fit()과 Predict() 과정이 이미 포함되어 있습니다. cross_val_score(), GridSearchCV.fit()함수 내에서 이미 이 Estimator의 fit()과 Predict()를 호출해서 평가하고있습니다.
# GridSearchCV의 refit으로 이미 학습이 된 estimator 반환
estimator = grid_dtree.best_estimator_
# GridSearchCV의 best_estimator_는 이미 최적 하이퍼 파라미터로 학습이 됨
pred = estimator.predict(X_test)
print('테스트 데이터 세트 정확도: {0:.4f}'.format(accuracy_score(y_test,pred)))
|
cs |
>>>
테스트 데이터 세트 정확도: 0.9667
Randomized Search CV
Ridge 회귀모델의 하이퍼파라미터를 튜닝해보겠습니다.
from sklearn.model_selection import RandomizedSearchCV
pipe = make_pipeline(
OneHotEncoder(use_cat_names=True)
, SimpleImputer()
, StandardScaler()
, SelectKBest(f_regression)
, Ridge()
)
# 튜닝할 하이퍼파라미터의 범위를 지정해 주는 부분
dists = {
'simpleimputer__strategy': ['mean', 'median'],
'selectkbest__k': range(1, len(X_train.columns)+1),
'ridge__alpha': [0.1, 1, 10],
}
clf = RandomizedSearchCV(
pipe,
param_distributions=dists,
n_iter=50,
cv=3,
scoring='neg_mean_absolute_error',
verbose=1,
n_jobs=-1
)
clf.fit(X_train, y_train);
|
cs |
>>>
Fitting 3 folds for each of 50 candidates, totalling 150 fits
print('최적 하이퍼파라미터: ', clf.best_params_)
print('MAE: ', -clf.best_score_)
|
cs |
>>>
최적 하이퍼파라미터: {'simpleimputer__strategy': 'median', 'selectkbest__k': 55, 'ridge__alpha': 10} MAE: 18414.633797820472
선형회귀, 랜덤포레스트 모델들의 튜닝 추천 하이퍼파라미터 입니다
Random Forest
class_weight (불균형(imbalanced) 클래스인 경우)
- max_depth (너무 깊어지면 과적합)
- n_estimators (적을경우 과소적합, 높을경우 긴 학습시간)
- min_samples_leaf (과적합일경우 높임)
- max_features (줄일 수록 다양한 트리생성)
Logistic Regression
- C (Inverse of regularization strength)
- class_weight (불균형 클래스인 경우)
- penalty
Ridge / Lasso Regression¶
- alpha