2절 Scikit - learn을 통한 예측 알고리즘 실습해보기
4장 Model Selection (2)
본 포스팅은 [위키북스- 파이썬 머신러닝 완벽 가이드]를 활용한 스터디 포스팅입니다.
저번 포스팅에서는 Cross-validation중에서 K-fold에 대한 개념과 구현 과정을 살펴보았다.
이번 포스팅에서는 K-fold를 구현하는데 좀 더 효율적인 방법을 지원해주는 라이브러리들을 살펴볼 것이다.
Stratified K-fold 교차 검증
- Stratified K-fold 란?
K fold는 random으로 데이터 셋을 split 해주는데, 이 때문에 레이블 값의 분포(비율)가 기존 데이터 full 셋에서의 분포(비율)와 크게 달라질 수도 있다.
Stratified K-fold 교차 검증 방법은 원본 데이터에서 레이블 분포를 먼저 고려한 뒤, 이 분포와 동일하게 학습 및 검증 데이터 세트를 분배한다.
(예를 들면 A와 B로 이루어진 원본 데이터의 구성 비율이 A : B = 3 : 7 이라면, training set 및 test set의 데이터의 구성비율도 A : B = 3 : 7이 되게 만들어 주는 개념이다.)
- Stratified K-fold 교차 검증 방법
Stratified K-fold 교차 검증 방법은 StratifiedKFold 라이브러리로 쉽게 구현이 가능하다.
아래처럼 라이브러리를 생성하고, k의 개수인 n_splits 을 설정해주면 된다.
from sklearn.model_selection import StratifiedKFold
skf = StratifiedKFold(n_splits=3)
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 원본 데이터의 target에 대한 구성은 50 : 50 : 50 의 비율을 가지고 있다.
Stratified K-fold로 데이터를 split 하면, 쪼개진 train/test데이터에도 같은 구성 비율로 생성이 될 것이다.
아래의 코드는 K-fold에서 쪼개진 3세트의 train/test데이터의 구성 비율을 구하는 코드이다.
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())
위의 결과를 보면, 각 모든 train데이터 및 test데이터 세트에서의 구성 비율이 1 : 1 : 1로 같음을 볼 수 있다.
교차 검증을 간단하게 하는 방법 : cross_val_score( )
- cross_val_score( ) 기능
cross_val_score( ) 함수는 교차 검증을 쉽게 하기 위한 함수이다.
cross_val_score( 알고리즘, 피쳐 데이터 세트, 레이블 데이터 세트, 스코어링 기준, 폴드수(cv) ) 형태로 쓰기 때문에, 교차 검증의 컨트롤이 쉬워진다.
- cross_val_score( ) 교차 검증 방법
cross_val_score( ) 함수를 사용하기 위해서는 cross_val_score과 cross_validate 라이브러리를 import 하면 된다.
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score, cross_validate
from sklearn.datasets import load_iris
iris = load_iris()
data = iris.data
label = iris.target
dt_clf = DecisionTreeClassifier(random_state=156)
score = cross_val_score(dt_clf, data, label, scoring='accuracy', cv=3)
print('교차 검증별 정확도:', np.round(score, 4))
print('평균 검증 정확도:', np.round(np.mean(score), 4))
이 검증에서는 K-fold 교차 검증 방법중 자동으로 Stratified K-fold 방법을 선택하여 분류 및 스코어링하는 것을 볼 수 있다.
GridSearchCV
- GridSearchCV 란?
교차 검증과 최적 하이퍼 파라미터 튜닝을 한번에 적용할 수 있게 해주는 사이킷런의 기능 중 하나이다.
Classifier 나 Regressor 같은 알고리즘에 사용되는 하이퍼 파라미터를 순차적으로 입력하면서 편리하게 최적 파라미터를 도출할 수 있게 해준다.
# 하이퍼 파라미터 : 머신러닝 알고리즘을 구성하는 요소중 하나로, 하이퍼 파라미터를 고정하면서 알고리즘 성능을 개선할 수 있다.
- GridSearchCV 교차 검증 방법
cross_val_score( ) 함수를 사용하려면, 우선 알고리즘 성능을 비교할 하이퍼 파라미터를 정해야 한다. 아래처럼 결정트리의 깊이가 1~3 depth일때와, k의 개수가 2~3개 일 때의 알고리즘 성능을 비교하기 위해 하이퍼 파라미터를 제한해 주었다.
grid_parameters = {'max_depth' : [1, 2, 3],
'min_samples_split' : [2, 3]}
# 총 6회에 걸친 분석 결과를 도출함 -> 고로 시간이 오래걸리는건 감수해야함!!
GridSearchCV 교차 검증을 위해서는 GridSearchCV 라이브러리를 설치해주어야 한다.
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import GridSearchCV
iris = load_iris()
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target,
test_size=0.2, random_state=121)
dtree = DecisionTreeClassifier()
parameters = {'max_depth' : [1, 2, 3], 'min_samples_split' : [2, 3]}
위의 예시들에서는 결정 트리 함수 자체를 변수에 할당하였다면, 이번에는 GridSearchCV 함수를 변수에 할당한 후 fit과 predict에도 적용하는 점이 다르다.
import pandas as pd
# param_grid의 하이퍼 파라미터를 3개의 train, test의 fold 로 나누어 테스트 수행 설정
# refit이란 True가 디폴트 -> True이면 가장 좋은 파라미터 설정으로 계속 재학습시킨다.
grid_dtree = GridSearchCV(dtree, param_grid=parameters, cv=3, refit=True)
grid_dtree.fit(x_train, y_train)
# GridSearchCV 결과를 추출해 DataFrame 으로 변환
scores_df = pd.DataFrame(grid_dtree.cv_results_)
scores_df
scores_df[['params',
'mean_test_score',
'rank_test_score',
'split0_test_score',
'split1_test_score',
'split2_test_score']]
따라서 결과가 좋은 {'max_depth': 3, 'min_samples_split': 2} 를 선택하면 된다.
print('GridSearchCV 최적 파라미터 : ', grid_dtree.best_params_)
print('GridSearchCV 최고 정확도 : {0:.4f}'.format(grid_dtree.best_score_))
GridSearchCV를 통해 test 데이터의 예측 정확도도 쉽게 구할 수 있다.
# GridSearchCV 의 refit 으로 이미 학습된 estimator 반환
estimator = grid_dtree.best_estimator_
# 위의 estimator로 예측
pred = estimator.predict(x_test)
print('테스트 데이트 세트 정확도 : {0:.4f}'.format(accuracy_score(y_test, pred)))
이번 포스팅에서는 여러가지의 K-fold 방법에 대해 알아보았다.
다음 포스팅에서는 예측 및 분류 모델에 사용되는 데이터를 어떻게 전처리 해야하는지에 대해 살펴보도록 하겠다.
댓글