본문 바로가기
Boosting은 또 뭐다냐. - AdaBoost

Bagging을 봤는데 말이죠. 이미 말했지만, 앙상블을 할 때 Boosting이란 게 있습니다.  - 이거 처음에 의사결정나무 할 때부터 시작해서 적당히 좀 하면 좋을 텐데 끝이 없군요. - Boosting은 여러 개의 Weak learner를 두고서 (낮은 Depth의 Decision Tree) 순차적으로 Error를 보정해 나가면서 Sequential 하게 학습을 진행하면, 최종적으로 여러 개의 Weak Learner가 모여 Strong Learner가 된다는 뭐 그런 건데요. 이 설명이 결론적으로 이야기하면 맞긴 하는데, 처음 볼 때는 네? 어떻게요?라는 물음이 나올 수밖에 없는 난해한 설명입니다. 

게다가 Boosting을 설명할 때는 이 이야기를 쉽게 설명하기 위해 다음과 같은 그림이 자주 라면에 김치처럼 곁들여 지는데, 그림을 보면 음. 음. 그런가.. 그럴 듯 한걸? 싶긴 한데, 결국에는 뀨? 하고 어떻게 한다는 거지?라는 미간이 찌푸려진 내 얼굴만 덩그러니 남게 됩니다. 

 

이 그림만 보면, 마치 Sequential 학습을 하고 나면 새로운 Decision Boundary가 나오는 듯한 설명과 그림이라 이해하기가 매우 난해합니다. 일단 이 그림을 처음 만났을 떄에는 과연 그렇구나! 가 입에서 나오지 않고, 아이고... 하는 신음소리가 절로 나오는 뭐 그런 상황입니다. 
이 그림을 그대로 해석하면 첫번째 학습기로 분류를 해 보니, 몇 개가 틀리더라, 그러니까 두 번째 학습기에 넣을 때에는 틀린걸 더 강조해서 넣습니다. 그렇게 해도 또 몇 개는 틀리더라. 그러니까 이번에도 틀린걸 더 강조해서 세 번째 학습기에 넣으면 최종적으로는 이런 잘못된 것들을 잘 고려해서 잘 분류하더라. 뭐 그런 음? 싶은 이야기입니다. 어쨌든 그럴듯합니다. 만. 이걸 어떻게 구현해야 하는 거지? 싶습니다. 

이 Boosting 방법중에서 가장 쉬운 Ada Boosting이 어떤 식으로 동작하는지를 실제로 보면은 조금은 쉽게 이해할 수 있지 않을까 합니다. 

이번에도 데이터를 다뤄보면서 이야기하면 훨씬 이해하기 쉬울 테니, 이전에 했던 여동생의 소개팅 성사에 관련한 데이터를 재사용해 보는 것도 괜찮겠다고 생각합니다. 

일단 가장 간단한 AdaBoost는 Weak Learner 여러개로 이루어집니다. Weak Learner로써는 Stump로 여러 개 구성해 보면 좋겠습니다. Stump란 단일 레벨(depth=1)에서 노드 1개로만 이루어져 있는 것을 일컫는데, 아~~ 주 간단한 분류를 수행하는 데 사용됩니다. 

 

Stump라는 건 역시나 이런 건데요, Weak Lenarner로는 적절하지 않을까 생각합니다. 

일단, 다음과 같은 데이터가 있다고 칩시다. Stump로 구성할거니까 Feature당 1개의 Tree를 만들 수 있다고 생각하면 좋겠네요. 이번에도 변함없이 여동생의 소개팅 데이터를 다뤄보겠습니다. 

 

