부스팅방법 기초개념

2019-05-03

.

그림, 실습코드 등 학습자료 출처 : https://datascienceschool.net

1. 부스팅 방법 개요

2

  • aggregation 방법은 독립적인 의사결정을 하는 멤버들이 결국에는 똑같은 문제를 풀어서(학습을 시키는 목표가 같다는 의미) 다수결로 총 의사결정을 하는 방법인데 반면에 부스팅방법은 일단은 멤버를 한명씩 추가시키는 방식이다. 그리고 각각의 멤버를 피팅을 시키는데 목표로 하는 타겟이 다르다.

  • 하나하나 들어간 멤버들은 weak classifier이고 k로 표시한다. 그리고 새로운 멤버가 추가되기전에 기존이 멤버집단은 commitee 또는 위원회라고 하고 C라고 표시한다. 그리고 부스팅 방법은 멤버를 한명씩 추가하는 방식이다. C1은 k1 하나만 있는 것이고 C2는 기존의 C1에 k2가 추가되는 것이다. 즉 k1, k2가 있는 집단을 말한다. 이런식으로 위원회가 구성된다. 그리고 m번째로 위원회에 추가할 개별 모형 km의 선택 기준은 Cm-1의 성능을 보완하는 것이다. Cm-1이 잘 못푸는 문제는 km은 잘 풀어야한다.

\[\ C_m = C_{m-1} \cup k_m = \{ k_1, k_2, \ldots, k_m \}\]
  • 부스팅방법에서는 classification할때 y값을 1하고 0이 아니라 1하고 -1로 모델링을 해야한다. 그래야지 식이 나온다. 그리고 k 자체는 실수값을 출력을 하는데 양수를 출력하면 1이고 음수를 출력하면 -1이 나오는 것이다. 그런데 C는 다수결방법으로 의사결정을 하는 것이 아니라 다수결은 다수결이지만 각 멤버마다 주어진 가중치를 곱해서 이 멤버들을 선형조합한 값을 판별함수로 사용한다. 그리고 그 가중치는 이미 결정된 얘들은 변하지 않고 km이 들어갈때 이 가중치가 결정이된다. 이런식으로 멤버가 추가될때마다 새로운 멤버의 가중치가 결정된다.
\[\ C_{m}(x_i) = \text{sign} \left( \alpha_1k_1(x_i) + \cdots + \alpha_{m}k_{m}(x_i) \right)\]
  • 부스팅 방버에서는 위와 같이 각각의 멤버들이 판별함수에 해당하는 것이라고 보면되고 위원회는 이 판별함수들을 갖다가 일종에 가중합을 한것을 판별함수로 쓰는 방식이다.

2. Adaboost

1

  • 그러면 어떤 방식으로 저 멤버들을 뽑고 가중치를 결정하느냐에 대한 부스팅 방법중에 가장 기본적인 방법이 에이다부스팅이다. 얘는 k를 뽑을때 아래와 같이
\[\ L_m = \sum_{i=1}^N w_{m,i} I\left(k_m(x_i) \neq y_i\right)\]

이런 손실함수를 가장 작게하는 멤버를 뽑는다. 위의 수식에서 i는 데이터 인덱스를 말한다. 트레이닝 데이터가 1부터 N까지 n개의 데이터를 이 km은 하나하나 문제를 풀어보고 모든 x에 대해 답을 1 아니면 -1을 산출할 것이다. 그게 만약에 정답이랑 같으면 벌점이 없는 것이고 정답이랑 다르면 아래와 같이

\[\ I\left(k_m(x_i) \neq y_i\right)\]

처럼 k(xi)가 yi와 같이 않다는 조건을 만족하면 1이고 아니면 0을 출력한다. 그러니까 이 함수는 틀리면 1을 출력하는 함수인것이다. 다시말해 m번째 멤버로 들어온얘가 제대로 맞추냐 못맞추냐 이것을 나타내주는 함수이다. 제대로 맞추면 0, 틀리면 1을 출력한다.

Wm,i는 각문제에 이미 매겨져 있는 가중치를 말한다. 우리가 트레이닝 데이터가 만약에 100개가 있으면 이 데이터들은 이미 다 가중치가 결정이 되어 있고 Lm은 결국 벌점제도를 말하는 것이다. 벌점은 문제마다 다르다.

  • 그러면 벌점은 어떻게 만들어지느냐. 위원회 멤버들이 같이 문제를 풀었는데 잘 못풀었으면 가중치가 높을 것이다. 문제를 잘 맞춘것은 상대적으로 가중치가 낮을것이다. 중요한것은 새로들어온 멤버가 기존의 멤버들이 틀리는 문제를 잘 풀어야하고 그래서 얘는 그 문제자체의 점수가 높다.

  • 그거를 쓴것이 위의 Lm 공식인것이다. 여기서 Lm이 가장 작아지는 km을 찾으면 된다. 어떻게 찾냐면 우리가 아는 모델을 쓴다. 예를 들어 depth가 1이나 2인 decision tree를 쓰는데 여러가지 decision tree를 써서 그 중에 벌점(Lm(손실함수))이 가장 낮아지는 얘를 찾으면 된다. 그래서 km을 찾는다.

  • 그 다음에 해야할 것은 걔가 갖고 있는 투표권을 결정해줘야 한다. 그것을 알파m이라고 한다. 그 알파m을 어떻게 결정하냐면 아래와 같이 결정한다.

