Introduction
지난번에 XGBM의 이론적인 부분들에 대해서 포스팅했다.
너무 길어서 한번 자르고, 이번에는 실제 코드를 써보는 걸 정리해보자!
결국 이론만 알아서는 금방 잊기 쉽기때문에 꼭 코드로 실습해봐야한다.
dlmc 개발그룹에서 XGBoost를 개발하고 있는데,
처음엔 C/C++이었다가, R과 파이썬에서도 사용할 수 있게 호환되었다가,
이후 사이킷런이 흥하면서 사이킷런 wrapper용으로도 XGBoost를 확장했다.
이번엔 사이킷런이 아닌 파이썬 native 코드를 실습해보자!
실습 코드
유방암 데이터세트->DMatrix 변환
import pandas as pd
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
import xgboost as xgb
from xgboost import plot_importance
# 유방암 데이터세트 로드 및 데이터프레임으로 변환
cancer = load_breast_cancer()
df = pd.DataFrame(data = cancer.data, columns = cancer.feature_names)
df['target'] = cancer.target
# 전체의 80%는 학습, 20%는 테스트셋으로 분리
X_train, X_test, y_train, y_test = train_test_split(df.iloc[:,:-1], df.iloc[:,-1], test_size=0.2)
# 80%인 학습을 또다시 9:1로 나눠 검증셋을 만든다.
X_tr, X_val, y_tr, y_val = train_test_split(X_train, y_train, test_size=0.1)
print(X_train.shape , X_test.shape)
print(X_tr.shape, X_val.shape)
# xgboost에 사용하기 위해 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)
데이터셋으로는 위스콘신 유방암 데이터셋을 사용했다.
train_test_split()을 두 번 사용하여, 80:20으로 나누고 학습데이터를 다시 90:10으로 나누었다.
이후 데이터셋 수를 확인하고 DMatrix로 변환하였다.
하이퍼파라미터 세팅과 학습 과정
# 하이퍼파라미터 설정
params = { 'max_depth':3,
'eta': 0.05, # learning rate
'objective':'binary:logistic', # 목적함수: 이진분류
'eval_metric':'logloss' # 로그 로스
}
num_rounds = 400
# 학습 데이터 셋은 'train' 또는 평가 데이터 셋은 'eval' 로 명기합니다.
# 또는 eval_list = [(dval,'eval')] 만 명기해도 무방.
eval_list = [(dtr, 'train'), (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)
# early_stopping_rounds: N번동안 eval-logloss가 더 줄지 않는다면 조기종료
# num_boost_round = 총 N번 돌려라
위의 코드를 보자.
사이킷런과 다르게 하이퍼파라미터들을 딕셔너리 형태로 잡아준 후,
xgb.train() 함수 호출시에 params에 넣어준다.
검증 데이터셋 또한 evals 파라미터에 전달한다.
또한 train() 메소드 호출 시 모델 객체를 반환받는다는 점에 유의하자.
early_stopping_rounds=50의 의미는
검증 데이터셋의 에러 eval-logloss가 50번 반복횟수동안 개선되지 않으면 학습을 조기 종료한다는 뜻이다.
예를들어 early_stopping_rouns=50일 때, 100번 iteration에서 early stopping이 일어났다면
50번째 eval-logloss가 최소값이고 그후 50번동안 eval-logloss가 개선되지 않았음을 의미한다.
예측 결과값 받기
import numpy as np
pred_probs = xgb_model.predict(dtest)
print('predict() 수행 결과값을 10개만 표시, 예측 확률 값으로 표시됨')
print(np.round(pred_probs[:10],3), '\n')
# 예측 확률이 0.5보다 크면 1, 그렇지 않으면 0으로 예측값 결정
preds = [1 if x>0.5 else 0 for x in pred_probs]
print('예측값 10개만 표시:', preds[:10])
Python native xgboost의 predict()는 사이킷런의 predict_proba()와 같이 동작한다.
따라서 위의 작업을 수행했다.
예측결과 평가하기
from sklearn.metrics import confusion_matrix, \
accuracy_score, precision_score, recall_score, f1_score, roc_auc_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_score(y_test, pred_proba)
print('오차행렬')
print(confusion, '\n')
print('accuracy:', np.round(accuracy,3))
print('precision:', np.round(precision,3))
print('recall:', np.round(recall,3))
print('F1:', np.round(f1,3))
print('AUC:', np.round(roc_auc,3))
get_clf_eval(y_test, preds, pred_probs)
예측결과를 실제값과 비교해 평가하기 위해 get_clf_eval() 함수를 작성했다.
결과값에 대한 설명은 딱히 필요 없을 듯 하다.
Feature Importance 시각화
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(10,12))
plot_importance(xgb_model, ax=ax)
첫 실습코드에 추가했던 xgboost의 plot_importance()를 실행한 결과.
여러 피쳐 중에 피쳐중요도가 높은 순으로 plot해주는 편리한 함수다.
Conclusion
XGBoost를 이해하기 위해 코드공부를 했다.
다음번에는 사이킷런의 xgboost를 공부해볼 예정이다.
Reference
파이썬 머신러닝 완벽 가이드 - 권철민
'CS > Python' 카테고리의 다른 글
Ensemble Learning 5: XGBM - 이론 파트 (0) | 2022.12.22 |
---|---|
Ensemble Learning 4: 그래디언트 부스트 GBM (0) | 2022.12.22 |
Ensemble Learning 3: 부스팅 기초, Adaboost (0) | 2022.12.22 |
쉬어가기: GridSearchCV 하이퍼파라미터 튜닝 관련 질문 (0) | 2022.12.22 |
Ensemble learning 2: 배깅 Bagging, 랜덤 포레스트 (0) | 2022.12.16 |
댓글