이번에 알아볼 앙상블 학습은 부스팅(Boosting) 기법 중 대표적인 방법인 XGBoost 입니다.
XGBoost는 트리 기반의 앙상블 학습에서 가장 각광받고 있는 알고리즘 중 하나입니다.
유명한 캐글 경연 대회(Kaggle Contest)에서 상위를 차지한 많은 데이터 과학자가 XGBoost를 이용하면서 널리 알려졌습니다. 이는, 일반적으로 다른 머신러닝보다 뛰어난 예측 성능을 가지고 있는데요
1. XGBoost란?
- XGBoost는 eXtreme Gradient Boosting의 약어로, 머신러닝과 데이터 분석에서 널리 사용되는 강력한 앙상블 학습 방법 중 하나입니다.
- 특히, 트리 기반의 앙상블 학습 방법 중 하나로서 그 성능과 효율성으로 유명합니다.
- XGBoost는 지난 포스팅에서 알아본 GBM(Gradient Boosting Machine) 알고리즘을 개선한 것입니다.
[머신러닝 with Python] 앙상블(Ensemble) 학습 (3) / 부스팅(Boosting) / GBM
이때, 개선된 사항은 아래와 같습니다.
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=(8, 6))
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=(10, 6))
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.01, 0.1, 0.2],
'max_depth': [3, 4, 5],
'n_estimators': [100, 200, 300]
}
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=(8, 6))
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=(10, 6))
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 |
포스팅이 길어지다보니 포스팅에 포함된 내용 하나하나를 자세히 다루기에는 제한되었는데요. 꼭 짚고 넘어가야할 요소들은 추후 포스팅을 통해서 더 알아보도록 하겠습니다
댓글