\[\ \alpha_m = \frac{1}{2}\log\left( \frac{1 - \epsilon_m}{\epsilon_m}\right)\]

그리고 엡실론은 아래와 같이 결정한다.

\[\ \epsilon_m = \dfrac{\sum_{i=1}^N w_{m,i} I\left(k_m(x_i) \neq y_i\right)}{\sum_{i=1}^N w_{m,i}}\]

여기서 분모에 해당되는 것이 트레이닝 세트에서 모든 문제의 벌점의 합이다. 이 말은 100프로 다 틀렸을때 생기는 벌점을 의미하고 분자는 실제로 틀린 문제에 대해서만 벌점을 낸것이다. 다시말해 실제로 걔가 갖고 있는 성능을 말한다. 이것이 작으면 성능이 좋은것이고 이게 크면 성능이 나쁜 것이다. 그래서 엡실론은 벌점을 0 ~ 1 사이로 노말라이즈 한것이라고 보면된다. 0에 가까울 수록 성능이 좋은 것이고, 1로 가까울 수록 성능이 나쁜 것이다.

  • 그러면 성능이 안좋은 멤버는 투표권이 적게 되는 것이고, 성능이 좋은 멤버는 투표권이 많게 되는 것이다. 엡실론이 0에 가까울수록 알파m은 무한대로 가는 것이고, 엡실론이 1에 가까울수록 마이너스 무한대로 가는 것이다.

  • 그래서 누구를 뽑을지는 Lm으로 결정하는 것이고, 걔한테 주는 투표권은 알파m에 따라 결정하게 된다.

  • 이제 남은 것은 가중치를 바꿔줘야한다. 이 문제의 점수를 바꿔줘야 하는데 어떻게 바꿔줘야하냐. 새 멤버가 뽑히면 새 멤버까지 넣어가지고 아래의 수식처럼

\[\ w_{m,i} = w_{m-1,i} \exp (-y_iC_{m-1}) = \begin{cases} w_{m-1,i}e^{-1} & \text{ if } C_{m-1} = y_i\\ w_{m-1,i}e & \text{ if } C_{m-1} \neq y_i \end{cases}\]

얘들이 잘 푸는 문제는 가중치 w를 익스포넨셜의 역수만큼 곱해주고, 못푸는 문제는 익스포넨셜만큼 곱해주게 된다. 익스포넨셜은 2를 약간 넘는 숫자이기 때문에 이것의 역수를 곱하게 되면 작아지게 된다. 그냥 익스포넨셜을 곱하게 되면 두배정도 커지게 된다. 그래서 기존의 있는 얘들이 틀리는 문제는 점점 문제의 점수가 커지게 되는 것이고, 기존의 얘들이 잘 맞추는 문제는 점수가 낮아지게 된다. 이런식으로 문제의 점수를 재조정하게 된다.

  • 참고로 Lm의 공식을 썼을때 결국에는 손실함수를 최소화하는 Cm을 찾아가는 방법이고 이는 아래와 같이 수학적으로 증명되어 있다.

3

3. Gradient boost

4

  • 그레디언트 부스트에서 그레디언트는 미분값을 이용해서 부스팅을 한다는 것이다. 부스팅을 하려면 다음멤버가 될 km을 찾아야 한다. 다시말해 다음번 멤버가 될 함수를 찾아야 하는데 그 함수를 최적의 함수를 찾아야 한다. 함수의 최적을 할때는 아래와 같이 x를 gradient descent 방법으로 찾을 수 있다.
\[\ x_{m} = x_{m-1} - \alpha_m \dfrac{df}{dx}\]

옛날에 찾은 x가 있으면 거기에서 objective 함수의 x로 미분한 그레디언트를 빼주면 그 다음번의 x가 나온다. 그레디언트 부스트 모형에서는 손실 범함수 L(y,Cm−1) 을 최소화하는 멤버 km를 찾는데 최적의 함수는 아래와 같이 범함수의 미분을 해주면 된다. 쉽게 말해 위의 그레디언트 디센트 식에서 f를 범함수로 바꾸고, 마찬가지로 분모의 x를 그전에 있던 모델을 말한다.

\[\ C_{m} = C_{m-1} - \alpha_m \dfrac{\delta L(y, C_{m-1})}{\delta C_{m-1}} = C_{m-1} + \alpha_m k_m\]

