본문 바로가기
머신러닝/앙상블 기법

앙상블 기법 - Boosting algorithm - GBM, XGBoost, LGBM

by 미생22 2024. 5. 23.
728x90

우리가 원하는 결과를 얻는 과정이 길 수 있습니다. Gradient가 붙으면 보통 계산하는 과정이 깁니다.

 

Boosting algorithm은 여러개의 약한 학습기 (week learner)를 순차적으로 학습-예측 하면서 잘못 예측한 데이터에 가중치를 부여해서 오류를 개선해나가는 방식이었습니다.

* 부스팅 알고리즘은 앙상블 기법의 한 종류입니다. 앙상블 기법은 여러 개의 모델을 결합하여 더 나은 성능을 내는 방법론을 말합니다. 앙상블 기법에는 대표적으로 배깅(Bagging)과 부스팅(Boosting)이 있습니다.

*부스팅 알고리즘의 대표적인 예는 다음과 같습니다:

  1. GBM (Gradient Boosting Machine): 경사 하강법을 사용하여 모델을 순차적으로 학습시키고 각 단계에서 오류를 최소화하는 방향으로 모델을 개선합니다.
  2. XGBoost (Extreme Gradient Boosting): GBM의 확장판으로, 더 빠른 학습 속도와 효율성을 제공하며, 정규화와 같은 추가 기능으로 과적합을 방지합니다.
  3. LightGBM (Light Gradient Boosting Machine): XGBoost보다 더 빠른 학습 속도를 제공하며, 메모리 사용량을 줄이고 대규모 데이터셋에 적합하도록 설계되었습니다.

이들 부스팅 알고리즘은 각기 다른 방식으로 성능을 최적화하고, 과적합을 방지하며, 학습 속도를 개선하는 다양한 기술들을 포함하고 있습니다.

GBM은 가중치를 업데이트 할 때 경사하강법 (Gradient Descent)을 이용하는 것이 큰 차이입니다.

 

지난 시간에 가져온 HAR 데이터를 가지고 시도해보겠습니다.

 

 

 

 

 

 

 

 

?learning rate는?

learning_rate는 주로 부스팅 알고리즘에서 중요한 하이퍼파라미터로, 각 단계에서 새롭게 추가되는 모델이 이전 모델의 예측을 얼마나 보정할지를 결정하는 매개변수입니다. learning_rate는 모델이 학습하는 속도를 제어하며, 작은 값을 설정하면 모델이 느리게 학습하고 큰 값을 설정하면 빠르게 학습합니다.

부스팅 알고리즘에서의 역할

  • Gradient Boosting Machine (GBM)
  • XGBoost
  • LightGBM

이와 같은 알고리즘에서 learning_rate는 각 단계에서 추가되는 약한 학습기(예: 결정 트리)의 기여도를 줄여줍니다. 즉, 각 학습기의 예측 값을 learning_rate 값만큼 곱한 후 기존 예측에 더합니다. 작은 learning_rate 값을 사용하면 모델이 더 천천히 학습하지만, 학습 과정에서 더 세밀하게 조정됩니다. 반면, 큰 learning_rate 값을 사용하면 모델이 더 빠르게 학습하지만, 잘못된 방향으로 학습될 위험이 있습니다.

 

이전 HAR 데이터를 가지고 각각을 돌려보겠습니다.

 

import pandas as pd
import matplotlib.pyplot as plt

url = 'https://raw.githubusercontent.com/PinkWink/ML_tutorial/master/dataset/HAR_dataset/features.txt'
feature_name_df = pd.read_csv(url, sep='\s+', header=None, names=['column_index', 'column_name'])
#txt도 read_csv로 읽을 수 있습니다.
#\s는 공백 한칸, \s+는 공백 여러칸입니다.

feature_name = feature_name_df.iloc[:, 1].values.tolist()

X_train = pd.read_csv('https://raw.githubusercontent.com/PinkWink/ML_tutorial/master/dataset/HAR_dataset/train/X_train.txt', sep='\s+', header=None)
X_test = pd.read_csv('https://raw.githubusercontent.com/PinkWink/ML_tutorial/master/dataset/HAR_dataset/test/X_test.txt', sep='\s+', header=None)

X_train.columns = feature_name
X_test.columns = feature_name

y_train = pd.read_csv('https://raw.githubusercontent.com/PinkWink/ML_tutorial/master/dataset/HAR_dataset/train/y_train.txt', sep='\s+', header=None, names=['action'])
y_test = pd.read_csv('https://raw.githubusercontent.com/PinkWink/ML_tutorial/master/dataset/HAR_dataset/test/y_test.txt', sep='\s+', header=None, names=['action'])

 

 

필요한 모듈을 import 시키겠습니다.

 

