Boosting이란?
Bagging VS Boosting
- 앙상블 학습은 여러 기본 모델을 학습하고 모델들의 예측을 합하여 최종 예측을 내는 방식
- 단일 모델 사용 기법의 과적합, 과소적합 문제를 해결하여 더 나은 일반화 성능을 내기 위해 많이 사용
- 기본 컨셉 성능이 뛰어나 강력한 단일 모델을 구축하기 위해 노력하는 대신 약한 모델들을 학습하고 지혜롭게 조합하는 것
- 대표적인 앙상블 기법은 Bagging & boosting
Bagging
- 좁은 의미 = 복원추출 → weak learner 학습 → weak learner들의 예측값을 합치는 과정
- 넓은 의미 = 기본 모델(weak learner)들을 병렬로 학습하고 평등하게 예측값을 합치는 과정
- 기본 모델(weak learner)들이 학습 시 상호 영향을 주고받지 않고, 독립적, 벙렬적으로 학습
- 대표적으로 Random Forest Model
Bagging은 모델의 분산을 줄여 과적합을 피하도록 한다
- 여러 기본 모델(weak learner)들의 서로 다른 양상으로 발생하는 오차들이 상쇄되어 과적합을 피하는 원리
Boosting
- Boosting은 Bagging과 달리, 모델들이 순차적으로 학습 지금까지 학습된 모델이 잘 예측하지 못하는 부분에 집중해서 다음 모델을 학습
- 대표적으로 AdaBoost, Gradient Boosting 모델이 있음
Boosting은 과정을 반복할 수록 최종 모델의 복잡도를 증가시켜, 모델의 편향을 줄여 과소적합을 방지
- 모델들이 순차적으로 학습되는 과정에서 전체 모델은 점차 데이터의 세밀한 곳까지 꼼꼼히 볼 수 있게 되며, 최종 예측 값은 점점 정확해진다
Bagging VS Boosting
Bagging Boosting
Weak Learner 학습 | 각 모델이 독립적이고 병렬적으로 학습 | 이전 모델의 오류를 고려하여 다음 모델이 순차적으로 학습 |
목적 | Variance 감소, 과적합 해결 | Bias 감소, 과소적합 해결 |
예시 | Random Forest | AdaBoost, Gradient Boosting |
AdaBoost
- 초기에 개발된 Boosting 알고리즘
- 분류 문제에 적합한 알고리즘, 다만 Gradient Boosting 보다 이상치에 민감하고 성능이 떨어져 자주 사용 X
- 각 단계별로 데이터 셋으로부터 데이터를 샘플링하여 학습
- 다음 모델이 학습될 때, 이전 모델이 잘못 분류한 관측치가 샘플링될 확률을 높임
- 결과적으로 모델들이 순차적으로 학습되며 이전 모델의 성능을 보완하는 양상으로 학습됩니다.
Step 0. (Init) 모든 관측치에 대해 가중치를 동일하게 설정합니다.
- 가중치는 각 관측치들이 샘플링될 확률이 됩니다.
Step 1. (weak learner 학습) 관측치를 복원추출하여 weak learner Di을 학습하고 +1, -1 분류를 진행합니다.
Step 2. (가중치 업데이트) 잘못 분류된 관측치에 가중치를 부여하여 다음 과정에서 샘플링이 더 잘 되도록 합니다.
Step 3. Step 1~2 과정을 n회 반복합니다.
Step 4. (최종 예측) weak learner들(D1, ..., Dn)을 결합하여 최종 예측을 수행합니다.
- 이때 각 weak learner들의 분류 성능에 따라 각 weak learner들의 예측치의 가중치를 다르게 주어 가중합합니다
Gradient Boosting
- 회귀, 분류 문제 모두 사용할 수 있는 알고리즘
- 매우 강력한 성능을 자랑하여 Kaggle이나 현업에서 인가가 높습니다
- 구현 라이브러리도 많아 쉽게 모델을 구축할 수 있다
Gradient Boosting은 틀린 데이터에 집중하기 위해, 가중 샘플링을 하는 대신 Residual를 학습
- 다음 모델이 이전 모델의 **잔차(Residual)**를 학습하는 구조입니다. 이는 잔차가 큰 관측치를 더 학습하도록 하는 효과가 있으며, 이전 모델이 틀린 만큼을 직접 학습하며 이전 모델을 순차적으로 보완합니다.
Gradient Boosting python library
- sklearn 외에 부스팅이 구현된 여러가지 라이브러리를 사용할 수 있습니다:
- scikit-learn Gradient Tree Boosting — 상대적으로 속도가 느릴 수 있습니다.
- Anaconda: already installed
- Google Colab: already installed
- xgboost — 결측값을 수용하며, monotonic constraints를 강제할 수 있습니다.
- Anaconda, Mac/Linux: conda install -c conda-forge xgboost
- Windows: conda install -c anaconda py-xgboost
- Google Colab: already installed
- LightGBM — 결측값을 수용하며, monotonic constraints를 강제할 수 있습니다.
- Anaconda: conda install -c conda-forge lightgbm
- Google Colab: already installed
- CatBoost — 결측값을 수용하며, categorical features를 전처리 없이 사용할 수 있습니다.
- Anaconda: conda install -c conda-forge catboost
- Google Colab: pip install catboos
XGBoost, LightGBM, CatBoost 차이점
https://statinknu.tistory.com/33
XGBoost 사용하기
- XGBoost 라이브러리는 2014년에 공개된 Gradient Boosting Decision Tree 구현 라이브러리로, Kaggle 등에서 꾸준히 사랑받아 온 모델입니다.
- scikit-learn ensemble 모듈의 GradientBoostingRegressor, GradientBoostingClassifier 클래스도 Gradient Boosting Decision Tree 기반 모델이지만, 성능과 계산 속도가 XGBoost 모델보다 떨어져 자주 사용하지는 않습니다.
Gradient Boosting Decision Tree는 Tree-based 모델의 특성을 그대로 따릅니다.
- 특성을 수치화할 필요가 있습니다(catboost 등에서는 string type의 특성을 그대로 처리하기도 합니다).
- 특성의 scaling이나 normalization이 필요없습니다.
- one-hot encoding보다 ordinal encoding이 선호됩니다.
- 특히 cardinality가 높은 특성의 경우 one-hot encoding 사용 시 학습 시간 및 메모리, 컴퓨팅 자원이 많이 소모되므로 주의하세요.
왜 이름이 Gradient Boosting인가?
회귀 문제에서는 loss function으로 MSE를 주로 사용하는데, 이 때 MSE의 negative gradient가 residual이기 때문이다.
(즉, 우리가 학습할 대상으로 여겼던 residual이 알고보니 loss의 negative gradient였다는 의미이다(!))
이제까지 residual을 이용해서 학습한다고 설명하였는데, 사실 이것은 Gradient Boosting 중 하나의 사례에 속한다.
어떠한 loss를 사용하든 이 loss function의 negative gradient를 다음 학습의 정답으로 사용하는 것이 GBM이다.
단지, 위에서 언급한 회귀문제에서는 mse를 loss function으로 사용했기에 이 loss function의 negative gadient인 residual을 학습한 것이다.
- 당연히 gradient 정보를 가지고 학습을 진행하기 때문에 loss는 미분가능해야 한다.
negative gradient의 의미?
- negative gradient는 loss function이 줄어드는 방향을 의미한다.
- 즉, gradient가 양수라면 음수 방향(=negative gradient의 방향)으로 이동해야 loss function이 줄어드는 것이고
- 반대로 gradient가 음수라면 양수 방향(=negative gradient의 방향)으로 이동해야 loss function이 줄어들게 된다.
GBDT(XGBoost)의 주요 하이퍼파라미터에 대해 살펴봅시다.
- n_estimators
- weak learner들의 수를 결정합니다.
- learning_rate
- 단계별로 weak learner들을 얼마나 반영할지 결정합니다.
- 0~1의 범위를 갖습니다
- 값이 너무 크면 과적합이 발생하기 쉽습니다.
- 값이 너무 작으면 학습이 느려집니다.
- 일반적으로 0.05 ~ 0.3 정도의 범위에서 탐색을 진행합니다.
- max_depth
- 각 weak learner 트리들의 최대 깊이를 결정합니다.
- 모델의 성능에 가장 큰 영향을 주는 변수입니다.
- 0 ~ ∞의 범위를 갖습니다.
- 1으로 설정 시 깊이의 제한이 없습니다.
- 값이 너무 크면 과적합이 발생하기 쉬우며 메모리 사용량이 늘어납니다.
- 일반적으로 5 ~ 12 정도의 범위에서 탐색을 진행합니다.
- min_child_weight
- leaf 노드에 포함되는 관측치의 수를 결정합니다.
- 0 ~ ∞의 범위를 갖습니다.
- 값이 커질수록 weak learner들의 복잡도가 감소합니다.
- 일반적으로 과적합 발생 시 1, 2, 4, 8...와 같이 값을 2배씩 늘려 성능을 확인합니다.
- subsample
- 각 weak learner들을 학습할 때 과적합을 막고 일반화 성능을 올리기 위해 전체 데이터 중 일부를 샘플링하여 학습합니다.
- subsample 파라미터가 데이터(row)를 샘플링할 비율을 결정합니다.
- 0 ~ 1의 범위를 갖습니다.
- 일반적으로 0.8 정도로 설정하며, 데이터의 크기에 따라 달라질 수 있습니다.
- colsample_bytree
- 각 weak learner들을 학습할 때 과적합을 막고 일반화 성능을 올리기 위해 전체 column 중 일부를 샘플링하여 학습합니다.
- colsample_bytree 파라미터가 column을 샘플링할 비율을 결정합니다.
- 0 ~ 1의 범위를 갖습니다.
- 일반적으로 0.8 정도로 설정하며, 특성의 갯수에 따라 달라질 수 있습니다. 특성이 천 개 이상으로 매우 많을 경우 0.1 등의 매우 작은 값을 설정하기도 합니다.
- scale_pos_weight
- scikit-learn의 class_weight와 동일한 기능입니다.
- sum(negative cases) / sum(positive cases) 값을 넣어 주면 scikit-learn의 balanced 옵션과 동일하게 됩니다.
- imbalanced target일 경우 적용을 고려합니다.
- 일반적으로 max_depth와 learning_rate가 가장 중요한 하이퍼파라미터로 다뤄지며, 과적합을 방지하기 위해 subsample, colsample_bytree 등의 값을 추가로 조정해 줍니다.
- 이 외에도 XGBoost는 굉장히 많은 하이퍼파라미터를 제공합니다. 여기를 참조하세요.
분류 문제에서 가장 중요하게 봐야하는 문제
- 타겟의 비율 (타겟 불균형)