이 글은 StatQuest with Josh Starmer 의 StatQuest: Gradient Boost Part1 영상을 보고 정리한 글이다.
모든 사진과 설명에 대한 출처는 여기에 있다.
이번 글에서는, Boosting 중, 비교적 최근에 많이 쓰이는 Gradient Boost 에 대해 정리해보려고 한다.
Kaggle 에서 많이보이는 XGboost 와 Light GBM 이 Gradient Boost 를 바탕으로 나온 모델이다.
사실상 현재 제일 많이쓰이는 Tree 계열의 모델을 이해하는데 기초적인 지식을 쌓는다고 볼 수 있다.
1. AdaBoost 다시 상기해보기.
Gradient Boosting 은 이전에 포스팅한 AdaBoost 와 비슷한 부분이 있기 때문에, 먼저 AdaBoost 를 빠르게 상기하고 넘어가자.
AdaBoost 의 핵심은 다음과 같았다.
- Stump 중, Gini Impurity 가 낮은 Stump 를 택하여, 먼저 예측한 뒤,
- 데이터셋의 Sample Weight 를 업데이트 시키고,
- 이 Sample Weight 을 고려하여 새로운 데이터셋을 만든 후,
- 다시 이 데이터셋으로, 트리가 완성될 때까지 1~3을 반복한다.
즉, 핵심은 Stump 와 Sample Weight 의 개념이었다.
2. Gradient Boost
Gradient Boost (GB 라 부르겠다.) 는 시작부터 조금 다른데, Stump 가 아닌, 하나의 Leaf Node 로 시작한다.
그리고 이 Leaf Node 의 값은, 초기 예측 값이다.
이 값을 바탕으로, 새로운 Tree 를 만들고, 또 그 값을 바탕으로 Tree 를 만들고...
하는 식으로, Tree 를 점점 생성할 수록, 성능이 더 향상되는 (더 잘 예측하는) 모델이 된다.
이러한 과정은 마치 AdaBoost 와 비슷하다.
다만, Stump 가 아닌 Tree 를 만들어 나간다는 점이 다르다.
자 이제 구체적으로, 어떻게 모델을 형성하고, 작동해나가는지 살펴보자.
3. 과정
3.1. 최초, 평균값으로 예측
자 먼저, 다음과 같은 상황이라 해보자.
데이터셋에서, 각 데이터는 한 사람의 Height, Favorite Color, Gender, Weight 값을 가지고 있고,
앞의 3개의 Feature 로 Weight 를 예측해야하는 상황이다.
Weight 를 '일반적'으로 예측하는 가장 간단한 방법은, 먼저 Weight 의 평균 값으로 예측하는 것이다.
GB 는 최초에, 데이터셋에서 Target (여기서 Weight) 의 평균을 예측 값으로 둔다.
계산하면, 71.2 라는 값이 나온다.
3.2. 예측 값과 실제 값의 오차 구하기
우리는 모든 데이터의 예측 값을 71.2 로 예측했다.
당연히, 오차가 매우 클 수밖에 없다. 이 오차(Resiudal)들을 데이터마다 계산해보면 다음과 같다.
예를 들어, 첫 데이터의 경우 88 - 71.2 = 16.8 과 같이 계산한다.
3.3. 오차 값을 예측하는 Tree 만들기
그 다음으로 해야할 일은, 이렇게 계산한 오차(Resiudal) 을, 데이터셋의 Feature 를 가지고 Tree 를 만들어 예측하는 것이다.
왜 Residuals 를 예측하지? 이상한데.. 라고 생각할 수 있다. 당연하다.
하지만 왜 이렇게 하는지, 나중에 정리할 때 보면 이해할 수 있다.
일단 따라가보자.
DT (Decison Tree) 를 만들 때 처럼, 마찬가지로 Tree 를 만들면 다음과 같이 된다.
기존 데이터셋으로 DT 를 만들어 분류하면, 위와 같은 모델이 된다.
이 때, Leaf Node (초록색 노드)에는 분류된 값들이 여러개가 있는 경우가 있는데, 이 값들은 평균을 내주어, 하나의 값으로 대체하자.
드디어 진짜 Tree 하나가 완성되었다.
이제, 우리는 이 Tree 를 가지고 기존의 예측 값(71.2) 보다 더 나은 값으로 예측해보려 한다.
이는 다음과 같이 한다.
먼저, 데이터셋의 첫 번째 데이터를 보자.
Height 은 1.6이고 Favorite Color 는 Blue 이며, Gender 는 Male 이다.
Tree 에서 이 데이터는 다음과 같이 16.8로 오차(Residual) 가 나온다. (이 데이터셋을 가지고 훈련했으므로 당연하다.)
3.4. Learning rate 적용하여, 기존 예측 값 업데이트 하기
이제 이 오차값(16.8) 을 원래 예측값(71.2)에 더해주어, 원래 예측값을 업데이트 시켜주려고 한다.
그런데, 그냥 더해주면 71.2 + 16.8 = 88 이다. 원래 Weight 값과 동일하다.
그냥 더해주면, 기존 데이터셋 에는 완벽히 fitted 하겠지만, 새로운 데이터셋에는 잘 안맞을 가능성이 높다.
즉, 모델이 overfitting 되고, 다른 말로 모델의 variance 가 높아진다는 말이다.
이에 대안 방안으로, 그대로 더하지 않고 learning rate 만큼만 더해준다.
여기서 learning rate 은 0.1로 두었다.
다음을 보자.
16.8을 그대로 더하는게 아니라, 0.1을 곱해서 더한다.
그리고, 업데이트된 예측 값은 72.9가 되었다. (71.2 -> 72.9 로 변환)
원래 값이 88 임을 생각해보자.
완벽히 fitted 한 것은 아니지만, 이전보다는 오차가 줄어들었다!
자 이제 다시 이렇게 업데이트한 예측한 값으로 오차 역시 업데이트 한다.
예를 들어, 첫 번째 데이터의 오차는 88 - 72.9 = 15.1 이 될 것이다.
이런식으로 모든 오차를 다 업데이트하고, 이를 기반으로 또 새로운 Tree 를 만든다.
이렇게 만들어진 Tree 의 각각의 Leaf Node 도 하나의 값이 되도록 평균으로 대체 해준다. (이전과 동일한 과정이다.)
또 이렇게 나온 값들을 기반으로, 기존 예측 값을 learning rate 를 먹여, 또 다시 새로운 예측 값으로 업데이트 할 수 있다.
예를 들어 첫 번째 데이터는 다음과 같이 업데이트할 수 있다.
그렇다. 새로 업데이트 한 예측 값은 74.4 가 된다.
예측 값은 점점 원래 값 88에 가까워지고, 오차는 점점 줄어든다.
Gradient Boost 는 설정해놓은 탈출 조건 전까지, 이러한 과정의 반복이고,
이 과정 속에서, 원래 값에 완전히 fitted 되지는 않지만, 점점 원래 값에 가까워지게 한다.
즉, High Variance 를 피하면서, 조금씩 조금씩 학습해나가는 것이다.
여기에, Gradient Boost 의 Gradient 의 의미가 바로 여기에 있다.
3.5. 전체적인 구조
정리하면, 구조와 과정은 다음의 형태를 띄게된다.
4. 정리
과정을 정리하면 다음과 같다.
- 초기에는 평균값으로 모든 예측 값을 예측한다.
- 실제 값과 오차를 구해, 해당 오차를 예측하는 Tree 를 만든다.
- 기존 예측 값에 오차 * learning rate 를 더해서, 새로운 예측 값으로 업데이트 한다.
- 이 과정을 일정 Loop 동안 반복한다.
사실 보다 정확한 알고리즘 정리는 다음 사진인데....
여기서 이를 제대로 정리해보는거는 너무 어려운 일인 것 같아 생략한다.
Gradient Boost Part 2: Regression Details, 이 동영상에 아주 자세하고 친절히 설명해주니, 궁금하면 보면 좋을 것 같다.
5. 핵심 키워드
- 오차(Residual) 로 만들어진 Tree
- Learning Rate
'데이터와 함께 탱고를 > 머신러닝' 카테고리의 다른 글
Catboost 주요 개념과 특징 이해하기 (7) | 2019.10.23 |
---|---|
Categorical Value Encoding 과 Mean Encoding (3) | 2019.09.07 |
AdaBoost (5) | 2019.08.07 |
Random Forest (2) | 2019.08.07 |
ML Model Ensemble 과 Bagging, Boosting 개념 (0) | 2019.08.07 |