시작에 앞서
해당 내용은 '<파이썬 머신러닝 완벽 가이드> 권철민 지음. 위키북스' 를 토대로 작성되었습니다. 보다 자세한 내용은 해당 서적에 상세히 나와있으니 서적을 참고해 주시기 바랍니다.
앙상블 학습(Ensemble Learning)
지난 내용
▶ XGBoost의 파이썬 패키지 xgboost 는 자체적으로 교차 검증, 성능 평가, 피처 중요도 등의 시각화 기능(plot_importance 모듈)을 가지고 있다. 또한 조기 중단 기능(early stopping) 이 있어서 num_rounds로 지정한 부스팅 반복 횟수에 도달하지 않더라도 더 이상 예측 오류가 개선되지 않으면 반복을 끝까지 수행하지 않고 중지해 수행 시간을 개선하는 기능도 가지고 있다.
파이썬 래퍼 XGBoost 적용 - 위스콘신 유방암 예측
위스콘신 유방암 데이터 세트는 종양의 크기, 모양 등의 다양한 속성 값을 기반으로 악성인지 양성 종양인지를 분류한 데이터 세트이다. 이는 사이킷런에 내장되어 있으며 load_breast_cancer()를 호출하면 된다.
# 위스콘신 유방암 예측 (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()
▶ 종양의 크기와 모양에 관련된 많은 속성이 숫자형 값으로 돼 있다. 타깃 레이블 값의 종류는 악성(malignant) 0, 양성(benign) 1
◆ 레이블 값의 분포 확인 (악성, 양성)
# 레이블 값의 분포 확인
print(dataset.target_names)
print(cancer_df['target'].value_counts())
▶ 악성(malignant), 0값: 212 /양성(benign), 1값: 357 개로 구성
◆ 데이터 세트 분할
80%는 학습용으로, 20%는 테스트용으로 추출한 뒤, 이 80%의 학습용 데이터에서 90%를 최종 학습용, 10%를 검증용으로 분할
# 데이터 세트 분할
# 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)
▶ 전체 569개 데이터 세트에서 최종 학습용 409개, 검증용 46개, 테스트용 114개가 추출되었다.
파이썬 래퍼 XGBoost - DMatrix
파이썬 래퍼 XGBoost는 사이킷런과 여러 차이가 있다.
그 중에서도 XGBoost만의 전용 데이터 객체인 DMatrix를 사용한다는 것인데,
▶ Numpy 또는 Pandas로 되어 있는 학습용, 검증, 테스트용 데이터 세트를 모두 전용의 데이터 객체인 DMatrix로 생성하여 모델에 입력해 줘야 한다. (주요 파라미터는 data - 피처 데이터 세트, label - 분류의 경우 레이블 데이터 세트 / 회귀의 경우 종속값 데이터 세트)
▶ DMatrix는 Numpy, DataFrame, Series 외에 libsvm txt 포맷 파일, xgboost 이진 버퍼 파일을 파라미터로 입력받아 변환할 수 있다.
[DataFrame 기반의 학습 데이터 세트와 테스트 데이터 세트 → DMatrix]
# DataFrame 기반의 학습 데이터 세트와 테스트 데이터 세트 > DMatrix
# 만약 구버전 XGBoost에서 DF으로 DMatrix 생성이 안 될 경우 X_train.values로 넘파이 변환
# 학습, 검증, 테스트용 DMatrix 생성
dtr = xgb.DMatrix(data=X_tr, label=y_tr)
dval = xgb.DMatrix(data=X_val, label=y_val)
dtest = xgb.DMatrix(data=X_test, label=y_test)
XGBoost 하이퍼 파라미터 설정
파이썬 래퍼 XGBoost 모듈인 xgboost를 이용해 학습을 수행하기 전 먼저 XGBoost의 하이퍼 파라미터 값 설정.
XGBoost의 하이퍼 파라미터는 주로 딕셔너리 형태로 입력한다.
# XGBoost 하이퍼 파라미터 설정
params = { 'max_depth':3, #트리 최대 깊이
'eta':0.05, #학습률
'objective':'binary:logistic', #예제 데이터가 0 또는 1인 이진분류이므로
'eval_metric':'logloss' #오류 함수의 평가 성능 지표
}
num_rounds = 400 #부스팅 반복 횟수
[ 지정된 하이퍼 파라미터로 XGBoost 모델 학습]
위에 지정된 하이퍼 파라미터로 XGBoost 모델 학습.
- 파이썬 래퍼 XGBoost는 하이퍼 파라미터를 xgboost 모듈의 train() 함수에 파라미터로 전달
※ 사이킷런의 경우는 Estimator의 생성자를 하이퍼 파라미터로 전달
- 조기 중단의 성능 평가는 주로 별도의 검증 데이터 세트를 이용
▶ 조기 중단은 xgboost의 train() 함수에 eary_stopping_rounds 파라미터를 입력하여 설정
조기 중단을 설정하기 위해서는 반드시 평가용 데이터 세트 지정과 eval_metric을 함께 설정해야 한다. (주로 error - 분류 오류 / logloss 적용)
※ xgboost는 반복마다 지정된 평가용 데이터 세트에서 eval_metric의 지정된 평가 지표로 예측 오류를 측정.
# 지정된 하이퍼 파라미터로 XGBoost 모델 학습
# 학습 데이터 셋은 'train' 또는 평가 데이터 셋은 'eval'로 명기
eval_list = [(dtr, 'train'), (dval, 'eval')]
# 또는 eval_list = [(dval, 'eval')]만 명기해도 무방
# 하이퍼 파라미터와 early stopping 파라미터를 train() 함수의 파라미터로 전달
xgb_model = xgb.train(params = params, dtrain=dtr, num_boost_round=num_rounds,
early_stopping_rounds=50, evals=eval_list)
▶ train() 으로 학습을 수행하면서 반복 시마다 train-logloss와 eval-logloss가 지속적으로 감소하고 있다.
그러나 num_boost_rounds를 400회로 설정했음에도 학습을 400번을 반복하지 않고 0부터 시작하여 175번째 반복에서 완료했음을 알 수 있다.
▶ 126번째 반복에서 eval-logloss로 표시되는 검증 데이터에 대한 logloss 값이 0.25587로 가장 낮다.
이후 126번에서 175번까지 early_stopping_rounds로 지정된 50회 동안 logloss 값은 이보다 향상되지 않았기 때문에(logloss가 작을수록 성능이 좋다) 더 이상 반복하지 않고 멈춘 것이다.
xgboost를 이용해 테스트 데이터 세트 예측 수행
파이썬 래퍼 XGBoost 는 예측을 위해 predict() 메서드를 이용하는데, 예측 결괏값이 아닌 결과를 추정할 수 있는 확률 값을 반환한다. 본 예제는 이진 분류(악성 또는 양성) 이므로, 예측 확률이 0.5보다 크면 1, 그렇지 않으면 0으로 예측 값을 결정하는 로직을 추가하면 된다.
※ 사이킷런 predict() 메서드는 예측 결과 클래스 값(0, 1)을 반환한다.
# xgboost를 이용해 테스트 데이터 세트 예측 수행
pred_probs = xgb_model.predict(dtest)
print('predict() 수행 결괏값을 10개만 표시, 예측 확률 값으로 표시됨')
print(np.round(pred_probs[:10],3))
# 예측 확률 0.5보다 크면 1, 그렇지 않으면 0으로 예측값 결정하여 list 객체인 preds에 저장
preds = [ 1 if x > 0.5 else 0 for x in pred_probs]
print('예측값 10개만 표시:', preds[:10])
◆ 이전에 사용했던 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() 함수를 적용해 XGBoost 예측 성능 평가
get_clf_eval(y_test, preds, pred_probs)
xgboost 패키지에 내장된 시각화 기능 수행
xgboost의 plot_importance() API는 피처의 중요도를 막대그래프 형식으로 나타낸다.
기본 평가 지표로 f스코어를 기반으로 해당 피처의 중요도를 나타낸다.
※ f스코어: 해당 피처가 트리 분할 시 얼마나 자주 사용되었는지를 지표로 나타낸 값
사이킷런은 Estimator 객체의 feature_importances_ 속성을 이용해 직접 시각화 코드를 작성해야 하지만, xgboost 패키지는 plot_importance()를 이용해 바로 피처 중요도를 시각화할 수 있다.
plot_importance() 호출 시 파라미터로 앞에서 학습이 완료된 모델 객체 및 맷플롯립의 ax 객체를 입력하기만 하면 된다.
※ 단, xgboost를 DataFrame이 아닌 Numpy 기반의 피처 데이터로 학습 시에는 Numpy에서 피처명을 제대로 알 수가 없으므로 Y축의 피처명을 나열 시 f0, f1과 같이 피처 순서별로 f자 뒤에 순서를 붙여 피처명을 나타낸다.
# xgboost 패키지에 내장된 시각화 기능 수행
import matplotlib.pyplot as plt
%matplotlib inline
fig, ax = plt.subplots(figsize=(10, 12))
plot_importance(xgb_model, ax=ax)
xgboost와 graphviz()
결정 트리에서 보여준 트리 기반 규칙 구조도 xgboost에서 시각화할 수 있다.
xgboost의 to_graphviz() API를 이용하면 주피터 노트북에 바로 규칙 트리 구조를 그릴 수 있다.
(Graphviz 프로그램과 패키지 설치 선행 필수)
xgboost의 최적 파라미터 추출 cv() API
파이썬 래퍼 XGBoost는 사이킷런의 GridSearchCV와 유사하게 데이터 세트에 대한 교차 검증 수행 후 최적 파라미터를 구할 수 있는 방법을 제공한다.
# xgboost의 최적 파라미터 추출 cv() API
xgboost.cv(params, dtrain, num_boost_round=10, nfold=3, stratified=False, folds=None, metrics=(),
obj=None, feval=None, maximaize=False, early_stopping_rounds=None, fpreproc=None,
as_pandas=True, verbose_eval=None, show_stdv=True, seed=0, callbacks=None, shuffle=True)
params | dict | 부스터 파라미터 |
dtrain | DMatrix | 학습 데이터 |
num_boost_round | int | 부스팅 반복 횟수 |
nfold | int | CV 폴드 개수 |
stratified | boolean | CV 수행 시 층화 표본 추출 수행 여부 |
metrics | string or list of string | CV 수행 시 모니터링할 성능 평가 지표 |
early_stopping_rounds | int | 조기 중단을 활성화시킴 (반복 횟수 지정) |
▶ xgboost.cv의 반환값은 DataFrame 형태
다음 글
'[파이썬 Projects] > <파이썬 머신러닝>' 카테고리의 다른 글
[머신러닝] 앙상블 : LightGBM (0) | 2024.07.04 |
---|---|
[머신러닝] 앙상블 : XG Boost (3) (0) | 2024.07.04 |
[머신러닝] 앙상블 : XG Boost (1) (0) | 2024.07.01 |
[머신러닝] 앙상블 : GBM (0) | 2024.06.30 |
[머신러닝] 앙상블 : 랜덤 포레스트 (0) | 2024.06.27 |