본문 바로가기
머신러닝 with Python

[머신러닝 with Python] 앙상블(Ensemble) 학습 (4) / XGBoost

by CodeCrafter 2023. 9. 13.
반응형

이번에 알아볼 앙상블 학습은 부스팅(Boosting) 기법 중 대표적인 방법인 XGBoost 입니다. 

 

XGBoost는 트리 기반의 앙상블 학습에서 가장 각광받고 있는 알고리즘 중 하나입니다. 

 

유명한 캐글 경연 대회(Kaggle Contest)에서 상위를 차지한 많은 데이터 과학자가 XGBoost를 이용하면서 널리 알려졌습니다. 이는, 일반적으로 다른 머신러닝보다 뛰어난 예측 성능을 가지고 있는데요 

 

 

1. XGBoost란?

- XGBoost는 eXtreme Gradient Boosting의 약어로, 머신러닝과 데이터 분석에서 널리 사용되는 강력한 앙상블 학습 방법 중 하나입니다.

 

- 특히, 트리 기반의 앙상블 학습 방법 중 하나로서 그 성능과 효율성으로 유명합니다.

 

- XGBoost는 지난 포스팅에서 알아본 GBM(Gradient Boosting Machine) 알고리즘을 개선한 것입니다.

[머신러닝 with Python] 앙상블(Ensemble) 학습 (3) / 부스팅(Boosting) / GBM

 

[머신러닝 with Python] 앙상블(Ensemble) 학습 (3) / 부스팅(Boosting) / GBM

이번 시간에는 지난 시간에 이어서 앙상블(Ensemble) 기법에 대해서 알아보겠습니다. 이번에 알아볼 것은 부스팅 기법에 대해서 알아보겠습니다. 부스팅에도 여러 기법이 존재하지만, 이번 시간에

jaylala.tistory.com

이때, 개선된 사항은 아래와 같습니다.

 

a) Regularization (규제): XGBoost는 L1 (Lasso) 및 L2 (Ridge) 규제를 사용합니다. 이는 모델의 복잡성을 제어하고 과적합을 방지하는 데 도움을 주는데, 이를 통해 모델이 더 안정적으로 학습되며, 일반화 능력이 향상됩니다.

 * L1 규제를 사용하는 Lasso와 L2 규제를 사용하는 Ridge, 그리고 이 둘을 사용하는 Elastic Net은 추가적인 포스팅을 업로드해보겠습니다.

b) 자동 특성 선택(Feature Selection): XGBoost는 트리를 구성하는 과정에서 각 특성(Feature)의 중요도를 계산합니다. 중요한 특성에 더 높은 가중치를 부여하므로 모델의 예측 성능을 향상시킵니다. 또한 중요하지 않은 특성은 자동으로 무시되어 모델이 간결해집니다.

c) 병렬 처리: XGBoost는 데이터 및 트리의 구축 과정에서 병렬 처리를 사용하여 학습 및 예측을 빠르게 수행할 수 있습니다.

d) 가지치기 (Tree Pruning): XGBoost는 가지치기 기법을 사용하여 불필요한 분할을 방지하고 트리의 깊이를 제한함으로써 과적합을 줄입니다. 이로 인해 모델이 더 간결하고 일반화 능력이 향상됩니다.

e) 결측값 처리: XGBoost는 결측값(missing values)을 처리하는 기능을 내장하고 있어, 결측값이 있는 데이터에 대한 처리를 간편하게 수행할 수 있습니다.

f) Early Stopping: 학습 중에 검증 데이터의 성능을 모니터링하고, 모델이 과적합되기 전에 학습을 중단할 수 있는 조기 중지(early stopping) 기능을 제공합니다. 이를 통해 최적의 모델을 빠르게 찾을 수 있습니다.

 

 

XGBoost의 알고리즘이 잘 정리된 wikipedia의 설명으로 이론적인 부분은 대체하겠습니다.

 

2. Python을 활용한 XGBoost 구현 - Breast Cancer 데이터 사용

- 이번에는 파이썬을 활용해 XGBoost를 구현해보겠습니다.

- 이번 구현에사용되는 데이터는 Breast Cancer  입니다

 

1
2
3
4
5
6
7
import numpy as np
import pandas as pd
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
import xgboost as xgb
from sklearn.metrics import accuracy_score
 
cs

* 먼저 데이터 분석에 활용될 numpy와 pandas 라이브러리를 임포트하고

* 사이킷런에서 breast cancer 데이터를 불러왔으며

* 사이킷런에서 train 데이터와 test 데이터를 분리하기 위한 라이브러리를 임포트하고

* xgboost 패키지와 정확도를 계산하기 위한 라이브러리를 불러옵니다.

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Breast Cancer 데이터 로드
data = load_breast_cancer()
X = data.data
y = data.target
 
# 데이터를 훈련 세트와 테스트 세트로 나눔
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
 
# XGBoost 모델 초기화
model = xgb.XGBClassifier()
 
# 모델을 훈련 세트로 훈련
model.fit(X_train, y_train)
 
# 테스트 세트로 예측
y_pred = model.predict(X_test)
 
# 정확도 계산
accuracy = accuracy_score(y_test, y_pred)
print(f'정확도: {accuracy * 100:.2f}%')
cs

* Breast Cancer 데이터를 로드하고

* 이를 train과 test 데이터로 나눈 뒤 

* XGBoost를 Classification 용으로 불러온 뒤, 하이퍼 파라미터들을 기본 값으로 설정합니다.

