from IPython.core.display import display, HTML
display(HTML("<style> .container{width:90% !important;}</style>"))
1. XGBoost(eXtra Gradient Boost)의 개요¶
트리 기반의 알고리즘의 앙상블 학습에서 각광받는 알고리즘 중 하나입니다.
GBM에 기반하고 있지만, GBM의 단점인 느린 수행시간, 과적합 규제 등을 해결한 알고리즘입니다.
XGBoost의 주요장점¶
(1) 뛰어난 예측 성능
(2) GBM 대비 빠른 수행 시간
(3) 과적합 규제(Overfitting Regularization)
(4) Tree pruning(트리 가지치기) : 긍정 이득이 없는 분할을 가지치기해서 분할 수를 줄임
(5) 자체 내장된 교차 검증
- 반복 수행시마다 내부적으로 교차검증을 수행해 최적회된 반복 수행횟수를 가질 수 있음
- 지정된 반복횟수가 아니라 교차검증을 통해 평가 데이트세트의 평가 값이 최적화되면 반복을 중간에 멈출 수 있는 기능이 있음
(6) 결손값 자체 처리
XGBoost는 독자적인 XGBoost 모듈과 사이킷런 프레임워크 기반의 모듈이 존재합니다.
독자적인 모듈은 고유의 API와 하이퍼파라미터를 사용하지만, 사이킷런 기반 모듈에서는 다른 Estimator와 동일한 사용법을 가지고 있습니다.
2. XGBoost의 하이퍼 파라미터¶
일반 파라미터¶
: 일반적으로 실행 시 스레드의 개수나 silent 모드 등의 선택을 위한 파라미터, default 값을 바꾸는 일은 거의 없음
파라미터 명 | 설명 |
---|---|
booster | - gbtree(tree based model) 또는 gblinear(linear model) 중 선택 - Default = 'gbtree' |
silent | - Default = 1 - 출력 메시지를 나타내고 싶지 않을 경우 1로 설정 |
nthread | - CPU 실행 스레드 개수 조정 - Default는 전체 다 사용하는 것 - 멀티코어/스레드 CPU 시스템에서 일부CPU만 사용할 때 변경 |
주요 부스터 파라미터¶
: 트리 최적화, 부스팅, regularization 등과 관련된 파라미터를 지칭
파라미터 명 (파이썬 래퍼) |
파라미터명 (사이킷런 래퍼) |
설명 |
---|---|---|
eta (0.3) |
learning rate (0.1) |
- GBM의 learning rate와 같은 파라미터 - 범위: 0 ~ 1 |
num_boost_around (10) |
n_estimators (100) |
- 생성할 weak learner의 수 |
min_child_weight (1) |
min_child_weight (1) |
- GBM의 min_samples_leaf와 유사 - 관측치에 대한 가중치 합의 최소를 말하지만 GBM에서는 관측치 수에 대한 최소를 의미 - 과적합 조절 용도 - 범위: 0 ~ ∞ |
gamma (0) |
min_split_loss (0) |
- 리프노드의 추가분할을 결정할 최소손실 감소값 - 해당값보다 손실이 크게 감소할 때 분리 - 값이 클수록 과적합 감소효과 - 범위: 0 ~ ∞ |
max_depth (6) |
max_depth (3) |
- 트리 기반 알고리즘의 max_depth와 동일 - 0을 지정하면 깊이의 제한이 없음 - 너무 크면 과적합(통상 3~10정도 적용) - 범위: 0 ~ ∞ |
sub_sample (1) |
subsample (1) |
- GBM의 subsample과 동일 - 데이터 샘플링 비율 지정(과적합 제어) - 일반적으로 0.5~1 사이의 값을 사용 - 범위: 0 ~ 1 |
colsample_bytree (1) |
colsample_bytree (1) |
- GBM의 max_features와 유사 - 트리 생성에 필요한 피처의 샘플링에 사용 - 피처가 많을 때 과적합 조절에 사용 - 범위: 0 ~ 1 |
lambda (1) |
reg_lambda (1) |
- L2 Regularization 적용 값 - 피처 개수가 많을 때 적용을 검토 - 클수록 과적합 감소 효과 |
alpha (0) |
reg_alpha (0) |
- L1 Regularization 적용 값 - 피처 개수가 많을 때 적용을 검토 - 클수록 과적합 감소 효과 |
scale_pos_weight (1) |
scale_pos_weight (1) |
- 불균형 데이터셋의 균형을 유지 |
학습 태스크 파라미터¶
: 학습 수행 시의 객체함수, 평가를 위한 지표 등을 설정하는 파라미터
파라미터 명 | 설명 |
---|---|
objective | - ‘reg:linear’ : 회귀 - binary:logistic : 이진분류 - multi:softmax : 다중분류, 클래스 반환 - multi:softprob : 다중분류, 확륣반환 |
eval_metric | - 검증에 사용되는 함수정의 - 회귀 분석인 경우 'rmse'를, 클래스 분류 문제인 경우 'error' ---------------------------------------------------- - rmse : Root Mean Squared Error - mae : mean absolute error - logloss : Negative log-likelihood - error : binary classification error rate - merror : multiclass classification error rate - mlogloss: Multiclass logloss - auc: Area Under Curve |
과적합 제어¶
- eta 값을 낮춥니다.(0.01 ~ 0.1) → eta 값을 낮추면 num_boost_round(n_estimator)를 반대로 높여주어야 합니다.
- max_depth 값을 낮춥니다.
- min_child_weight 값을 높입니다.
- gamma 값을 높입니다.
- subsample과 colsample_bytree를 낮춥니다.
※ Early Stopping 기능 :¶
GBM의 경우 n_estimators에 지정된 횟수만큼 학습을 끝까지 수행하지만, XGB의 경우 오류가 더 이상 개선되지 않으면 수행을 중지
n_estimators 를 200으로 설정하고, 조기 중단 파라미터 값을 50으로 설정하면, 1부터 200회까지 부스팅을 반복하다가
50회를 반복하는 동안 학습오류가 감소하지 않으면 더 이상 부스팅을 진행하지 않고 종료합니다.
(가령 100회에서 학습오류 값이 0.8인데 101~150회 반복하는 동안 예측 오류가 0.8보다 작은 값이 하나도 없으면 부스팅을 종료)
3. 파이썬 래퍼 XGBoost 적용¶
위스콘신 유방암 데이터 세트를 활용한 API 사용법
import xgboost as xgb ## XGBoost 불러오기
from xgboost import plot_importance ## Feature Importance를 불러오기 위함
import pandas as pd
import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix, accuracy_score, precision_score, recall_score
from sklearn.metrics import confusion_matrix, f1_score, roc_auc_score
import warnings
warnings.filterwarnings('ignore')
dataset = load_breast_cancer()
X_features = dataset.data
y_label = dataset.target
cancer_df = pd.DataFrame(data=X_features, columns = dataset.feature_names)
cancer_df['target'] = y_label
cancer_df.head(3)
위의 데이터셋에서 악성종양은 0, 양성은 1 값으로 되어 있음
print(dataset.target_names)
print(cancer_df['target'].value_counts())
# 전체 데이터셋을 학습용 80%, 테스트용 20%로 분할
X_train, X_test, y_train, y_test = train_test_split(X_features, y_label, test_size=0.2, random_state=156)
print(X_train.shape, X_test.shape)
파이썬래퍼 XGBoost와 사이킷런래퍼 XGBoost의 가장 큰 차이는
파이썬래퍼는 학습용과 테스트 데이터 세트를 위해 별도의 DMatrix를 생성한다는 것입니다.
DMatrix : 넘파이 입력 파라미터를 받아서 만들어지는 XGBoost만의 전용 데이터 세트
- 주요 입력 파라미터는 data(피처 데이터 세트)와 label
(분류: 레이블 데이터 세트/회귀: 숫자형인 종속값 데이터 세트) - 판다스의 DataFrame으로 데이터 인터페이스를 하기 위해서는 DataFrame.values를 이용해 넘파이로 일차변환 한 뒤에 DMatrix 변환을 적용
# 넘파이 형태의 학습 데이터 세트와 테스트 데이터를 DMatrix로 변환하는 예제
dtrain = xgb.DMatrix(data=X_train, label = y_train)
dtest = xgb.DMatrix(data=X_test, label=y_test)
# max_depth = 3, 학습률은 0.1, 예제가 이진분류이므로 목적함수(objective)는 binary:logistic(이진 로지스틱)
# 오류함수의 평가성능지표는 logloss
# 부스팅 반복횟수는 400
# 조기중단을 위한 최소 반복횟수는 100
params = {'max_depth' : 3,
'eta' : 0.1,
'objective' : 'binary:logistic',
'eval_metric' : 'logloss',
'early_stoppings' : 100 }
num_rounds = 400
파이썬래퍼 XGBoost에서 하이퍼 파라미터를 xgboost 모듈의 train( ) 함수에 파라미터로 전달합니다.
(사이킷런 래퍼는 Estimator 생성자를 하이퍼 파라미터로 전달)
early_stopping_rounds 파라미터 : 조기 중단을 위한 라운드를 설정합니다.
조기 중단 기능 수행을 위해서는 반드시 eval_set과 eval_metric이 함께 설정되어야 합니다.
- eval_set : 성능평가를 위한 평가용 데이터 세트를 설정
- eval_metric : 평가 세트에 적용할 성능 평가 방법
(반복마다 eval_set으로 지정된 데이터 세트에서 eval_metric의 지정된 평가 지표로 예측 오류를 측정)
train() 함수를 호출하면 xgboost가 반복 시마다 evals에 표시된 데이터 세트에 대해 평가 지표를 출력합니다.
그 후 학습이 완료된 모델 객체를 반환합니다.
# train 데이터 세트는 'train', evaluation(test) 데이터 세트는 'eval' 로 명기
wlist = [(dtrain, 'train'), (dtest,'eval')]
# 하이퍼 파라미터와 early stopping 파라미터를 train() 함수의 파라미터로 전달
xgb_model = xgb.train(params = params, dtrain=dtrain, num_boost_round=num_rounds, evals=wlist)
train( ) 을 통해 학습을 수행하면 반복시 train-logloss와 eval-logloss가 지속적으로 감소합니다.
xgboost를 이용해 학습이 완료됐으면 predict() 메서드를 이용해 예측을 수행합니다.
여기서 파이썬 래퍼는 예측 결과를 추정할 수 있는 호가률 값을 반환합니다.(반면 사이킷런 래퍼는 클래스 값을 반환)
pred_probs = xgb_model.predict(dtest)
print('predict() 수행 결과값을 10개만 표시, 예측 확률 값으로 표시됨')
print(np.round(pred_probs[:10], 3))
# 예측 확률이 0.5보다 크면 1, 그렇지 않으면 0으로 예측값 결정해 리스트 객체인 preds에 저장
preds = [ 1 if x > 0.5 else 0 for x in pred_probs]
print('예측값 10개만 표시: ', preds[:10])
# 혼동행렬, 정확도, 정밀도, 재현율, F1, AUC 불러오기
def get_clf_eval(y_test, y_pred):
confusion = confusion_matrix(y_test, y_pred)
accuracy = accuracy_score(y_test, y_pred)
precision = precision_score(y_test, y_pred)
recall = recall_score(y_test, y_pred)
F1 = f1_score(y_test, y_pred)
AUC = roc_auc_score(y_test, y_pred)
print('오차행렬:\n', confusion)
print('\n정확도: {:.4f}'.format(accuracy))
print('정밀도: {:.4f}'.format(precision))
print('재현율: {:.4f}'.format(recall))
print('F1: {:.4f}'.format(F1))
print('AUC: {:.4f}'.format(AUC))
get_clf_eval(y_test, preds)
Feature importance를 시각화할 때,
→ 기본 평가 지료로 f1스코어를 기반으로 각 feature의 중요도를 나타냅니다.
→ 사이킷런 래퍼는 estimator 객체의 featureimportances 속성을 이용해 시각화 코드를 직접 작성해야 합니다.
→ 반면, 파이썬 래퍼는 plot_importance()를 이용해 바로 피처 중요 코드를 시각화 할 수 있습니다.
from xgboost import plot_importance
import matplotlib.pyplot as plt
%matplotlib inline
fig, ax = plt.subplots(figsize=(10, 12))
plot_importance(xgb_model, ax=ax)
다만, xgboost 넘파이 기반의 피처 데이터로 학습 시에 피처명을 제대로 알 수 없으므로
피처별로 f자 뒤에 순서를 붙여 X축에 피처들로 나열합니다.(f0는 첫번째 피처, f1는 두번째 피처를 의미)
파이썬 래퍼의 교차 검증 수행 및 최적 파라미터 구하기¶
: xgboost는 사이킷런의 GridSearchCV와 유사하게 cv( )를 API로 제공합니다.
xgb.cv(params, dtrain, num_boost_round=10, nfold=3, stratified=False,
folds=None, metrics=(),obj=None, feval=None, maximize=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(bool) : CV수행시 샘플을 균등하게 추출할지 여부
- metrics(string or list of strings) : CV 수행시 모니터링할 성능 평가 지표
- early_stopping_rounds(int) : 조기중단을 활성화시킴. 반복횟수 지정
xgv.cv의 반환 값은 데이터프레임 형태입니다.
4. 사이킷런 래퍼 XGBoost의 개요 및 적용¶
특징¶
- 사이킷런의 기본 Estimator를 이용해 만들어 fit()과 predict()만으로 학습과 예측이 가능
- GridSearchCV,Pipeline 등 사이킷런의 유틸리티를 그대로 사용 가능
- 분류 : XGBClassifier / 회귀 : XGBRegressor
파이썬 래퍼와 비교시 달라진 파라미터¶
- eta → learning_rate
- sub_sample → subsample
- lambda → reg_lambda
- alpha → reg_alpha
- num_boost_round → n_estimators
위와 동일하게 위스콘신 유방암 데이터를 통한 예측
# max_depth = 3, 학습률은 0.1, 예제가 이진분류이므로 목적함수(objective)는 binary:logistic(이진 로지스틱)
# 부스팅 반복횟수는 400
from xgboost import XGBClassifier
xgb_wrapper = XGBClassifier(n_estimators = 400, learning_rate = 0.1, max_depth = 3)
xgb_wrapper.fit(X_train, y_train)
w_preds = xgb_wrapper.predict(X_test)
# 예측 결과 확인
get_clf_eval(y_test, w_preds)
앞선 파이썬 래퍼 XGBoost와 동일한 결과가 나옵니다.
사이킷런 래퍼 XGBoost에서도 조기 중단 기능을 수행할 수 있는데 fit( )에 해당 파라미터를 입력하면 됩니다.
→ early_stopping_rounds, eval_metrics, eval_set
# max_depth = 3, 학습률은 0.1, 예제가 이진분류이므로 목적함수(objective)는 binary:logistic(이진 로지스틱)
# 오류함수의 평가성능지표는 logloss
# 부스팅 반복횟수는 400
# 조기중단을 위한 최소 반복횟수는 100
# 아래 예제에서는 평가를 위한 데이터 세트로 테스트 데이터 세트를 사용했지만, 바람직하진 않습니다.
# 테스트 데이터 세트는 학습에 완전히 알려지지 않은 데이터 세트를 사용해야 합니다.
# 평가에 테스트 데이터 세트를 사용하면 학습시에 미리 참고가 되어 과적합할 수 있기 때문입니다.
xgb_wrapper = XGBClassifier(n_estimators = 400, learning_rate = 0.1 , max_depth = 3)
evals = [(X_test, y_test)]
xgb_wrapper.fit(X_train, y_train, early_stopping_rounds = 100,
eval_metric="logloss", eval_set = evals, verbose=True)
ws100_preds = xgb_wrapper.predict(X_test)
위의 결과에서는 211번 반복시 logloss가 0.085593 이었는데 이후 100번 반복되는 311번째까지
성능평가 지수가 향상되지 않았기 때문에 더 이상 반복하지 않고 멈추게 되었습니다.
get_clf_eval(y_test, ws100_preds)
조기 중단값을 너무 급격하게 줄이면 성능이 향상될 여지가 있음에도 학습을 멈춰 예측 성능이 저하될 수 있습니다.
# early_stopping_rounds = 10 으로 설정하고 재학습
xgb_wrapper.fit(X_train, y_train, early_stopping_rounds = 10,
eval_metric='logloss', eval_set=evals , verbose=True)
ws10_preds = xgb_wrapper.predict(X_test)
get_clf_eval(y_test, ws10_preds)
62번째까지만 수행이 되고 종료되었는데, 이렇게 학습된 모델로 예측한 결과, 정확도는 약 0.9561로
ealry_stopping_rounds = 100일 때의 정확도인 0.9649보다 낮게 나왔습니다.
모델 예측 후 피처 중요도를 동일하게 plot_importance() API를 통해 시각화할 수 있습니다.
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)
'Machine Learning > 파이썬 머신러닝 완벽가이드 학습' 카테고리의 다른 글
[Chapter 4. 분류] 예제-산탄데르 고객만족 예측 문제 (2) | 2019.11.04 |
---|---|
[Chapter 4. 분류] LightGBM (1) | 2019.11.03 |
[Chapter 4. 분류] 부스팅알고리즘(AdaBoost, GBM) (0) | 2019.10.20 |
[Chapter 4. 분류] 랜덤포레스트(Random Forest) (1) | 2019.10.19 |
[Chapter 4. 분류] 앙상블 학습 (0) | 2019.10.14 |