[ML] 교차 검증(Cross Validation) 및 GridSearchCV 정리
❖교차 검증이란?
데이터를 내가 원하는 k개 만큼 부분집합으로 만들어주고, 그 k개로 나누어진 데이터들을 학습과 데이터 셋을 한 fold씩 이동하며,
한 fold에 머물지 않고, 여러번 교차해 검증하는 것이다.
→왜 사용하는가?
알고리즘을 학습 시키는 과정에서 학습 데이터와 테스트 데이터를 나누어 진행하게 된다.
학습 데이터와 테스트 데이터를 일정 비율로 나누어 진행하는데, 만약 8:2 의 비율로 학습 데이터와 테스트 데이터로 나누게 된다면,
학습 데이터에게만 최적화 된 모델 성능을 보여, 예측을 진행할때 현저히 떨어지는 경우가 발생할 수 있다.
또한, 이러한 과정은 테스트 데이터로 편향된 성능 개선이 이루어 질 수 있게 된다.
(고정된 학습 데이터와 테스트 데이터로 성능을 평가하고 있기 떄문에 테스트 데이터로 예측한 정확도를 개선하려는 과정이 만들어지는 것)
이러한 단점을 개선할 수 있는 방법이 '교차 검증' 이다.
특정 테스트 데이터에 편향된 성능 개선을 막을 수 있으며, Overfiting 또한 방지할 수 있음
▹ K-fold
나누어진 Train Data_set과 Test_set을 편향된 성능 향상을 방지하기 위해, k개의 fold로 나누어 학습을 진행
즉, 4/5를 Train Data_set , 1/5를 Test Data_set으로 fold를 한칸씩 이동하며, 여러번 k번만큼 학습을 진행한다.
▹ Stratified K-fold
'불균형(Imbalanced) 분포도를 가진 labels데이터 집합을 위한 K-fold 방식'
가령, 20대 남성의 암 여부에 대한 데이터의 경우 건강한 경우의 labels 데이터의 분포가 그렇지 않은 경우의 labels보다
압도적으로 많을 것 이다.
이 경우에는 Train Data와 Test Data로 나누어 학습하고 예측했을 경우 제대로 된 예측이 진행되지 않을 확률이 매우 높다.
즉, 특정 labels 값이 학습 데이터에 아예 포함이 안되어 있거나 비율적으로 매우 적게 들어갈 경우 모델 학습에 큰 문제가 발생
Stratified k-fold 방식은 위와 같은 경우 학습 데이터와 테스트 데이터를 제대로 분배할 수 있도록 도와주는 방식
[붓꽃 데이터 세트로 k-fold 진행]
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.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
dt_clf = DecisionTreeClassifier( )
iris_data = load_iris()
X_train, X_test,y_train, y_test= train_test_split(iris_data.data, iris_data.target,
test_size=0.3, random_state=121)
dt_clf.fit(X_train, y_train)
pred = dt_clf.predict(X_test)
print('예측 정확도: {0:.4f}'.format(accuracy_score(y_test,pred)))
예측 정확도: 0.9556
넘파이 ndarray 뿐만 아니라 판다스 DataFrame/Series도 train_test_split( )으로 분할 가능
import pandas as pd
iris_df = pd.DataFrame(iris_data.data, columns=iris_data.feature_names)
iris_df['target']=iris_data.target
iris_df.head()
sepal length (cm) | sepal width (cm) | petal length (cm) | petal width (cm) | target | |
---|---|---|---|---|---|
0 | 5.1 | 3.5 | 1.4 | 0.2 | 0 |
1 | 4.9 | 3.0 | 1.4 | 0.2 | 0 |
2 | 4.7 | 3.2 | 1.3 | 0.2 | 0 |
3 | 4.6 | 3.1 | 1.5 | 0.2 | 0 |
4 | 5.0 | 3.6 | 1.4 | 0.2 | 0 |
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)
dt_clf = DecisionTreeClassifier( )
dt_clf.fit(X_train, y_train)
pred = dt_clf.predict(X_test)
print('예측 정확도: {0:.4f}'.format(accuracy_score(y_test,pred)))
예측 정확도: 0.9556
DecisionTreeClassifier 알고리즘을 이용하여 학습, 예측을 진행한 경우 위와 같은 결과가 나옴
[K-fold 방식을 이용하여 학습, 예측 진행]
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(random_state=156)
# 5개의 폴드 세트로 분리하는 KFold 객체와 폴드 세트별 정확도를 담을 리스트 객체 생성.
kfold = KFold(n_splits=5)
cv_accuracy = []
print('붓꽃 데이터 세트 크기:',features.shape[0])
붓꽃 데이터 세트 크기: 150
n_iter = 0
# KFold객체의 split( ) 호출하면 폴드 별 학습용, 검증용 테스트의 로우 인덱스를 array로 반환
for train_index, test_index in kfold.split(features):
# kfold.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)
# 개별 iteration별 정확도를 합하여 평균 정확도 계산
print('\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]
[ 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]
#2 교차 검증 정확도 :0.9667, 학습 데이터 크기: 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]
[ 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 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]
#3 교차 검증 정확도 :0.8667, 학습 데이터 크기: 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]
[ 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 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 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]
#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]
[ 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 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
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]
#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 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 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]
## 평균 검증 정확도: 0.9
일반적인 K-fold를 이용하여 진행했을 경우 0.9 정확도가 나옴, 이전과 다소 떨어진 정확도를 보이고 있음
[Stratified K-fold 방식을 이용하여 학습, 예측 진행]
import pandas as pd
iris = load_iris()
iris_df = pd.DataFrame(data=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 = KFold(n_splits=3)
# kfold.split(X)는 폴드 세트를 3번 반복할 때마다 달라지는 학습/테스트 용 데이터 로우 인덱스 번호 반환.
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('## 교차 검증: {0}'.format(n_iter))
print('학습 레이블 데이터 분포:\n', label_train.value_counts())
print('검증 레이블 데이터 분포:\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
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('## 교차 검증: {0}'.format(n_iter))
print('학습 레이블 데이터 분포:\n', label_train.value_counts())
print('검증 레이블 데이터 분포:\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
StratifiedFold 방식을 이용했을 경우 0.9666..으로 K-fold방식보다 다소 높은정확도를 보이고 있고,
교차 검증 방식을 이용하기 전보다 다소 높은 정확도를 보여주고 있음
☑︎Cheak
- 일반적인 k-fold 방식은 폴드별 레이블 개수가 다 다름 / 반대로 Stratified 방식은 폴드별 레이블 개수가 동일하며, 세가지 레이블에 상응하는
데이터를 고루 학습하고 있음을 확인할 수 있음 - 일반적인 k-fold 방식은 분활 과정에서 labels 데이터 값을 넣어주지 않지만, Stratified K-fold 방식을 이용할 경우에는
반드시 labels 데이터 값을 넣어주어야함
▹ Cross_val_score
Cross_val_score는 위 같은 경우 학습 알고리즘을 이용하여, K개의 fold로 나누어 그것을 각각 for문을 활용하여
정확도를 구했는데, 이 모든 것을 한번에 해줄 수 있는 방식이다.
원하는 학습 알고리즘 객체와 Data를 넣어주고, 원하는 fold개수 만큼 cv에 넣어주면,
한줄 코드로 위에서 진행했던 부분들이 가능하다.
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_iris
import numpy as np
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)
#print(scores, type(scores))
print('교차 검증별 정확도:',np.round(scores, 4))
print('평균 검증 정확도:', np.round(np.mean(scores), 4))
[0.98 0.94 0.98] <class 'numpy.ndarray'>
교차 검증별 정확도: [0.98 0.94 0.98]
평균 검증 정확도: 0.9667
▹ GridSearchCV
Gridsearch(격차 탐색)은 모델 하이퍼 파라미터를 통해 best score를 낼 수 있도록 튜닝을 손쉽게 할 수 진행할 수 있다.
즉, Gridsearch 방식을 이용하는 이유는 가장 우수한 성능을 보이는 모델의 하이퍼 파라미터를 찾기 위해서
모든 경우의 수를 원하는 만큼 입력하고 가장 성능 좋은 best 파라미터를 뽑아내는 것
트리뿐만 아니라 앙상블과 같은 알고리즘에서 또한, 다방면으로 사용가능함
여기서의 CV 또한 Stratifited 방식으로 교차 검증을 진행한다.
하이퍼파라미터 튜닝시 주의사항!
파라미터를 설정해줄 때, 반드시 {} 튜플 형식으로 감싸주고, value 값들은 무조건 [] list 형태로 들어가줘야한다. 또한, cv(fold 개수) 같은 경우는 통상 원하는 만큼 설정 5-10회가 일반적이고, refit = True로 해줄 경우 bestprameters를 찾아서 알아서 그 파라미터로 적용해주고 우리는 그것을 fit만 시켜주면된다.
GridSearchCv() 주요 파라미터
- estimator - estimator object
- param_grid - searching하고자 하는 하이퍼 파라미터로 딕셔너리 형태
- scoring - 테스트 세트에서 교차 검증된 모델의 성능을 평하기 위한 지표
- n_jobs - 병렬 처리하기 위한 job의 수
- refit - 전체 데이터 세트에서 가장 성능이 좋은 bestprameters를 찾아서 해당 파라미터로 적용하여 재적
- cv - 교차 검증을 위한 데이터 세트 수 설정
- 이외 파라미터는 잘 사용하지 않음 (필요한 경우 사이킷런 홈페이지 참고)
GridSearchCV의 장단점
GridSearchCV는 몇줄의 코드로 여러경우의 수를 확인할 수 있고, 우수한 성능을 뽑아낼 수 있다.
또한, 트리 모델과 같은 학습 알고리즘을 사용할 경우 max_depth나 min_sample_spilt과 같은
과적합을 최소화할 수 있는 경우를 찾아낼 수 있다.
**하지만, 내가 하이퍼 파라미터를 튜닝하는 만큼, 그 경우의 수 만큼 수행 시간이 오래걸린다는 것을
유의해야함
☑︎Cheak
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]}
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']]
params | mean_test_score | rank_test_score | split0_test_score | split1_test_score | split2_test_score | |
---|---|---|---|---|---|---|
0 | {'max_depth': 1, 'min_samples_split': 2} | 0.700000 | 5 | 0.700 | 0.7 | 0.70 |
1 | {'max_depth': 1, 'min_samples_split': 3} | 0.700000 | 5 | 0.700 | 0.7 | 0.70 |
2 | {'max_depth': 2, 'min_samples_split': 2} | 0.958333 | 3 | 0.925 | 1.0 | 0.95 |
3 | {'max_depth': 2, 'min_samples_split': 3} | 0.958333 | 3 | 0.925 | 1.0 | 0.95 |
4 | {'max_depth': 3, 'min_samples_split': 2} | 0.975000 | 1 | 0.975 | 1.0 | 0.95 |
5 | {'max_depth': 3, 'min_samples_split': 3} | 0.975000 | 1 | 0.975 | 1.0 | 0.95 |
grid_dtree.cv_results_
{'mean_fit_time': array([0.00033339, 0. , 0.00050179, 0. , 0. ,
0. ]),
'std_fit_time': array([0.00047148, 0. , 0.00040443, 0. , 0. ,
0. ]),
'mean_score_time': array([0.00023373, 0. , 0. , 0.00016761, 0. ,
0. ]),
'std_score_time': array([0.00033054, 0. , 0. , 0.00023703, 0. ,
0. ]),
'param_max_depth': masked_array(data=[1, 1, 2, 2, 3, 3],
mask=[False, False, False, False, False, False],
fill_value='?',
dtype=object),
'param_min_samples_split': masked_array(data=[2, 3, 2, 3, 2, 3],
mask=[False, False, False, False, False, False],
fill_value='?',
dtype=object),
'params': [{'max_depth': 1, 'min_samples_split': 2},
{'max_depth': 1, 'min_samples_split': 3},
{'max_depth': 2, 'min_samples_split': 2},
{'max_depth': 2, 'min_samples_split': 3},
{'max_depth': 3, 'min_samples_split': 2},
{'max_depth': 3, 'min_samples_split': 3}],
'split0_test_score': array([0.7 , 0.7 , 0.925, 0.925, 0.975, 0.975]),
'split1_test_score': array([0.7, 0.7, 1. , 1. , 1. , 1. ]),
'split2_test_score': array([0.7 , 0.7 , 0.95, 0.95, 0.95, 0.95]),
'mean_test_score': array([0.7 , 0.7 , 0.95833333, 0.95833333, 0.975 ,
0.975 ]),
'std_test_score': array([1.11022302e-16, 1.11022302e-16, 3.11804782e-02, 3.11804782e-02,
2.04124145e-02, 2.04124145e-02]),
'rank_test_score': array([5, 5, 3, 3, 1, 1]),
'split0_train_score': array([0.7 , 0.7 , 0.975 , 0.975 , 0.9875, 0.9875]),
'split1_train_score': array([0.7 , 0.7 , 0.9375, 0.9375, 0.9625, 0.9625]),
'split2_train_score': array([0.7 , 0.7 , 0.9625, 0.9625, 0.9875, 0.9875]),
'mean_train_score': array([0.7 , 0.7 , 0.95833333, 0.95833333, 0.97916667,
0.97916667]),
'std_train_score': array([1.11022302e-16, 1.11022302e-16, 1.55902391e-02, 1.55902391e-02,
1.17851130e-02, 1.17851130e-02])}
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)))
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
GridSearch방식을 이용하여 진행했을 경우 하이퍼 파라미터를 어떻게 조절하느냐에 따라 성능의 차이가 발생할 수 있음
[참고]
파이썬 머신러닝 완벽 가이드