728x90
1. Model Selection
Scikit Learn 활용 ML 워크플로우
- Load Data: 데이터셋 준비
- Preprocessing: 데이터 전처리(fit, transform)
- Model Train: 모델 학습 (fit), 모델 활용 예측 (predict)
- Evaluation: 모델 성능 평가 (accuracy, precision, recall, f1, roc_auc)
Train Data Set (학습 데이터 세트)
- ML ALgorithm의 학습을 위해 사용
- Data의 Feature과 Target값(Label 값) 모두를 가지고 있음
- 학습 데이터를 기반으로 ML Algorithm이 데이터 Feature과 Target값(Label 값)의 패턴을 학습하고 결과를 추론
Test Data Set (테스트 데이터 세트)
- 테스트 데이터 세트에서 학습된 ML Algorithm을 테스트
- 테스트 데이터는 Feature Data Set만 ML Algorithm에 제공하며, ML Algorithm은 제공된 데이터를 기반으로 결정값을 예측
- Test Data는 Train Data와 별도의 Data Set으로 제공되어야 함
학습 데이터와 테스트 데이터의 분리 - train_test_split()
- sklearn.model_selection의 train_test_split() 함수
- X_train, X_test, y_train, y_test = train_test_split(iris_data.data, iris_data.target, test_size=0.3, random_state=121)
- test_size: 전체 데이터에서 테스트 데이터 세트 크기를 얼마로 샘플링할 것인가를 결정
- float: 0.0 ~ 1.0 사이의 값이며 전체 데이터에서 test 데이터의 비율을 의미
- int: test sample의 총 개수를 의미
- default는 0.25
- train_size: 전체 데이터에서 학습용 데이터 세트 크기를 얼마로 샘플링할 것인가를 결정
- test_size parameter를 통상적으로 사용하기 때문에 train_size는 잘 사용하지 않음
- shuffle: 데이터를 분리하기 전에 데이터를 미리 섞을지를 결정함
- default는 True
- 데이터를 분산시켜서 좀 더 효율적인 학습 및 test data set을 만드는데 사용됨
- random_state: random_state는 호출할 때마다 동일한 학습/데이터용 data set를 생성하기 위해 주어지는 난수 값
- train_test_split()은 호출 시 무작위로 데이터를 분리하므로 random_state를 지정하지 않으면 수행할 때마다 다른 학습/테스트용 데이터를 생성함
- stratify: stratify=y_labels로 설정하면 y_label(기존 데이터셋의 target 값) 의 Label 분포와 최대한 동일하게 y_train, y_test 각각 생성해준다
train_test_split()에서 사용되는 random_state 인자는 데이터를 train과 test 데이터 세트로 특정 비율로 분할 할때 random 하게 섞어서 분할을 하게 되는데, 이때 random 분할을 수행시 마다 동일하게 적용하기 위해서 random seed값을 random_state로 지정
학습 데이터셋으로 예측을 시키는 경우
- 분류 모델의 경우 train data로 predict를 시키면 모든 성능이 100%
- 회귀 모델의 경우 train data로 predict를 시키도 선형 회귀(단순, 일반/다중, 다항)는 모든 data point를 지날 수 없으므로 성능이 100%가 나올 수 없다
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
iris = load_iris()
dt_clf = DecisionTreeClassifier()
train_data = iris.data
train_label = iris.target
dt_clf.fit(train_data, train_label)
# 학습 데이터셋으로 예측 수행
pred = dt_clf.predict(train_data)
print("예측 정확도:", accuracy_score(train_label, pred))
# 예측 정확도: 1.0
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
dt_clf = DecisionTreeClassifier()
iris = load_iris()
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.3, random_state=121)
dt_clf.fit(X_train, y_train)
pred = dt_clf.predict(X_test)
print(f"예측 정확도: {accuracy_score(pred, y_test):.4f}")
# 예측 정확도: 0.9556
- ndarray 뿐만 아니라 pandas DataFrame/Series도 train_test_split()으로 분할 가능
import pandas as pd
iris_df = pd.DataFrame(iris.data, columns=iris.feature_names)
iris_df["target"] = iris.target
iris_df.head(3)
ftr_df = iris_df.iloc[:, :-1]
tgt_df = iris_df.iloc[:, -1]
X_train, X_test, y_train, y_test = train_test_split(
ftr_df, tgt_df, test_size=0.3, random_state=121
)
print(type(X_train), type(X_test), type(y_train), type(y_test))
# <class 'pandas.core.frame.DataFrame'> <class 'pandas.core.frame.DataFrame'> <class 'pandas.core.series.Series'> <class 'pandas.core.series.Series'>
dt_clf = DecisionTreeClassifier()
dt_clf.fit(X_train, y_train)
pred = dt_clf.predict(X_test)
print(f"예측 정확도: {accuracy_score(pred, y_test):.4f}")
# 예측 정확도: 0.9556
2. Cross-Validation (교차 검증)
Cross-Validation
- Train Data Set: 학습 데이터를 다시 분할하여 학습 데이터와 학습된 모델의 성능을 일차 평가하는 검증 데이터(일종의 Test Data)로 나눔 (모델을 개선시키기 위해 모델의 성능을 판단할 수 있는 지표가 필요)
- Test Data Set: 모든 학습/검증 과정이 완료된 후 최종적으로 성능을 평가하기 위한 데이터 세트
- WHY?
- 만약 검증 데이터가 고정이 있으면 정확도가 더 높은 모델을 그 검정 데이터에 대해 더 적합할 뿐 전체 데이터에 대해 더 적합한지는 판단할 수 없음
- 편향된 데이터가 아닌 일반화된 데이터에 대한 성능을 측정할 방법이 요구됨
- Solution으로 교차 검증, 여러 세트로 구성된 학습 데이터 세트와 검증 데이터 세트에서 학습과 평가가 이루어짐
K-Fold Cross-Validation
- Train Data Set을 비슷한 크기의 k개의 Fold으로 구분
- 각 fold set별로 검증 데이터를 달리 하며 학습과 검증을 반복적으로 수행하는 방법
- k-1개의 Group을 train, 1개의 Group을 validation에 사용
- Train : model parameter를 fitting하는데 사용
- Validation : model optimization하는데 사용
기본 K-Fold Cross-Validation Code
# 3개 k-fold방식 적용
kf = KFold(n_splits=3)
# X_train을 다시 학습과 검증용 데이터로 분리
for tr_index, val_index in kf.split(X_train):
# kf.split(X_train)으로 추출된 학습과 검증 index값으로 학습과 검증 데이터 세트 분리
X_tr, y_tr = X_train.iloc[tr_index], y_train.iloc[tr_index]
X_val, y_val = X_train.iloc[val_index], y_train.iloc[val_index]
실습 Code
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
from sklearn.model_selection import KFold
import numpy as np
iris = load_iris()
features = iris.data
label = iris.target
dt_clf = DecisionTreeClassifier()
# 5개의 fold set으로 분리하는 KFold 객체와 Fold 세트별 정확도를 담을 리스트를 생성
kfold = KFold(n_splits=5)
cv_accuracy = []
print(f"붓꽃 데이터 세트 크기: {features.shape[0]}")
# 붓꽃 데이터 세트 크기: 150
Label(1차원)과 features(2차원)는 모두 ndarray이다
- KFold 객체의 split(X(Feature))을 호출하여 train용, validation_test용 data의 row_index를 반환
- 반환한 Index를 Fancy Indexing을 통해 ndarray인 label과 feature에 적용
print(type(features), type(label))
# <class 'numpy.ndarray'> <class 'numpy.ndarray'>
n_iter = 0
# KFold 객체의 split() 호출하면 fold별 학습용, 검증용_테스트의 row_index를 array로 반환
for train_index, test_index in kfold.split(features):
# kfold.split()으로 반환된 인덱스를 이용하여 학습용, 검증용 test data 추출
X_train, X_test = features[train_index], features[test_index]
y_train, y_test = label[train_index], label[test_index]
# 학습 및 예측
dt_clf.fit(X_train, y_train)
pred = dt_clf.predict(X_test)
n_iter += 1
# 반복 시 마다 정확도 측정
accuracy = np.round(accuracy_score(pred, y_test), 4)
train_size = X_train.shape[0]
test_size = X_test.shape[0]
print(
f"\n#{n_iter} 교차 검증 정확도 :{accuracy}, 학습 데이터 크기 :{train_size}, 검증 데이터 크기 :{test_size}"
)
print(f"#{n_iter} 검증 세트 인덱스:{test_index}")
cv_accuracy.append(accuracy)
# 개별 iteration별 정확도를 합하여 평균 정확도 계산
print(f"\n## 평균 검증 정확도: {np.mean(cv_accuracy)}")
#1 교차 검증 정확도 :1.0, 학습 데이터 크기 :120, 검증 데이터 크기 :30
#1 검증 세트 인덱스:[ 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]
#2 교차 검증 정확도 :1.0, 학습 데이터 크기 :120, 검증 데이터 크기 :30
#2 검증 세트 인덱스:[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]
#3 교차 검증 정확도 :0.9, 학습 데이터 크기 :120, 검증 데이터 크기 :30
#3 검증 세트 인덱스:[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]
#4 교차 검증 정확도 :0.9333, 학습 데이터 크기 :120, 검증 데이터 크기 :30
#4 검증 세트 인덱스:[ 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]
#5 교차 검증 정확도 :0.7333, 학습 데이터 크기 :120, 검증 데이터 크기 :30
#5 검증 세트 인덱스:[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]
## 평균 검증 정확도: 0.909995
Stratified(계층화된) K-Fold
- imbalanced(불균형한) 분포도를 가진 Label(결정 Class) Data Set을 위한 K-Fold 방식
- WHY?
- K-Fold 교차 검증 과정에서 랜덤하게 k개의 데이터 세트를 고르다보니 검증 데이터 세트별 학습되는 정확도가 크게 달라지게 됨
- 원본 데이터와 유사한 Label 분포를 학습/검증 데이터 세트에도 유지하는 것이 요구됨
- 학습 데이터와 검증 데이터 세트가 가지는 Label 분포도가 원본 Label 분포도와 유사하도록 데이터 추출
- 원본 Label 데이터를 추가로 입력받아 원본 데이터의 Label 분포를 고려한 뒤 해당 분포와 동일하게 학습/검증 데이터 세트를 분배
- Classification에 사용, Regression은 사용 불가능(연속이므로)
K-Fold CV에 관한 고찰
모델을 평가하는데 있어서 가장 좋은 K값은 무엇인가?
- K값이 커지면 bias가 감소하고 variance가 커지면서 computational cost가 증가
- K값이 작아지면 bias가 증가하고 variance가 감소하면서 computational cost가 감소
import pandas as pd
iris = load_iris()
iris_df = pd.DataFrame(iris.data, columns=iris.feature_names)
iris_df["label"] = iris.target
iris_df["label"].value_counts()
# 0 50
# 1 50
# 2 50
# Name: label, dtype: int64
kfold.split(X(Feature))
- X가 2차원 ndarray 형태로 들어가야 한다
- 학습 Label에 있는 data 분포와 검증 Label에 있는 data 분포가 무관함: 예측이 불가능함
kfold = KFold(n_splits=3)
# kfold.split(X)는 fold set를 3번 반복할 때마다 달라지는 학습/테스트 용 데이터 row_index 번호 반환
n_iter = 0
for train_index, test_index in kfold.split(iris_df):
n_iter += 1
label_train = iris_df["label"].iloc[train_index]
label_test = iris_df["label"].iloc[test_index]
print(f"## 교차 검증: {n_iter}")
print(f"학습 레이블 데이터 분포:\n {label_train.value_counts()}")
print(f"검증 레이블 데이터 분포:\n {label_test.value_counts()}")
# ## 교차 검증: 1
# 학습 레이블 데이터 분포:
# 1 50
# 2 50
# Name: label, dtype: int64
# 검증 레이블 데이터 분포:
# 0 50
# Name: label, dtype: int64
# ## 교차 검증: 2
# 학습 레이블 데이터 분포:
# 0 50
# 2 50
# Name: label, dtype: int64
# 검증 레이블 데이터 분포:
# 1 50
# Name: label, dtype: int64
# ## 교차 검증: 3
# 학습 레이블 데이터 분포:
# 0 50
# 1 50
# Name: label, dtype: int64
# 검증 레이블 데이터 분포:
# 2 50
# Name: label, dtype: int64
Stratified K-Fold 이용
skf.split(X(feature), y(label))
- 반드시 parameter가 2개 들어가야 함
- X가 2차원 ndarray, y가 1차원 ndarray 형태로 들어가야 한다
- X: Feature Data Set
- y: imbalanced(불균형한) 분포도를 가진 Label(결정 Class) Data Set
from sklearn.model_selection import StratifiedKFold
skf = StratifiedKFold(n_splits=3)
n_iter = 0
for train_index, test_index in skf.split(iris_df, iris_df["label"]):
n_iter += 1
label_train = iris_df["label"].iloc[train_index]
label_test = iris_df["label"].iloc[test_index]
print(f"## 교차 검증: {n_iter}")
print(f"학습 레이블 데이터 분포:\n {label_train.value_counts()}")
print(f"검증 레이블 데이터 분포:\n {label_test.value_counts()}")
# ## 교차 검증: 1
# 학습 레이블 데이터 분포:
# 2 34
# 0 33
# 1 33
# Name: label, dtype: int64
# 검증 레이블 데이터 분포:
# 0 17
# 1 17
# 2 16
# Name: label, dtype: int64
# ## 교차 검증: 2
# 학습 레이블 데이터 분포:
# 1 34
# 0 33
# 2 33
# Name: label, dtype: int64
# 검증 레이블 데이터 분포:
# 0 17
# 2 17
# 1 16
# Name: label, dtype: int64
# ## 교차 검증: 3
# 학습 레이블 데이터 분포:
# 0 34
# 1 33
# 2 33
# Name: label, dtype: int64
# 검증 레이블 데이터 분포:
# 1 17
# 2 17
# 0 16
# Name: label, dtype: int64
dt_clf = DecisionTreeClassifier(random_state=156)
skfold = StratifiedKFold(n_splits=3)
n_iter=0
cv_accuracy=[]
# StratifiedKFold의 split( ) 호출시 반드시 레이블 데이터 셋도 추가 입력 필요
for train_index, test_index in skfold.split(features, label):
# split( )으로 반환된 인덱스를 이용하여 학습용, 검증용 테스트 데이터 추출
X_train, X_test = features[train_index], features[test_index]
y_train, y_test = label[train_index], label[test_index]
#학습 및 예측
dt_clf.fit(X_train , y_train)
pred = dt_clf.predict(X_test)
# 반복 시 마다 정확도 측정
n_iter += 1
accuracy = np.round(accuracy_score(y_test,pred), 4)
train_size = X_train.shape[0]
test_size = X_test.shape[0]
print('\n#{0} 교차 검증 정확도 :{1}, 학습 데이터 크기: {2}, 검증 데이터 크기: {3}'
.format(n_iter, accuracy, train_size, test_size))
print('#{0} 검증 세트 인덱스:{1}'.format(n_iter,test_index))
cv_accuracy.append(accuracy)
# 교차 검증별 정확도 및 평균 정확도 계산
print('\n## 교차 검증별 정확도:', np.round(cv_accuracy, 4))
print('## 평균 검증 정확도:', np.mean(cv_accuracy))
#1 교차 검증 정확도 :0.98, 학습 데이터 크기: 100, 검증 데이터 크기: 50
#1 검증 세트 인덱스:[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 50
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 100 101
102 103 104 105 106 107 108 109 110 111 112 113 114 115]
#2 교차 검증 정확도 :0.94, 학습 데이터 크기: 100, 검증 데이터 크기: 50
#2 검증 세트 인덱스:[ 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 67
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 116 117 118
119 120 121 122 123 124 125 126 127 128 129 130 131 132]
#3 교차 검증 정확도 :0.98, 학습 데이터 크기: 100, 검증 데이터 크기: 50
#3 검증 세트 인덱스:[ 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 83 84
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 133 134 135
136 137 138 139 140 141 142 143 144 145 146 147 148 149]
## 교차 검증별 정확도: [0.98 0.94 0.98]
## 평균 검증 정확도: 0.9666666666666667
3. Cross Validation API
KFold Class를 이용한 교차 검증 방법
Fold Set 추출 -> 학습/테스트 데이터 추출 -> 학습/예측/평가 반복
- Fold Set 설정: KFold(n_split)
- for 루프에서 반복적으로 학습/검증 데이터 추출 및 학습과 예측 수행: for train_index, test_index in kfold.split()
- Fold Set 별로 예측 성능을 평균하여 최종 성능 평가
cross_val_score(estimator, X_train, y_train, scoring, cv)
- 교차 검증을 보다 간편하게 해주는 함수
- Fold Set 추출 -> 학습/테스트 데이터 추출 -> 학습/예측/평가 반복 를 한번에 수행
- X가 2차원 ndarray, y가 1차원 ndarray 형태로 들어가야 한다
- 각 Fold set의 정확도를 ndarray 형태로 반환
- cross_val_score(estimator, X(Features), y(label)=None, scoring=None, cv=None, n_jobs=1, verbose=0, fit_params=None, pre_dispatch='2*n_jobs')
- estimator: 알고리즘 클래스 (regressor: Kfold, classifier: stratified Kfold)
- X: Train_Feature Data Set, y: Train_label data set
- scoring: 예측 성능 평가함수
- 분류 모델: accuracy, recall, precision
- 회귀 모델: MSE, RMSE, MAE
- verbose
- 함수 인자로 verbose가 있으면 함수 수행시 발생하는 상세한 정보들을 표준 출력으로 자세히 내보낼 것인가를 나타냄
- 보통 0 은 출력하지 않고, 1은 자세히, 2는 함축적인 정보만 출력하는 형태로 되어 있음
- cv: Fold의 Set 개수
- Stratified K-fold 사용: target 값의 학습 데이터와 검증 데이터의 분포도가 원본 데이터 Label 분포도와 동일하게 나오도록 추출
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_iris
import numpy as np
iris = load_iris()
dt_clf = DecisionTreeClassifier(random_state=156)
data = iris.data
label = iris.target
# 성능 지표는 정확도(accuracy), 교차 검증 세트는 3개
scores = cross_val_score(dt_clf, data, label, scoring="accuracy", cv=3)
# print(scores, type(scores))
print(f"교차 검증별 정확도: {np.round(scores,4)}")
print(f"평균 검증 정확도: {np.round(np.mean(scores),4)}")
# 교차 검증별 정확도: [0.98 0.94 0.98]
# 평균 검증 정확도: 0.9667
4. Hyperparameter Optimization
Hyper Parameter VS Learnable Parameter
- Hyper parameter: 경험, 데이터의 특성 등에 근거해 사용자가 설정한 사전에 정의된 parameter (update X)
- max_depth, min_samples_split
- Learnable parameter: 모델 내부에 존재하여 알고리즘을 통해 자동적으로 학습하고자 하는 parameter (update O)
- 회귀 모델의 계수
GridSearchCV(estimator, param_grid, scoring, cv, refit, return_train_score)
교차 검증과 최적 하이퍼 파라미터 튜닝을 한번에 해서 Model 의 학습(fit)을 수행
이후 .best_estimator_를 이용하여 Model의 활용 예측 / 예측 성능 평가 수행
GridSearchCV 객체 만든 후 fit() 수행!!
- GridSearchCV
- param_grid: Hyperparameter 명
- Dict 형태로 Key에 Parameter 이름, Value에 Parameter 후보 값들을 list로 Setting
- refit: True이면 가장 좋은 parameter 설정으로 재학습시킴
- estimator: 알고리즘 클래스
- scoring: 예측 성능 평가함수 - Test Data가 아니라 Validation Data에 적용하여 성능 도출
- 분류 모델: accuracy, recall, precision
- 회귀 모델: MSE, RMSE, MAE
- GridSearchCV에서 scoring을 지정하지 않으면 기본으로 accuracy를 기반으로 평가
- cv: Fold의 set 개수
- n_jobs: 'None'이 default인데 CPU 1 Core만 쓰겠다는 뜻, n_jobs=-1일 경우 CPU의 모든 Processor를 사용한다는 뜻
- n_jobs=-1일 경우 모든 CPU의 Core를 다 쓰기 때문에 다른 작업을 하고 있을 경우 컴퓨터가 느려진다
- verbose
- 함수 인자로 verbose가 있으면 함수 수행시 발생하는 상세한 정보들을 표준 출력으로 자세히 내보낼 것인가를 나타냄
- 보통 0 은 출력하지 않고, 1은 자세히, 2는 함축적인 정보만 출력하는 형태로 되어 있음
- GridSearchCV를 이용해 Classifier이나 Regressor와 같은 알고리즘에 사용되는 Hyper Parameter를 순차적으로 입력하면서 편리하게 최적의 Parameter를 도출할 수 있는 방안을 제공
- Hyper Parameter: ML의 개별적인 모델을 알고리즘적으로 튜닝하는 최적의 parameter
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_tets = train_test_split(
iris.data, iris.target, test_size=0.2, random_state=121
)
dtree = DecisionTreeClassifier()
### parameter 들을 dictionary 형태로 설정
parameters = {"max_depth": [1, 2, 3], "min_samples_split": [2, 3]}
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",
]
]
- grid_dtree.best_parmas_: 최적의 parameter 조합
- grid_dtree.best_score_: 최적의 성능
- 검증 Data Set (Validation Data set)에 적용하여 나온 최적의 성능이다: Test Data Set이 아니다
- GridSearchCV에서 scoring을 지정하지 않으면 기본으로 accuracy를 기반으로 평가
- GridSearchCV는 refit option을 줬기 때문에 학습이 완료된 Estimator를 내포하고 있음: 최적의 parameter를 찾아내고 해당 hyper parameter로 학습함 -> predict 가능
- grid_dtree.best_estimator_: GridSearchCV의 refit으로 이미 학습이 된(fit 완료) estimator 반환
- predict 이후 Test Data로 예측 성능 평가
print("GridSearchCV 최적 파라미터:", grid_dtree.best_params_)
print(f"GridSearchCV 최적 정확도: {grid_dtree.best_score_:.4f}")
# refit=True로 설정된 GridSearchCV 객체가 fit()을 수행 시 학습이 완료된 Estimator를 내포하고 있으므로 predict()를 통해 예측도 가능.
pred = grid_dtree.predict(X_test)
print(f"테스트 데이터 세트 정확도: {accuracy_score(y_test, pred):.4f}")
# GridSearchCV 최적 파라미터: {'max_depth': 3, 'min_samples_split': 2}
# GridSearchCV 최적 정확도: 0.9750
# 테스트 데이터 세트 정확도: 0.9667
# 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)))
# 테스트 데이터 세트 정확도: 0.9667
Grid Search VS Random Search
Grid Search
- 모든 parameter로 학습 진행
- 시간이 오래걸림
Random Search
- 정해진 격자 사이 값을 확률적으로 탐색
- 데이터가 많을 때 효과적
5. cross_val_score VS GridSearchCV
cross_val_score
- cross_val_score()는 StratifiedFold 방식으로 validation 데이터 세트를 분할 해서 학습하여 예측 한 뒤 evaluation 값만 반환합니다.
- 때문에 evaluation값만 반환하여 아주 간편하게 사용될 수 있습니다.
- 다만 반환하는 것이 학습된 모델이 아니라 evaluation값 뿐이기 때문에 추가적인 활용이 어려울 수는 있습니다.
GridSearchCV
- GridSearchCV는 다양한 하이퍼 파라미터 값을 입력해서 최적의 학습 모델을 찾아 줍니다.
- 최적의 하이퍼 파라미터 뿐만 아니라 최적 학습 모델도 반환 할 수 있습니다.
cross_val_score():
간단하게 validation 데이터 세트들의 평균 evaluation 결과값만 간단하게 받아 볼 필요가 있을 때만 활용
GridSearchCV():
validation 데이터 세트를 기반으로 evaluation 값이 가장 높은 하이퍼 파라미터 찾고 + 해당 하이퍼 파라미터로 튜닝한 학습된 모델 반환
728x90