2절 Scikit - learn을 통한 예측 알고리즘 실습해보기
4장 Model Selection (1) - K-fold
본 포스팅은 [위키북스- 파이썬 머신러닝 완벽 가이드]를 활용한 스터디 포스팅입니다.
Model을 선택하는데 있어 필요한 개념이 있는데, 바로 Cross-validation인 교차검증이다.
오늘의 포스팅에서는 Cross-validation(교차검증) 중에서도 K-fold 교차검증을 구현하는 방법에 대해서 자세히 살펴볼 예정이다.
- Cross-validation(교차검증)이란?
교차검증이란 일반화 성능을 측정하기 위해 데이터를 여러번 반복해서 나누어 여러 모델을 학습하는 과정을 뜻한다. 대표적으로 KFold 교차검증이 존재한다.
- K-fold 교차검증
데이터를 폴드라 부르는 비슷한 크기의 부분집합(n_splits)으로 나누고 각각 폴드의 정확도를 측정하여 검증을 진행한다. 검증의 순서는 다음과 같다.
1. 첫번재 폴드는 테스트 세트로 사용하고, 나머지 폴드를 훈련세트로 사용하여 학습
2. 나머지 훈련세트로 만들어진 세트의 정확도를 첫번째 폴드로 평가
3. 다음은 두번째 폴드가 테스트세트가 되고 나머지 폴드의 훈련세트를 두번째 폴드로 정확도를 측정.
4. 이 과정을 마지막 폴드까지 반복.
5. 이렇게 훈련세트와 테스트세트로 나누는 N개의 분할, 정확도를 측정하여 평균값을 낸게 정확도가 됨.
[ Decision Tree 방법으로 K-fold 교차검증 실습 ]
1단계 : 데이터 Split (train data/test data) 실행
위에서 설명한 K-fold 교차검증을 결정 트리를 활용하여 실습해보도록 하겠다. (결정트리는 나중 포스팅에서 자세히 배울 것이니, 지금은 K-fold 학습에만 집중해보도록 한다!)
가장 먼저, 실습을 위해서 아래와 같이 라이브러리를 설치한다.
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
import numpy as np
import pandas as pd
기초적으로 iris 데이터를 활용하기 위해 데이터를 불러오며, 실습에 활용할 결정트리와 정확도 라이브러리를 블러온다.
우선, 데이터를 나누기 전에(왜 나누는지는 추후에 설명한다) 전체 데이터 셋을 모두 학습시켜 품종을 분류해보도록 한다.
iris = load_iris()
dt_clf = DecisionTreeClassifier()
train_data = iris.data
train_label = iris.target
데이터를 불러온 후, 결정트리 함수를 dt_clf에 할당시켜 추후 불러오기 쉽게 만들어 준다. iris 데이터에는 data 속성에 feature 값들이 들어있고 target 속성에 꽃의 종류인 목적변수가 들어있다.
dt_clf.fit(train_data, train_label)
정의한 결정트리에 데이터를 집어 넣어 fit함수를 실행하면 위와같이 결정트리 학습이 실행된다.
학습을 시킨 뒤에, predict 함수를 적용시켜 데이터에 대한 분류 예측을 실행할 수 있다. 예측 실행 결과의 지표는 다양한데, 여기서는 일단 Accuracy(정확도)를 구해보도록 한다.
pred = dt_clf.predict(train_data)
accuracy_score(train_label,pred)
- 예측 정확도가 1인 이유?
train 데이터 셋으로 예측한 모델로 같은 데이터를 통해 예측을 했기 때문에 예측 정확도가 1이 나올수 밖에 없다.
따라서 데이터를 train / test 셋으로 나눠야 학습된 모델을 통해 테스트 셋을 예측할 수 있다.
- train / test 데이터 분리하기
위에서 했던 방법과 동일하게 실습하되, 이번에는 데이터를 split하여 예측 모델을 생성, 적용해보도록 하겠다.
위에서 설치했던 라이브러리에 더해서 train_test_split 라이브러리를 추가로 import 해준다.
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split #### 데이터 셋을 train / test 로 분류해주는 라이브러리
import numpy as np
import pandas as pd
dt_clf = DecisionTreeClassifier()
iris = load_iris()
train_test_split 함수를 활용하여 데이터를 분할해 준다.
In [7]:
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.3, random_state=121)
# random_state 는 데이터를 분할해줄때 패턴을 부여하는 값으로, 다음번에 121을 부여하면 똑같은 데이터셋으로 분할됨
위에서 train_test_split 함수로 인해 split되는 데이터의 의미는 다음과 같다.
- x_train : train 데이터셋에서의 feature값
- x_test : test 데이터셋에서의 feature값
- y_train : train 데이터셋에서의 목적변수
- y_train : train 데이터셋에서의 목적변수
split 된 데이터를 활용하여 fit 및 predict를 하게 되면, 다음과 같은 예측 정확도를 얻을 수 있다.
In [8]:
dt_clf.fit(x_train, y_train)
pred = dt_clf.predict(x_test)
accuracy_score(y_test,pred)
여기까지 데이터를 split하여 모델을 생성하고 예측하는 과정을 거쳤다.
2단계 : K-fold 교차검증 실행
데이터를 split 했으니, 이제 K fold 교차 검증을 실행할 준비가 끝났다.
K fold 함수를 사용하기 위해서는 model_selection에서 KFold 라이브러리를 import 해준다.
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
from sklearn.model_selection import KFold
import numpy as np
iris 데이터를 불러와 독립변수인 feature와 종속변수인 target 값을 나누어 저장시킨다.
iris = load_iris()
feature = iris.data
print(feature.shape)
label = iris.target
print(label.shape)
아래의 결과로 feature는 4개, target은 1개인 데이터가 150개 들어있는 것을 알 수 있다.
결정트리 라이브러리를 dt_clf에 저장시킨다.
dt_clf = DecisionTreeClassifier(random_state=156)
kfold 함수를 활용하여 split할 개수인 n_splits의 개수를 정해준다.
kfold = KFold(n_splits=5)
데이터를 split하지 않았을 때와 같은 방법으로 정확도를 예측할 것이다. 하지만 K fold의 특성상 n개로 나누어진 데이터 셋에 대해서 5번의 예측 정확도를 생산하는 과정이 필요하다.
아래의 예시코드에서는 직접 for문을 돌려 K-fold 교차 검증을 실행하였으며, 각 예측 정확도를 활용하여 정확도의 평균을 구할 수 있다.
cv_accuracy = []
n_iter =0
for train_index, test_index in kfold.split(feature): # feautres 데이터를 위에서 지정한 kfold 숫자로 분할
x_train, x_test = feature[train_index], feature[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) # 소수점 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.mean(cv_accuracy))
하지만 이렇게 직접 코드를 치지 않아도 cross validation을 손쉽게 지원해주는 함수가 있다.
다음 포스팅에서 그 함수들을 살펴보기로 하자.
댓글