Python 데이터 분석
Python 데이터분석 기초 59 - 일반화 모델을 위한 과적합 방지 방법
코딩탕탕
2022. 11. 21. 13:17
1. train/test split 방법
2. Validation = train data를 쪼개 학습과 검정을 같이한다. 교차검증(cross validation) - train/test split을 해도 과적합 발생 또는 데이터의 양이 적은 경우
3. GridSearchCV = 최적의 모델을 찾아준다.
'''
일반화 모델을 위한 과적합 방지 방법
iris dataset을 사용
train/test split, KFold, GridSearchCV
'''
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
iris=load_iris()
print(iris.keys())
train_data=iris.data
train_label=iris.target
print(train_data[:3])
print(train_label[:3])
print('분류 모델')
dt_clf=DecisionTreeClassifier()
print(dt_clf)
dt_clf.fit(train_data, train_label)
dt_clf.fit(train_data, train_label)
pred=dt_clf.predict(train_data)
print('예측값 : ', pred)
print('실제값 : ', train_label)
print('예측 정확도 : ', accuracy_score(train_label, pred))
# 1.0은 뭔가 이상하다, 과적합
print('\n과적합 방지 방법1 : train/test split')
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.3, random_state=121)
print(x_train.shape, x_test.shape, y_train.shape, y_test.shape)
print(x_train[:5])
print(iris.data[:5])
dt_clf.fit(x_train, y_train) #트레인 데이터로 학습
pred2=dt_clf.predict(x_test) #테스트 데이터로 검정
print('예측값 : ', pred2)
print('실제값 : ', y_test)
print('예측 정확도 : ', accuracy_score(y_test, pred2))
# 예측 정확도 : 0.955555555555
# 100% 가 되지 않도록 처리함, 모델의 포용성을 위해
# 100%이면 자신의 정확하게 학습한 데이터만 인식하기 때문에
# 조금 달라도 맞다고 하는 것이다.
print('"추론통계는 모든 환경에서 100%가 되어서는 안된다."라는 철학을 이해하자')
'''
https://modern-manual.tistory.com/19
train 데이터에 대해서 validation을 쓰는 것이다.
https://www.incodom.kr/k-%EA%B2%B9_%EA%B5%90%EC%B0%A8_%EA%B2%80%EC%A6%9D#:~:text=%EA%B5%90%EC%B0%A8%20%EA%B2%80%EC%A6%9D%EC%9D%B4%EB%9E%80%20%EC%89%BD%EA%B2%8C%20%EB%A7%90%ED%95%B4,%EC%96%BB%EC%9D%84%20%EC%88%98%20%EC%9E%88%EA%B8%B0%20%EB%95%8C%EB%AC%B8%EC%9D%B4%EB%8B%A4.
k-fold cross-validation(k-겹 교차 검증)
-> k는 몇 개로 접어서 1개의 validation fold 와 k-1개의traing으로 나눠서
비교해서 돌면서 해당 퍼포먼스의 전체 평균을 구해서 사용한다
'''
print('\n과적합 방지 방법2 : 교차검증(cross validation) - train/test split을 해도 과적합 발생 또는 데이터의 양이 적은 경우')
#모델 학습 도중 train data를 쪼개 validation data를 만든 후 학습시 검증을 함께 함
#K-fold 교차검증 : train data를 k개 접어 validation data로 사용
from sklearn.model_selection import KFold
import numpy as np
features = iris.data
label = iris.target
dt_clf = DecisionTreeClassifier(criterion='entropy', random_state=123)
kfold=KFold(n_splits = 5)
cv_acc = []
print('iris shape : ', features.shape)
#iris shape : (150, 4)
# 전체 행수 : 150, 학습데이터 : 4/5 ,120개, 검증 데이터 : 1/5, 30개
n_iter = 0
for train_index, test_index, in kfold.split(features):
# print('n_iter : ', n_iter)
# print('train_index : ', train_index)
# print('test_index : ', test_index)
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
#반복할 때마다 정확도 측정
acc = np.round(accuracy_score(y_test, pred), 3)
train_size = x_train.shape[0] # (행,열)
test_size = x_test.shape[0]
print('반복수 : {0}, 교차검증 정확도 : {1}, 학습데이터 크기 : {2}, 검증데이터 크기 : {3}'
.format(n_iter, acc, train_size, test_size ))
print('반복수 : {0}, 검증 데이터 인덱스 : {1}'.format(n_iter, test_index))
cv_acc.append(acc)
print('평균 검정 정확도 : ', np.mean(cv_acc))
print('\n과적합 방지 방법2-1 : 교차검증(cross validation) - 불균형한 분포(편향, 왜곡)을 가진 경우')
#불균형이란 특정 레이블 값이 특이하게 많거나 적은 경우
from sklearn.model_selection import StratifiedKFold
skfold = StratifiedKFold(n_splits=5)
cv_acc = []
n_iter = 0
for train_index, test_index, in skfold.split(features, label):
# print('n_iter : ', n_iter)
# print('train_index : ', train_index)
# print('test_index : ', test_index)
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
#반복할 때마다 정확도 측정
acc = np.round(accuracy_score(y_test, pred), 3)
train_size = x_train.shape[0] # (행,열)
test_size = x_test.shape[0]
print('반복수 : {0}, 교차검증 정확도 : {1}, 학습데이터 크기 : {2}, 검증데이터 크기 : {3}'
.format(n_iter, acc, train_size, test_size ))
print('반복수 : {0}, 검증 데이터 인덱스 : {1}'.format(n_iter, test_index))
cv_acc.append(acc)
print('평균 검정 정확도 : ', np.mean(cv_acc))
print('\n과적합 방지 방법3 : cross_val_score 함수로 간단하게 쓸 수 있다')
from sklearn.model_selection import cross_val_score
data=iris.data
label = iris.target
score=cross_val_score(dt_clf, data, label, scoring='accuracy', cv=5)
print('교차 검증별 정확도 : ', np.round(score, 3))
print('평균 검정 정확도 : ', np.round(np.mean(score), 3))
print('\n과적합 방지 방법4 : GridSearchCV - 모델 생성시 최적의 parameter 찾기')
from sklearn.model_selection import GridSearchCV
# max_depth = 트리의 최대 깊이 , min_samples_split = 노드 분할을 위한 최소 표본수 제어값
para={'max_depth' : [1,2,3], 'min_samples_split':[2,3]}
grid_dtree = GridSearchCV(dt_clf, param_grid=para, cv=3, refit=True)
grid_dtree.fit(x_train, y_train)
# GridSearchCV를 사용하여, 자동으로 복수의 내부 모형을 생성한 후, 최적의 파라미터를 찾음
import pandas as pd
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']
pd.set_option('display.max_columns', 500)
print(scores_df)
print('GridSearchCV 최적 파라미터 :', grid_dtree.best_params_)
print('GridSearchCV 최고 정확도 {0:4f}'.format(grid_dtree.best_score_))
# best 파라미터값을 제공한다. 최고 정확도도 제공.
# df_clf = DecisionTreeClassifier(max_depth = 2, min_samples_split = 2)
best_df_clf = grid_dtree.best_estimator_
print(best_df_clf)
pred = best_df_clf.predict(x_test)
print(pred)
print('best_df_clf acc :', accuracy_score(y_test, pred))
<console>
dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module'])
[[5.1 3.5 1.4 0.2]
[4.9 3. 1.4 0.2]
[4.7 3.2 1.3 0.2]]
[0 0 0]
분류 모델
DecisionTreeClassifier()
예측값 : [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2]
실제값 : [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2]
예측 정확도 : 1.0
과적합 방지 방법1 : train/test split
(105, 4) (45, 4) (105,) (45,)
[[6.3 2.8 5.1 1.5]
[6.8 3.2 5.9 2.3]
[4.8 3.4 1.9 0.2]
[6.3 2.5 4.9 1.5]
[5. 3.5 1.3 0.3]]
[[5.1 3.5 1.4 0.2]
[4.9 3. 1.4 0.2]
[4.7 3.2 1.3 0.2]
[4.6 3.1 1.5 0.2]
[5. 3.6 1.4 0.2]]
예측값 : [1 2 1 0 0 1 1 1 1 2 2 1 1 0 0 2 1 0 2 0 2 2 1 1 1 1 0 0 2 2 1 2 0 0 1 2 0
0 0 2 2 2 2 0 1]
실제값 : [1 2 1 0 0 1 1 1 1 2 1 1 1 0 0 2 1 0 2 0 2 2 1 1 1 1 0 0 2 2 1 2 0 0 1 2 0
0 0 2 2 2 2 0 2]
예측 정확도 : 0.9555555555555556
"추론통계는 모든 환경에서 100%가 되어서는 안된다."라는 철학을 이해하자
과적합 방지 방법2 : 교차검증(cross validation) - train/test split을 해도 과적합 발생 또는 데이터의 양이 적은 경우
iris shape : (150, 4)
반복수 : 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, 교차검증 정확도 : 0.967, 학습데이터 크기 : 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.933, 학습데이터 크기 : 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.8, 학습데이터 크기 : 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.9199999999999999
과적합 방지 방법2-1 : 교차검증(cross validation) - 불균형한 분포(편향, 왜곡)을 가진 경우
반복수 : 1, 교차검증 정확도 : 0.967, 학습데이터 크기 : 120, 검증데이터 크기 : 30
반복수 : 1, 검증 데이터 인덱스 : [ 0 1 2 3 4 5 6 7 8 9 50 51 52 53 54 55 56 57
58 59 100 101 102 103 104 105 106 107 108 109]
반복수 : 2, 교차검증 정확도 : 0.967, 학습데이터 크기 : 120, 검증데이터 크기 : 30
반복수 : 2, 검증 데이터 인덱스 : [ 10 11 12 13 14 15 16 17 18 19 60 61 62 63 64 65 66 67
68 69 110 111 112 113 114 115 116 117 118 119]
반복수 : 3, 교차검증 정확도 : 0.9, 학습데이터 크기 : 120, 검증데이터 크기 : 30
반복수 : 3, 검증 데이터 인덱스 : [ 20 21 22 23 24 25 26 27 28 29 70 71 72 73 74 75 76 77
78 79 120 121 122 123 124 125 126 127 128 129]
반복수 : 4, 교차검증 정확도 : 0.933, 학습데이터 크기 : 120, 검증데이터 크기 : 30
반복수 : 4, 검증 데이터 인덱스 : [ 30 31 32 33 34 35 36 37 38 39 80 81 82 83 84 85 86 87
88 89 130 131 132 133 134 135 136 137 138 139]
반복수 : 5, 교차검증 정확도 : 1.0, 학습데이터 크기 : 120, 검증데이터 크기 : 30
반복수 : 5, 검증 데이터 인덱스 : [ 40 41 42 43 44 45 46 47 48 49 90 91 92 93 94 95 96 97
98 99 140 141 142 143 144 145 146 147 148 149]
평균 검정 정확도 : 0.9534
과적합 방지 방법3 : cross_val_score 함수로 간단하게 쓸 수 있다
교차 검증별 정확도 : [0.967 0.967 0.9 0.933 1. ]
평균 검정 정확도 : 0.953
과적합 방지 방법4 : GridSearchCV - 모델 생성시 최적의 parameter 찾기
mean_fit_time std_fit_time mean_score_time std_score_time \
0 0.000332 0.000470 0.000000 0.00000
1 0.000664 0.000470 0.000000 0.00000
2 0.000499 0.000407 0.000000 0.00000
3 0.000333 0.000471 0.000000 0.00000
4 0.000333 0.000470 0.000332 0.00047
5 0.000332 0.000470 0.000332 0.00047
param_max_depth param_min_samples_split \
0 1 2
1 1 3
2 2 2
3 2 3
4 3 2
5 3 3
params split0_test_score \
0 {'max_depth': 1, 'min_samples_split': 2} 0.675
1 {'max_depth': 1, 'min_samples_split': 3} 0.675
2 {'max_depth': 2, 'min_samples_split': 2} 0.950
3 {'max_depth': 2, 'min_samples_split': 3} 0.950
4 {'max_depth': 3, 'min_samples_split': 2} 0.950
5 {'max_depth': 3, 'min_samples_split': 3} 0.950
split1_test_score split2_test_score mean_test_score std_test_score \
0 0.65 0.65 0.658333 0.011785
1 0.65 0.65 0.658333 0.011785
2 0.95 0.90 0.933333 0.023570
3 0.95 0.90 0.933333 0.023570
4 0.95 0.90 0.933333 0.023570
5 0.95 0.90 0.933333 0.023570
rank_test_score
0 5
1 5
2 1
3 1
4 1
5 1
GridSearchCV 최적 파라미터 : {'max_depth': 2, 'min_samples_split': 2}
GridSearchCV 최고 정확도 0.933333
DecisionTreeClassifier(criterion='entropy', max_depth=2, random_state=123)
[0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2]
best_df_clf acc : 1.0