TOP
class="layout-aside-left paging-number">
본문 바로가기
[파이썬 Projects]/<파이썬 머신 | 딥러닝 & AI>

[파이썬] 분류 > 앙상블 - 4 : XG Boost (3)

by 기록자_Recordian 2024. 7. 4.
728x90
반응형
시작에 앞서
해당 내용은 '<파이썬 머신러닝 완벽 가이드> 권철민 지음. 위키북스' 를 토대로 작성되었습니다. 보다 자세한 내용은 해당 서적에 상세히 나와있으니 서적을 참고해 주시기 바랍니다.

앙상블 학습(Ensemble Learning)
 

[파이썬] 분류: 앙상블 학습(Ensemble Learning) - 1

시작에 앞서해당 내용은 ' 권철민 지음. 위키북스' 를 토대로 작성되었습니다. 보다 자세한 내용은 해당 서적에 상세히 나와있으니 서적을 참고해 주시기 바랍니다.앙상블 학습(Ensemble Learning) 

puppy-foot-it.tistory.com

 

 

[파이썬] 분류 > 앙상블 - 3 : GBM

시작에 앞서해당 내용은 ' 권철민 지음. 위키북스' 를 토대로 작성되었습니다. 보다 자세한 내용은 해당 서적에 상세히 나와있으니 서적을 참고해 주시기 바랍니다.앙상블 학습(Ensemble Learning) [

puppy-foot-it.tistory.com


지난 내용
 

[파이썬] 분류 > 앙상블 - 4 : XG Boost (1)

시작에 앞서해당 내용은 ' 권철민 지음. 위키북스' 를 토대로 작성되었습니다. 보다 자세한 내용은 해당 서적에 상세히 나와있으니 서적을 참고해 주시기 바랍니다.앙상블 학습(Ensemble Learning) [

puppy-foot-it.tistory.com

▶ XGBoost의 파이썬 패키지 xgboost 는 자체적으로 교차 검증, 성능 평가, 피처 중요도 등의 시각화 기능(plot_importance 모듈)을 가지고 있다. 또한 조기 중단 기능(early stopping) 이 있어서 num_rounds로 지정한 부스팅 반복 횟수에 도달하지 않더라도 더 이상 예측 오류가 개선되지 않으면 반복을 끝까지 수행하지 않고 중지해 수행 시간을 개선하는 기능도 가지고 있다.

 

 

[파이썬] 분류 > 앙상블 - 4 : XG Boost (2)

시작에 앞서해당 내용은 ' 권철민 지음. 위키북스' 를 토대로 작성되었습니다. 보다 자세한 내용은 해당 서적에 상세히 나와있으니 서적을 참고해 주시기 바랍니다.앙상블 학습(Ensemble Learning) [

puppy-foot-it.tistory.com


사이킷런 래퍼 XGBoost의 개요 및 적용

 

XGBoost 개발 그룹은 사이킷런의 프레임워크와 연동하기 위해 사이킷런 전용의 XGBoost 래퍼 클래스를 개발했다.

사이킷런의 기본 Estimator를 그대로 상속해 만들었기 때문에 fit()과 predict() 만으로 학습과 에측이 가능하고, GridSearchCV, Pipeline 등 사이킷런의 다른 유틸리티를 그대로 사용할 수 있다.

 

XGBClassifier는 기존 사이킷런에서 일반적으로 사용하는 하이퍼 파라미터와 호환성을 유지하기 위해 기존의 xgboost 모듈에서 사용하던 네이티브 하이퍼 파라미터 몇 개를 다음과 같이 변경하였다.

  • eta → learning_rate
  • sub_sample → subsample
  • lambda → reg_lambda 
  • alpha → reg_alpha

또한, xgboost의 n_estimators와 num_boost_round 하이퍼 파라미터는 서로 동일한 파라미터이기 때문에, 만약 두 개가 동시에 사용되면 파이썬 래퍼 XGBoost API 에서는 n_estimarots 파라미터를 무시하고 run_boost_round 파라미터를 적용한다.

그러나 사이킷런 래퍼 XGBoost 클래스에서는 n_estimarots 파라미터를 적용한다.


위스콘신 대학병원의 유방암 데이터 세트 예측 (XGBClassifier 이용)

 

파이썬 래퍼 XGBoost 작업 후 새로 시작하는 분들은 하단의 코드를 입력하여 기본 세팅을 한다.

# XGBoost
import xgboost as xgb

# 위스콘신 유방암 예측 (xgboost)
from xgboost import plot_importance #시각화 모듈
import pandas as pd
import numpy as np
from sklearn.datasets import load_breast_cancer # 유방암 데이터셋 로드
from sklearn.model_selection import train_test_split #훈련, 테스트 데이터 분할
import warnings
warnings.filterwarnings('ignore')

dataset = load_breast_cancer()
features = dataset.data
labels = dataset.target

cancer_df = pd.DataFrame(data=features, columns=dataset.feature_names)
cancer_df['target'] = labels
cancer_df.head()
# 데이터 세트 분할
# cancer_df 에서 feature 용 DataFrame과 Label용 Series 객체 추출
# 맨 마지막 컬럼: Label
# Feature용 DataFrame은 cancer_df의 첫번째-맨 마지막 칼럼에서 두 번재 칼럼까지를 :-1 슬라이싱으로 추출
X_features = cancer_df.iloc[:, :-1]
y_label = cancer_df.iloc[:, -1]

# 전체 데이터 중 80% 학습용, 20% 테스트용
X_train, X_test, y_train, y_test = train_test_split(X_features, y_label, test_size=0.2,
                                                    random_state=156)

# 위에서 만든 학습용 데이터를 다시 쪼개서 90% 학습 10%는 검증용으로 분리
X_tr, X_val, y_tr, y_val = train_test_split(X_train, y_train, test_size=0.1,
                                            random_state=156)

print(X_train.shape, X_test.shape)
print(X_tr.shape, X_val.shape)

 

그리고 모델의 하이퍼 파라미터는 앞의 파이썬 래퍼 XGBoost와 동일하게

n_estimators = 400 (num_rounds 대응)

learning_rate = 0.1 (eta 대응)

max_depth = 3 으로 설정

# 사이킷런 래퍼 XGBoost 클래스인 XGBClassifier 임포트
import xgboost as xgb
from xgboost import XGBClassifier

# Warning 메시지를 없애기 위해 eval_metric 값을 XGBClassifier 생성 인자로 입력
xgb_wrapper = XGBClassifier(n_estimators=400, learning_rate=0.05, max_depth=3,
                            eval_metric='logloss')
xgb_wrapper.fit(X_train, y_train, verbose=True)
w_preds = xgb_wrapper.predict(X_test)
w_pred_proba = xgb_wrapper.predict_proba(X_test)[:, 1]

 

get_clf_eval() 를 이용해 사이킷런 래퍼 XGBoost로 만들어진 모델의 예측 성능 평가.

from sklearn.metrics import roc_auc_score
from sklearn.metrics import roc_curve
from sklearn.metrics import accuracy_score, precision_score, recall_score, confusion_matrix
from sklearn.metrics import f1_score

def get_clf_eval(y_test, pred=None, pred_proba=None):
    confusion = confusion_matrix(y_test, pred)
    accuracy = accuracy_score(y_test, pred)
    precision = precision_score(y_test, pred)
    recall = recall_score(y_test, pred)
    f1 = f1_score(y_test, pred)
    # ROC-AUC 추가
    roc_auc = roc_auc_score(y_test, pred)
    print('오차 행렬')
    print(confusion)
    # ROC-AUC print 추가
    print('정확도: {0:.4f}, 정밀도: {1:.4f}, 재현율: {2:.4f},\
        F1: {3:.4f}, AUC: {4:.4f}'.format(accuracy, precision, recall, f1, roc_auc))
get_clf_eval(y_test, w_preds, w_pred_proba)

▶ 앞 예제의 파이썬 래퍼 XGBoost 보다 더 좋은 평가 결과가 나왔다.

(파이썬 래퍼 XGBoost는 각 0.9561 / 0.9615 / 0.9740 / 0.9677 / 0.9937)

 

위스콘신 데이터 세트가 작기 때문에 전반적으로 검증 데이터를 분리하거나 교차 검증 등을 적용할 때 성능 수치가 불안정한 모습을 보이나, 데이터 건수가 많은 경우라면, 원본 학습 데이터를 다시 학습과 검증 데이터로 분리하고 여기에 조기 중단 회수를 적절하게 부여할 경우 일반적으로는 과적합을 개선할 수 있어 모델 성능이 조금 더 향상될 수 있다.


사이킷런 래퍼 XGBoost에서 조기 중단 수행하기

 

조기 중단 관련한 파라미터를 fit()에 입력하면 된다.

[조기 중단 관련 파라미터]

  • early_stopping_rounds: 반복 횟수 정의
  • eval_metric: 조기 중단을 위한 평가 지표
  • eval_set: 성능 평가를 수행할 데이터 세트

최초 학습 데이터에서 분리된 최종 학습 데이터와 검증 데이터를 이용하여 학습과 조기 중단 적용

# 사이킷런 래퍼 XGBoost 조기 중단
from xgboost import XGBClassifier

xgb_wrapper = XGBClassifier(n_estimators=400, learning_rate=0.05, max_depth=3)
evals = [(X_tr, y_tr), (X_val, y_val)]
xgb_wrapper.fit(X_tr, y_tr, early_stopping_rounds = 50, eval_metric='logloss',
                eval_set=evals, verbose=True)


ws50_preds = xgb_wrapper.predict(X_test)
ws50_pred_proba = xgb_wrapper.predict_proba(X_test)[:, 1]

▶ n_estimators 가 400 이지만 400번을 반복하지 않고 176번째 반복에서 학습을 마무리했다.

 

▶ 126번째 반복에서 검증 데이터 세트의 성능인 validation_1-logloss가 0,25587로 가장 낮고, 이후 50번 반복까지 더 이상 반복이 향상되지 않았기 때문에 조기 종료되었다.


조기 중단으로 학습된 XGBClassifier의 예측 성능

 

# 조기 중단 학습된 XGBClassifier 예측 성능
get_clf_eval(y_test, ws50_preds, ws50_pred_proba)

▶ 위스콘신 데이터가 워낙 작아서, 조기 중단을 위한 검증 데이터를 분리하면 검증 데이터가 없는 학습 데이터를 사용했을 때보다 성능이 약간 저조하다.

 

그러나, 조기 중단값을 급격하게 줄이면 예측 성능이 저하될 우려가 크다.

만약 early_stopping_rounds를 10로 하면 아직 성능이 향상될 여지가 있음에도 10번 반복동안 성능이 향상되지 않으면 반복이 멈춰 충분한 학습이 되지 않아 예측 성능이 나빠질 수 있다.

 

# early_stopping_rounds를 10으로 줄인 예측 성능
xgb_wrapper.fit(X_tr, y_tr, early_stopping_rounds = 10, eval_metric='logloss',
                eval_set=evals, verbose=True)

ws10_preds = xgb_wrapper.predict(X_test)
ws10_pred_proba = xgb_wrapper.predict_proba(X_test)[:, 1]

 103번째 반복까지만 수행된 후 학습이 종료됐는데, 103번째 반복의 logloss가 0.25991, 93번째 반복의 logloss가 0.25864로서 10번 반복하는 동안 성능 평가 지수가 향상되지 못해서 더 이상 반복하지 않고 학습이 종료되었다.

 

이때의 예측 성능은

# 조기 중단 10번으로 학습된 XGBClassifier 예측 성능
get_clf_eval(y_test, ws10_preds, ws10_pred_proba)

early_stopping_rounds가 50일 때보다 낮다.


피처의 중요도 시각화

 

from xgboost import plot_importance
import matplotlib.pyplot as plt
%matplotlib inline

fig, ax = plt.subplots(figsize=(10, 12))
# 사이킷런 래퍼 클래스를 입력해도 무방
plot_importance(xgb_wrapper, ax=ax)


 

728x90
반응형