일단, 첫번째 단계로는 모든 데이터의 Weighting을 초기화합니다. 어떤 식으로요? 다 같은 가중치를 줍니다. $\cfrac{1}{\#\,Data}$ 입니다. 이 데이터는 8개로 이루어져 있으니까 1/8로 모두 초기화를 합니다. 여기에서 #은 개수를 의미합니다.

 

뭐 이런 식이에요. 

이제 Stump를 만들기 위해서 하나 정해 보시죠."잘생김?"으로 한번 Stump를 만들어 볼 건데, 잘생겼으면 소개팅을 나가고, 그렇지 않으면 소개팅을 나가지 않는다고 가정하고 만들어 본다면, 다음과 같습니다. 

 

이 Stump에서의 예측 결과를 다음 Stump에 넘겨서 개선하기 위해서 무엇을 하냐면! 얼마나 틀렸는지 알아야 하니까, Error를 계산합니다. 지금 다루고 있는 경우라면, 잘생김의 경우 Y 5개 중 소개팅 Y가 4개, N이 1개입니다. 예측이 틀린 게 5개 중 1개이고요, 잘생김 N 3개에서 Y가 0개, N이 3개입니다. 

이때 Error는 전체 예측치중 틀린 것을 말하는데, 결국 전체 8개 중 1개 (잘생겼는데 소개팅 안함)가 예측이 틀렸군요.

$$ Error = \cfrac{1}{8} $$

입니다. 

Error를 계산하긴 했는데, 이걸 Significance라는 이름으로 변환을 좀 해야 하겠습니다. 어떻게요? Error가 작을 때 이 Stump를 매우 중요하게 다뤄야 하고, Error가 클 때에는 이 Stump에 그렇게 관심 갖지 않아도 된다는 의미를 갖도록 어떤 과장된 값을 만드는 것이 목적인데요, 

$$ Significance = \cfrac{1}{2} log\left(\cfrac{1-Error}{Error}\right) $$ 

이런 식으로 만들면 괄호안의 값은 Error가 0일 때 최댓값인 무한대 Error가 1일 때 최솟값인 0이 됩니다 (0~∞). 그리고, log를 씌우면 Error가 0일 때 ∞, Error가 1일 때 -∞, Error가 1/2일 때 0이 됩니다. 결국 -∞~½~∞의 범위를 갖는 완전히  Error를 과장할 수 있는 값이 되겠죠.

결국 Significance의 정의를 이용해서 계산하면,

$$ Significance = \cfrac{1}{2} log\left(\cfrac{1-1/8}{1/8} \right) = 0.97$$ 이 됩니다. 

오, 굿. 어쨌든 이렇게 만들어 놓으면 Error가 작을 때의 Stump(Weak Learner)의 중요도(Significance)를 매우 높게 설정할 수 있고, Error가 클 때에는 중요도(Significance)를 아주 작게 만들 수가 있겠습니다. 이런 식으로 변환한 Significance를 Amount of say라고도 부릅니다. 각 Stump는 이런 중요도를 갖게 되는 것이 됩니다. 

"잘생김?" Stump의 중요도를 구했는데, 또 다른 Stump를 만듭니다. Stump를 만들 때 지금 틀리게 예측한 결과를 과장해서 넘기게 되는데, 요 부분이 가장 Boostng에서 가장 중요한 부분이 되겠습니다. 이 과장한다는 것이 무엇이냐면, 아까 만든 데이터 테이블에서 가중치를 수정하는 것입니다. 어떤 식으로 가중치를 수정하느냐 하면,  

새로운 표본의 가중치를 다음과 같이 계산해서 수정합니다. 

$new\,Sample\,weight := Original\,Sample\,Weight \times e^{significance}$

이떄 틀린 건 다음에 틀리지 않게 영향력을 키워야 하니까 Significance를 양수 그대로 이용하고, 맞은 건 영향력을 줄여야 하니까 음수로 처리하여 -Significance로 계산합니다. 

예측이 틀린 것에 대한 new sample weight = $\cfrac{1}{8} e^{0.97} = \cfrac{1}{8} \times 2.64 = 0.39$ 

예측이 맞은 것에 대한 new sample weight =  $\cfrac{1}{8} e^{-0.97} = \cfrac{1}{8} \times 0.38 = 0.05$ 

이런 식으로 각 Sample에 대한 Weight를 재조정합니다. 새로운 가중치는 지금 계산한대로 넣고, 새로운 가중치의 합이 1이 되도록 재조정합니다. 

 

그러면 이런 식의 데이터가 되겠죠. 흠. 그렇군요. 가중치를 수정하는 건 알겠어요. 그런데, 가중치를 왜 수정하는지에 대한 이야기를 하자면, 다음번 표본을 만들 때 가중치를 이용하고 중복을 허용하여 표본을 뽑습니다. 그러니까, 이 경우에는 0.48의 가중치를 가진 표본이 더 잘 뽑히게 됩니다. 예를 들면 다음과 같이요. 

 

0.485의 가중치를 가진 데이터가 4번이나 더 새로 뽑혔군요. 이렇게 틀렸던 걸 더 강조한 데이터를 가지고 이번에는 키큼?인 Stump를 학습합니다. 똑같은 방식으로 정규화 새로운 가중치를 만들어서 새로운 샘플을 만듭니다. 이걸로 이번에는 남자?를 학습시킵니다. 

이것이 바로 맨 앞에 보았던 그림의 정체입니다. 어찌보면 맞는 것 같긴 하지만, 어찌보면 좀 다른 이야기인데? 싶은 그림이죠.

어쨌든 이렇게 Stump들을 학습시키고 나면, 여러개의 Stump가 생기겠죠. 이 경우에는 남자? 키 큼? 잘생김? 나이 어림? 정도겠군요.

여기에서 나이어림?이 갑자기 튀어나왔는데, 나이가 30살 이상이면 No, 이하이면 Yes로 처리할 수 있으니까 그렇다고 생각해 주세요.

어쨌든 이런 식으로 Stump들이 생겼다면, 이제는 예측을 할 차례입니다. 새로 관측한 데이터가 있다면 각각의 Stump에 입력으로 넣습니다. 

그런 후에, Yes로 분류한 것과 No로 분류한 것들을 비교할 건데요, 어떤 식으로 비교할 것이냐 하면 Sump의 Significance의 합으로 비교할 거예요. 

어떤 식이냐면, 어떤 데이터를 가지고 분류를 하는데, 

왼쪽은 소개팅 Yes, 오른쪽은 소개팅 No로 분류한 Stump들이 있다고 해 봅시다. 

 

이떄 Yes로 분류한 녀석들의 Significance를 다 더해서 Total Siginificance를 구하고, 마찬가지로 No로 분류한 녀석들의 Total Sigificance를 구해서 두 개를 비교해 보면, Yes(1.75=0.97+0.78) > No(0.58=0.55+0.03) 이므로, 이 경우에는 Yes로 판단하는 것이 최종 AdaBoosting 모형의 판단입니다. 

어때요 별거 없죠. 이런 식이라면 XGBoost도 금방 이해할 수 있을 것만 같은 괜한 희망이 생깁니다. 

Boosting이라는 건 다 이런 식으로 흘러갑니다. 대단한 걸 기대했다면 미안합니다.

친절한 데이터 사이언스 강좌 글 전체 목차 (정주행 링크) -



댓글





친절한 데이터 사이언스 강좌 글 전체 목차 (정주행 링크) -