내장된 예제 데이터 세트
from sklearn.datasets import load_iris
iris_data = load_iris()
print(type(iris_data))
<class 'sklearn.utils.Bunch'>
keys = iris_data.keys()
print('붓꽃 데이터 세트의 키들:' ,keys)
붓꽃 데이터 세트의 키들: dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename'])
print('\n feature_names 의 type:',type(iris_data.feature_names))
print(' feature_names 의 shape:',len(iris_data.feature_names))
print(iris_data.feature_names)
print('\n target_names의 type', type(iris_data.target_names))
print(' target_names의 shape:', len(iris_data.target_names))
print(iris_data.target_names)
print('\n data의 type:', type(iris_data.data))
print(' data의 shape:',len(iris_data.data))
print(iris_data.data)
print('\n target의 type:', type(iris_data.target))
print(' target의 shape:', len(iris_data.target))
print(iris_data.target)
feature_names 의 type: <class 'list'>
feature_names 의 shape: 4
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
target_names의 type <class 'numpy.ndarray'>
target_names의 shape: 3
['setosa' 'versicolor' 'virginica']
data의 type: <class 'numpy.ndarray'>
data의 shape: 150
[[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]
[5.4 3.9 1.7 0.4]
[4.6 3.4 1.4 0.3]
[5. 3.4 1.5 0.2]
[4.4 2.9 1.4 0.2]
[4.9 3.1 1.5 0.1]
[5.4 3.7 1.5 0.2]
[4.8 3.4 1.6 0.2]
[4.8 3. 1.4 0.1]
[4.3 3. 1.1 0.1]
[5.8 4. 1.2 0.2]
[5.7 4.4 1.5 0.4]
[5.4 3.9 1.3 0.4]
[5.1 3.5 1.4 0.3]
[5.7 3.8 1.7 0.3]
[5.1 3.8 1.5 0.3]
[5.4 3.4 1.7 0.2]
[5.1 3.7 1.5 0.4]
[4.6 3.6 1. 0.2]
[5.1 3.3 1.7 0.5]
[4.8 3.4 1.9 0.2]
[5. 3. 1.6 0.2]
[5. 3.4 1.6 0.4]
[5.2 3.5 1.5 0.2]
[5.2 3.4 1.4 0.2]
[4.7 3.2 1.6 0.2]
[4.8 3.1 1.6 0.2]
[5.4 3.4 1.5 0.4]
[5.2 4.1 1.5 0.1]
[5.5 4.2 1.4 0.2]
[4.9 3.1 1.5 0.2]
[5. 3.2 1.2 0.2]
[5.5 3.5 1.3 0.2]
[4.9 3.6 1.4 0.1]
[4.4 3. 1.3 0.2]
[5.1 3.4 1.5 0.2]
[5. 3.5 1.3 0.3]
[4.5 2.3 1.3 0.3]
[4.4 3.2 1.3 0.2]
[5. 3.5 1.6 0.6]
[5.1 3.8 1.9 0.4]
[4.8 3. 1.4 0.3]
[5.1 3.8 1.6 0.2]
[4.6 3.2 1.4 0.2]
[5.3 3.7 1.5 0.2]
[5. 3.3 1.4 0.2]
[7. 3.2 4.7 1.4]
[6.4 3.2 4.5 1.5]
[6.9 3.1 4.9 1.5]
[5.5 2.3 4. 1.3]
[6.5 2.8 4.6 1.5]
[5.7 2.8 4.5 1.3]
[6.3 3.3 4.7 1.6]
[4.9 2.4 3.3 1. ]
[6.6 2.9 4.6 1.3]
[5.2 2.7 3.9 1.4]
[5. 2. 3.5 1. ]
[5.9 3. 4.2 1.5]
[6. 2.2 4. 1. ]
[6.1 2.9 4.7 1.4]
[5.6 2.9 3.6 1.3]
[6.7 3.1 4.4 1.4]
[5.6 3. 4.5 1.5]
[5.8 2.7 4.1 1. ]
[6.2 2.2 4.5 1.5]
[5.6 2.5 3.9 1.1]
[5.9 3.2 4.8 1.8]
[6.1 2.8 4. 1.3]
[6.3 2.5 4.9 1.5]
[6.1 2.8 4.7 1.2]
[6.4 2.9 4.3 1.3]
[6.6 3. 4.4 1.4]
[6.8 2.8 4.8 1.4]
[6.7 3. 5. 1.7]
[6. 2.9 4.5 1.5]
[5.7 2.6 3.5 1. ]
[5.5 2.4 3.8 1.1]
[5.5 2.4 3.7 1. ]
[5.8 2.7 3.9 1.2]
[6. 2.7 5.1 1.6]
[5.4 3. 4.5 1.5]
[6. 3.4 4.5 1.6]
[6.7 3.1 4.7 1.5]
[6.3 2.3 4.4 1.3]
[5.6 3. 4.1 1.3]
[5.5 2.5 4. 1.3]
[5.5 2.6 4.4 1.2]
[6.1 3. 4.6 1.4]
[5.8 2.6 4. 1.2]
[5. 2.3 3.3 1. ]
[5.6 2.7 4.2 1.3]
[5.7 3. 4.2 1.2]
[5.7 2.9 4.2 1.3]
[6.2 2.9 4.3 1.3]
[5.1 2.5 3. 1.1]
[5.7 2.8 4.1 1.3]
[6.3 3.3 6. 2.5]
[5.8 2.7 5.1 1.9]
[7.1 3. 5.9 2.1]
[6.3 2.9 5.6 1.8]
[6.5 3. 5.8 2.2]
[7.6 3. 6.6 2.1]
[4.9 2.5 4.5 1.7]
[7.3 2.9 6.3 1.8]
[6.7 2.5 5.8 1.8]
[7.2 3.6 6.1 2.5]
[6.5 3.2 5.1 2. ]
[6.4 2.7 5.3 1.9]
[6.8 3. 5.5 2.1]
[5.7 2.5 5. 2. ]
[5.8 2.8 5.1 2.4]
[6.4 3.2 5.3 2.3]
[6.5 3. 5.5 1.8]
[7.7 3.8 6.7 2.2]
[7.7 2.6 6.9 2.3]
[6. 2.2 5. 1.5]
[6.9 3.2 5.7 2.3]
[5.6 2.8 4.9 2. ]
[7.7 2.8 6.7 2. ]
[6.3 2.7 4.9 1.8]
[6.7 3.3 5.7 2.1]
[7.2 3.2 6. 1.8]
[6.2 2.8 4.8 1.8]
[6.1 3. 4.9 1.8]
[6.4 2.8 5.6 2.1]
[7.2 3. 5.8 1.6]
[7.4 2.8 6.1 1.9]
[7.9 3.8 6.4 2. ]
[6.4 2.8 5.6 2.2]
[6.3 2.8 5.1 1.5]
[6.1 2.6 5.6 1.4]
[7.7 3. 6.1 2.3]
[6.3 3.4 5.6 2.4]
[6.4 3.1 5.5 1.8]
[6. 3. 4.8 1.8]
[6.9 3.1 5.4 2.1]
[6.7 3.1 5.6 2.4]
[6.9 3.1 5.1 2.3]
[5.8 2.7 5.1 1.9]
[6.8 3.2 5.9 2.3]
[6.7 3.3 5.7 2.5]
[6.7 3. 5.2 2.3]
[6.3 2.5 5. 1.9]
[6.5 3. 5.2 2. ]
[6.2 3.4 5.4 2.3]
[5.9 3. 5.1 1.8]]
target의 type: <class 'numpy.ndarray'>
target의 shape: 150
[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]
Model Selection 모듈 소개
학습 테스트 데이터 세트 분리 train_test_split
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 = df_clf.predict(train_data)
print('예측정확도:',accuracy_score(train_label, pred))
### 학습데이터와 테스터 데이터를 분리하지 않으면 ?
#해당 테스트 데이터를 먼저 학습해버리기 떄문에 모의고사를 한번 보고 다시 시험을 보게되기에
예측정확도: 0.9866666666666667
# test_size : 전체 데이터에서 테스트 데이터 세트 크기 지정 디폴트 0.25 25%
# train_size : 전체사이즈에서 얼마나 샘플링 할 것인가
# shuffle: 테스트를 분리하기전 미리 섞을 겄인가 디폴트는 True
# random_state : 호출 할떄마다 학습과 테스트 데이터를 분리하기위한 난수를 생성하는 것
# train_test_split 반환 값은 튜플의 형태이다.
# 1.학습용 데이터의 피처데이터 세트, 테스트용 데이터의 피처데이터 , 학습용 레이블 세트, 테스트용 레이블 세트
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)
df_clf.fit(X_train, y_train)
pred = df_clf.predict(X_test)
print('예측 정확도: {0:4f}'.format(accuracy_score(y_test, pred)))
예측 정확도: 0.955556
교차 검증
과적합 될 수 있는 문제를 해결하기 위해서 먼저 교차검증은 실제 모델이 학습데이터에만 과도하게 최적화되어서 실제 테스트 데이터에는
최적의 성능을 할 수 없는 것을 막기위해서
본고사를 보기전에 모의고사를 여러번 보는 것이다. 즉 ML은 데이터에 기반합니다. 그리고 데이터는 이상치, 분포도, 다양한 속성값, 피처 중요도 등 ML에 영향을 미치는 요소를 가지고 있다. 특정 ML알고리즘에서 최적으로 동작할 수 있도록 데이터를 선별해 학습
교차 검증은 이러한 편증을 막기 위해서 별도의 여러 세트로 구성된 학습데이터와 검증 데이터 세트를 만들고 학습과 평가를 함
학습데이터를 다시 분할하여 학습데이터 세트 + 검증 데이터 세트
K폴드 교차 검증
K폴드 교차 검증은 가장 보편적으로 사용되는 교차검증 기법이다. 폴드 세트를 만들어서 K번만큼 각 폴트 세트에 학습과 검증평가를 함
from sklearn.model_selection import KFold
import numpy as np
features = iris.data
label = iris.target
dt_clf = DecisionTreeClassifier(random_state=15)
#5개의 폴드 세트로 분리하는 Kfold객체와 폴드 세트별 정확도를 담을 리스트 객체 생성
kfold = KFold(n_splits=5)
cv_accuracy = []
print('붓꽃 데이터 세트 크기:', feature.shape[0])
붓꽃 데이터 세트 크기: 150
n_iter = 0;
#Kfold 객체의 split()호출 하면 폴드 별 학습용, 검증용 테스트의 로우 인덱스를 array로 변환
for train_index, test_index in kfold.split(features):
#kforld.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]
accuracy = np.round(accuracy_score(y_test, pred),4)
train_size = X_train.shape[0]
test_size = X_test.shape[0]
print('#{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]
##평균 검증 정확도: 1.0
#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.98335
#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]
##평균 검증 정확도: 0.9555666666666666
#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.95
#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.9066599999999999
Stratified K 폴드
stratified K폴드는 불균형한 분포도를 가진 레이블 데이터 집합을 위한 K폴드 방식
레이블이 특이하게 많거나 매우 적어서 값의 분포가 한쪽으로 치우는 것을 말합니다.
테스트데이터 세트에 제대로 레이블의 분포를 할 수없을때 ( 대출사기 등 1건 2건 이런 이상치가 작을때)
Stratified K 폴드는 이처럼 K폴드가 레이블데이터 분포 분배를 못할 때
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()
iris_df
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) label
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
... ... ... ... ... ...
145 6.7 3.0 5.2 2.3 2
146 6.3 2.5 5.0 1.9 2
147 6.5 3.0 5.2 2.0 2
148 6.2 3.4 5.4 2.3 2
149 5.9 3.0 5.1 1.8 2
150 rows × 5 columns
#이렇게 할 경우 Kfold의 학습데이터셋에서는 검증데이터셋과 달라지게 됨
kfold = KFold(n_splits=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
학습 레이블 데이터 분포:
2 50
1 50
Name: label, dtype: int64
검증 레이블 데이터 분포:
0 50
Name: label, dtype: int64
##교차 검증:2
학습 레이블 데이터 분포:
2 50
0 50
Name: label, dtype: int64
검증 레이블 데이터 분포:
1 50
Name: label, dtype: int64
##교차 검증:3
학습 레이블 데이터 분포:
1 50
0 50
Name: label, dtype: int64
검증 레이블 데이터 분포:
2 50
Name: label, dtype: int64
#이러한 부분의 폴드의 교차검증을 막고자 데이터의 분포를 맞추기위해
#StratifiedFold 사용
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[test_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 17
0 17
2 16
Name: label, dtype: int64
검증 레이블 데이터 분포:
1 17
0 17
2 16
Name: label, dtype: int64
##교차 검증:2
학습 레이블 데이터 분포:
2 17
0 17
1 16
Name: label, dtype: int64
검증 레이블 데이터 분포:
2 17
0 17
1 16
Name: label, dtype: int64
##교차 검증:3
학습 레이블 데이터 분포:
2 17
1 17
0 16
Name: label, dtype: int64
검증 레이블 데이터 분포:
2 17
1 17
0 16
Name: label, dtype: int64
교차 검증을 보다 간편하게 해보자 - cross_val_score()
from sklearn.model_selection import cross_val_score, cross_validate
iris_data = load_iris()
df_clf = DecisionTreeClassifier(random_state=156)
data = iris_data.data
label = iris_data.target
#성능 지표는 정확도(accuracy), 교차 검증 세트는 3개
scores = cross_val_score(df_clf, data, label, scoring = 'accuracy', cv=3)
print('교차 검증별 정확도:',np.round(scores,4))
print('평균 검증 정확도:',np.round(np.mean(scores),4))
교차 검증별 정확도: [0.98 0.94 0.98]
평균 검증 정확도: 0.9667