* 그리고 모델을 train 데이터 셋으로 훈련시키고

* 테스트 세트로 데이터를 예측하고

* 정확도를 계산했습니다.

** train 데이터로 훈련된 xgboost의 test 데이터에 대한 분류 결과는 95.61% 입니다.

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix
 
# Confusion Matrix 계산
cm = confusion_matrix(y_test, y_pred)
 
# Seaborn을 사용하여 Confusion Matrix 시각화
plt.figure(figsize=(86))
sns.heatmap(cm, annot=True, fmt="d", cmap="Blues",
            xticklabels=data.target_names, yticklabels=data.target_names)
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.title('Confusion Matrix')
plt.show()
cs

* 해당 test data에 대한 분류 결과를 confusion matrix로 만들어 나타내보면 위와 같습니다.

* benign을 malignant로 예측한 경우가 2개, malignant를 benign으로 예측한 경우가 3개 나타났습니다.

 

 

1
2
3
4
5
6
# Feature Importance 시각화
plt.figure(figsize=(106))
xgb.plot_importance(model, importance_type='weight', show_values=False, xlabel='Weight')
plt.title('Feature Importance (Weight)')
plt.show()
 
cs

* 해당 분류 모델이 어떠한 변수들에 중점을 두고 분류했는지, Feature Importance로 확인해봤습니다. 가장 큰 영향을 미친 것은 f21이라는 변수이며, 그 다음으로는 f13, f1 ..... 순임을 알 수 있습니다. 

 

 

1
2
3
4
5
6
7
8
pip install shap
import shap
# SHAP 값을 계산
explainer = shap.Explainer(model)
shap_values = explainer(X_test)
# SHAP Summary Plot을 생성
shap.summary_plot(shap_values, X_test, feature_names=data.feature_names, show=False)
 
cs

* feature importance만으로는 각 데이터들이 결과 예측에 대한 방향성(+ 또는 -)를 알 수 없기 때문에, SHAP value를 통해 알아보았습니다.

* 가장 영향력이 큰 mean concave points라는 변수의 예시를 통해서 결과를 해석해보면,

  해당 변수의 경우, 변수의 값이 클수록(빨간색에 가까울수록) 결과 값 예측에 음(-)의 영향력을 보여주며 변수의 값이 작을수록(파란색에 가까울수록) 결과 값 예측에 양(+)의 영향력을 보여줌을 알 수 있습니다.

  즉, 해당 변수는 값이 클수록 0(benign)이 예측되도록 해주는 변수라는 의미를 가지고 있습니다.

 

 

 

 

다음은 모델의 성능을 GridSearchCV를 통해서 향상시켜보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from sklearn.model_selection import GridSearchCV
 
param_grid = {
    'learning_rate': [0.010.10.2],
    'max_depth': [345],
    'n_estimators': [100200300]
}
 
grid_search = GridSearchCV(estimator=xgb.XGBClassifier(),
                           param_grid=param_grid,
                           scoring='accuracy',
                           cv=5,
                           n_jobs=-1,
                           verbose=2)
 
grid_search.fit(X_train, y_train)
 
print("최적 하이퍼파라미터:", grid_search.best_params_)
 
 
cs

*이때 튜닝할 파라미터는 learning rate(학습률 / Gradient Descent를 할 때 step size를 의미)와 결정트리의 최대 깊이, 그리고 학습할 트리의 개수를 정하는 n_estimators를 3가지의 범주로 정해서 GridSearch CV를 해보았습니다.

 

 

1
2
3
4
best_model = grid_search.best_estimator_
y_pred = best_model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f'최적 모델 정확도: {accuracy * 100:.2f}%')
cs

* 결과는 96.49%로 테스트 데이터를 분류했고, 이는 기존 기본모델보다 약 1% 정도 분류 결과를 향상시킨 것임을 알 수 있습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
# Confusion Matrix 계산
cm = confusion_matrix(y_test, y_pred)
 
# Seaborn을 사용하여 Confusion Matrix 시각화
plt.figure(figsize=(86))
sns.heatmap(cm, annot=True, fmt="d", cmap="Blues",
            xticklabels=data.target_names, yticklabels=data.target_names)
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.title('Confusion Matrix')
plt.show()
 
cs

* 이를 Confusion Matrix를 통해 결과를 알아보면, 기본 모델보다 benign 클래스를 malginant로 예측하는 경우를 1개 더 줄여주었습니다.

 

 

*아래 내용은 해당 모델의 학습결과를 통해 변수 중요도(Feature Importance)와 SHAP value를 계산해본 것입니다.

 

1
2
3
4
5
# Feature Importance 시각화
plt.figure(figsize=(106))
xgb.plot_importance(model, importance_type='weight', show_values=False, xlabel='Weight')
plt.title('Feature Importance (Weight)')
plt.show()
cs

 

1
2
3
4
5
6
7
8
9
import shap
 
# SHAP 값을 계산
explainer = shap.Explainer(model)
shap_values = explainer(X_test)
 
# SHAP Summary Plot을 생성
shap.summary_plot(shap_values, X_test, feature_names=data.feature_names, show=False)
 
cs

 

 

 포스팅이 길어지다보니 포스팅에 포함된 내용 하나하나를 자세히 다루기에는 제한되었는데요. 꼭 짚고 넘어가야할 요소들은 추후 포스팅을 통해서 더 알아보도록 하겠습니다

반응형

댓글