from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import accuracy_score
import time
import warnings

warnings.filterwarnings('ignore')

 

start_time = time.time()

gb_clf = GradientBoostingClassifier()
gb_clf.fit(X_train, y_train)
gb_pred = gb_clf.predict(X_test)

print('ACC : ',accuracy_score(y_test, gb_pred))
print('Fit time : ', time.time() - start_time)

ACC :  0.9392602646759416
Fit time :  1400.0743038654327

 

라는 결과가 나옵니다.

acc가 93.9%, 계산시간은 20분정도 나옵니다.
일반적으로 GBM이 성능자체는 랜덤포레스트보다 좋다고 알려져있는데, 이전에 HAR 데이터에서 random forest로 grid search cv를 돌렸을 때 92%정도 나왔었습니다.
scikit learn의 GBM은 속도가 아주 느린 것으로 알려져있어서 20분정도 걸리나봅니다.

Grid search로 GBM을 더 찾아보겠습니다.

 

from sklearn.model_selection import GridSearchCV

params = {
    'n_estimators' : [100, 500], #100개, 500개의 decision tree를 써라.
    'learning_rate' : [0.05, 0.1]
}

start_time = time.time()
grid = GridSearchCV(gb_clf, param_grid=params, cv=2, n_jobs=-1)
grid.fit(X_train)
print('Fit time : ', time.time() - start_time)

 

XGBoost는 트리 기반의 앙상블 학습에서 가장 각광받는 알고리즘 중 하나입니다.
GBM 기반의 알고리즘인데, GBM의 느린 속도를 다양한 규제를 통해 해결했습니다.
특히 병렬 학습이 가능하도록 설계되었다는게 큰 특징입니다.
XGBoost는 반복 수행 시마다 내부적으로 학습데이터와 검증데이터를 교차검증을 수행합니다.
교차검증을 통해 최적화되면 반복을 중단하는 조기 중단 기능을 가지고있습니다.

 

!pip install xgboost 혹은 conda install xgboost 를 통해 다운로드시켜줍니다.

옵션은 다음과 같습니다.

- nthread : CPU로 돌릴 때 thread 개수를 조정합니다. 디폴트가 전체 스레드를 사용하는 것으로 따로 조정하지 않아도 됩니다.
- eta : GBM의 학습률입니다. XGBoost는 별도의 모듈이라 learning rate가 아니라 eta라고 합니다.
- num_boost_rounds : n_estimators와 같은 파라미터입니다.
- max_depth

 

from xgboost import XGBClassifier

start_time = time.time()
xgb = XGBClassifier(n_estimators=400, learning_rate=0.1, max_depth=3)
xgb.fit(X_train.values, y_train)
print('Fit time : ', time.time() - start_time)

여기서 꼭 기억해야할 점은 XGBoost는 X_test의 values를 던져줘야한다는 것니다

accuracy_score(y_test, xgb.predict(X_test.values))

 

94%정도 나옵니다.

 

XGBoost의 특징인 조기 종료 조건과 검증데이터를 지정할 수 있습니다.

먼저 종료조건을 주기 위해서는 따로 validation data를 만들어야합니다. 우리는 그냥 test 데이터를 검증 데이터로 쓰겠습니다.

evals = [(X_test.values, y_test)]

start_time = time.time()
xgb = XGBClassifier(n_estimators=400, learning_rate=0.1, max_depth=3)
xgb.fit(X_train.values, y_train, early_stopping_rounds=10, eval_set=evals)

 

조기종료와 검증데이터는 fit에 옵션으로 줍니다.
early_stopping_rounds는 XGBoost의 특징인 조기종료 관련 옵션입니다. 비슷한 범위 값이 10번 나오면 종료한다는 겁니다.
eval_set은 검증 셋이고 미리 만들어둔 evals에 있다고 합니다.

 

accuracy_score(y_test, xgb.predict(X_test.values))

 

Light GBM

Light GBM은 XGBoost와 함께 부스팅 계열에서 가장 각광받는 알고리즘입니다.
속도가 빠르다는 장점이 있지만, 적은 수의 데이터에는 성능이 매우 나빠집니다.(일반적으로 10000건 이상의 데이터가 필요하다고 함)
GPU버전도 존재합니다. !pip install lightgbm 명령어를 통해 다운로드 받습니다.

 

from lightgbm import LGBMClassifier

start_time = time.time()
lgbm = LGBMClassifier(n_estimators=400)
lgbm.fit(X_train.values, y_train, early_stopping_rounds=20, eval_set=evals)

print('Fit time : ', time.time()-start_time)

 

LightGBM도 마찬가지로 X_train의 values를 던져줍니다.

 

accuracy_score(y_test, lgbm.predict(X_test.values))

 

 

728x90