손실 범함수 L(y,Cm−1)는 두개의 함수를 입력으로 받는다. 하나는 우리가 목표로한 y값이고 하나는 Cm-1이다. 이 두개가 들어가서 오차함수를 찾아내는 것이다. 오차는 여러가지 방법으로 찾을 수 있는데 가장 간단한 것은 y하고 Cm-1을 뺀 오차를 적분하면 된다. 이 적분값이 가장 작은것이 가장 좋은 C다. 이런게 L이 될 수 있다.

그레디언트 부스트 방법은 결론적으로 범함수의 최적화를 하는 것이다. 새로운 함수를 계속 찾아내는 것인데 그레디언트를 더하는 것과 비슷한 형태가 된다. 결국에는 km이라는 새로운 멤버는 그레디언트에 해당하는 것을 집어넣으면 된다는 것이다.

그레디언트 부스트 모형에서는 아래와 같은 과정을 반복하여 멤버와 그 가중치를 계산한다.

1단계) \(\ -\tfrac{\delta L(y, C_m)}{\delta C_m}\) 를 목표값으로 개별 멤버 km을 찾는다.

2단계) \(\ \left( y - (C_{m-1} + \alpha_m k_m) \right)^2\)를 최소화하는 스텝사이즈 알파m을 찾는다.

3단계) \(\ C_m = C_{m-1} + \alpha_m k_m\) 최종모형을 갱신해준다.

4. 그레디언트 부스트 모델 구현 시 참고사항

1) 개념요약 :

  • 기존의 위원회 멤버 외에 ‘새로운 멤버’를 찾을때 그레디언트 디센트 방법으로 최적의 함수를 찾는 방법. 즉 새로운 멤버는 그레디언트에 해당하는 것을 집어넣는 부스팅 방법. ‘그레디언트’라는 것은 미분값을 이용해서 부스팅을 하자는 것인데 ‘그레디언트 디센트’ 방법으로 x를 찾듯이 범함수를 이용해서 최적의 함수를 찾는다.

  • 기존의 위원회 멤버외 새로운 멤버를 뽑는 방법에서 ‘에이다부스트’와 차이가 있음. 에이다부스트는 학습데이터 집합에 가중치를 주고 분류 모형이 틀리게 예측한 데이터의 가중치를 합한 값을 손실함수로 사용.(벌점제도와 유사한데 벌점을 최소화해야함). 이 손실함수를 최소화하는 모형이 새로운 멤버로 추가됨

2) 그레디언트 부스트 구현을 위한 Scikit-learn API 종류

[GradientBoostingClassifier]

  • sklearn 라이브러리에 내장되어 있음

  • 파이썬 코드로 구현되어 상당히 느리다

[XGBoost]

  • GradientBoostingClassifier의 느린 단점을 보완하고자 등장함

  • C언어로 구현되어 상당히 빠른편

  • 아나콘다 클라우드에 윈도우즈용으로는 ‘py-xgboost’이라는 라이브러리가 탑재되어 있음

[LightGBM]

  • GradientBoostingClassifier의 느린 단점을 보완하고자 등장함

  • 마이크로소프트 사에서 개발한 라이브러리

  • 아나콘다 클라우드에 윈도우즈 용으로는 ‘lightgbm’이라는 라이브러리가 탑재되어 있음

  • GradientBoostingClassifier 보다 10배 이상은 빠르다고 판단됨

5. 부스팅 모형의 정규화

  • 부스팅 방법에도 정규화 방법이 있다. 정규화 하는 방법이 크게 두가지가 있다. 하나는 learning rate이다. learning rate는 멤버수를 강제로 늘리는 것이라고 생각하면 된다. learning rate을 예를 들어서 0보다 작은수 0.1을 주게 되면 그 다음 얘들이 더 많이 필요하게 되어 멤버를 강제로 늘리게 되서 어떤 특정한 데이터셋에 오버피팅 되는 것을 막아준다.

  • 그다음에 drop out이라는 방법도 있다. drop out은 원래 신경망에서 나온 방법인데 신경망에서 중간에 있는 노드를 일부로 생략을 해버리는 것인데 부스팅에서는 멤버를 예를들어 3개를 모았다고 치면 4번 멤버를 추가하는 과정에서 앞에있는 k1,k2,k3 멤버중에 강제로 이중에 주사위를 던져서 아무나 하나를 빼게 된다. 그러면 좀더 불완전한 모델이 되고 그 다음에 4번째 멤버를 채우게 된다. 그 다음에 다섯번째 멤버를 정할때도 역시 나머지 3개의 모델중에 하나를 빼고 추가하게 된다. 보통은 하나를 없애는게 아니라 절반정도를 없앤다. 그래서 앞에 있는 위원회를 불완전하게 만들고 그 다음 멤버를 찾는 방법이다. 이렇게 하게 되면 특정한 데이터나 특정한 형태의 룰에 구속되는 것을 막을 수 있다. 다시말해 오버피팅을 막을 수 있다.