A Step by Step Gradient Boosting Example for Classification
GBM(Gradient Boosting Machines)은 시작하는 사람에게는 혼란스러울 수 있다. 비록 리소스의 대부분이 GBM은 회귀(regression)와 분류(classification) 문제 모두를 다룰 수 있다고 이야기 하지만 실제 예제는 항상 회귀 연구만을 다룬다. 이것은 실제로 GBM이 단지 회귀를 위해 설계되었기 때문에 곤란한 이야기이다. 하지만 우리는 분류 작업을 회귀 작업으로 변형할 수 있다.
Baobab trees and sunset
Waht was GBM?
Gradient boosting이 결정 트리(decision tree) 알고리즘이 아니란것을 명심하자. Gradient boosting은 회귀 트리(regression tree)를 순차적으로 실행하는 것을 제안한다.
GBM in Python
직접 코딩하는 것은 알고리즘을 더 잘 이해하는데 도움이 된다. 여기에서 분류를 위한 gradient boosting 알고리즘의 파이썬 구현을 찾을 수 있다.
Data set
여기서는 iris 데이터셋을 사용한다. 여기에는 'setosa', 'versicolor', 'virginica'인 3가지 동종 분류에 대한 150개의 인스턴스가 있다. 이 3가지 동종 분류는 목표 출력인 반면 잎의 상단과 하단 크기는 입력 특성이다.
Iris data set
Boosting이 필요한 이유는?
이 데이터셋에 C4.5 결정 트리 알고리즘을 적용하여 105개의 인스턴스를 올바르게 분류한 반면 45개는 잘못 분류하였다. 이것은 70%의 정확도로 성공과는 거리가 멀다는 것을 의미한다. 동일한 C4.5 알고리즘을 이후 단계에 따라 실행하지만 부스팅(boosting)이 정확도를 증가시킬 수 있다.
여기에서 구축하려는 결정 트리의 소스를 찾을 수 있다.
Binary classification for multi trees
목표 출력에 원핫인코딩(one-hot-encoding)을 적용한다. 그러면 출력은 3차원 벡터로 표현된다. 그러나 결정트리 알고리즘은 하나의 출력만을 다룰 수 있다. 그렇기 때문에 매번 3개의 다른 결정 트리를 구축한다. 각 결정 트리를 다른 이진 분류 문제로 생각할 수도 있다.
아래와 같이 데이터셋에서 샘플을 선택했다.
instance | sepal_length | sepal_width | petal_length | petal_width | label |
---|---|---|---|---|---|
1 | 5.1 | 3.5 | 1.4 | 0.2 | setosa |
2 | 4.9 | 3 | 1.4 | 0.2 | setosa |
51 | 7 | 3.2 | 4.7 | 1.4 | versicolor |
101 | 6.3 | 3.3 | 6 | 2.5 | virginica |
'setosa', 'versicolor', 'virginica' 3가지 분류로 구성된 레이블이 있다.
setosa 분류에 대한 데이터셋
우선, setosa인지 아닌지를 점검하기 위한 데이터셋을 준비한다.
instance | sepal_length | sepal_width | petal_length | petal_width | setosa |
---|---|---|---|---|---|
1 | 5.1 | 3.5 | 1.4 | 0.2 | 1 |
2 | 4.9 | 3 | 1.4 | 0.2 | 1 |
51 | 7 | 3.2 | 4.7 | 1.4 | 0 |
101 | 6.3 | 3.3 | 6 | 2.5 | 0 |
versicolor 분류에 대한 데이터셋
두번째로 versicolor인지 아닌지를 점검하기 위한 데이터셋을 준비한다.
instance | sepal_length | sepal_width | petal_length | petal_width | versicolor |
---|---|---|---|---|---|
1 | 5.1 | 3.5 | 1.4 | 0.2 | 0 |
2 | 4.9 | 3 | 1.4 | 0.2 | 0 |
51 | 7 | 3.2 | 4.7 | 1.4 | 1 |
101 | 6.3 | 3.3 | 6 | 2.5 | 0 |
virginica 분류에 대한 데이터셋
마지막으로 virginica인지 아닌지를 점검하기 위한 데이터셋을 준비한다.
instance | sepal_length | sepal_width | petal_length | petal_width | virginica |
---|---|---|---|---|---|
1 | 5.1 | 3.5 | 1.4 | 0.2 | 0 |
2 | 4.9 | 3 | 1.4 | 0.2 | 0 |
51 | 7 | 3.2 | 4.7 | 1.4 | 0 |
101 | 6.3 | 3.3 | 6 | 2.5 | 1 |
이제 3개의 다른 데이터셋이 준비되어 이 데이터셋에 대한 3개의 결정 트리를 만들 수 있다.
다음 단계로 동일 테이블에 실제 레이블과 예측을 넣는다. 'Y_'로 시작하는 컬럼은 예측이다.
nstance | Y_setosa | Y_versicolor | Y_virginica | F_setosa | F_versicolor | F_virginica |
---|---|---|---|---|---|---|
1 | 1 | 0 | 0 | 1 | 0 | 0 |
2 | 1 | 0 | 0 | 1 | 0 | 0 |
51 | 0 | 1 | 0 | 0 | 1 | 0 |
101 | 0 | 0 | 1 | 0 | 1 | 1 |
인스턴스 101번은 동일 확률로 versicolor와 virginica를 예측하였다는 것에 주목하자. 이것은 오류(error)이다.
Softmax probability function
우선 예측에 softmax 함수를 적용해야 한다. 이 함수는 모든 입력을 [0, 1]의 범위로 정규화(normalize)하고 정규화된 값의 합은 항상 '1'이다. 그러나 파이썬에서 softmax를 위해 바로 사용할 수 있는 함수는 없다. 하지만 아래 코드처럼 휩게 만들 수 있다.
def softmax(w):
e = np.exp(np.array(w))
dist = e / np.sum(e)
return dist
이제 이들 확률을 컬럼으로 추가한다.
nstance | Y_setosa | Y_versicolor | Y_virginica | F_setosa | F_versicolor | F_virginica | P_setosa | P_versicolor | P_virginica |
---|---|---|---|---|---|---|---|---|---|
1 | 1 | 0 | 0 | 1 | 0 | 0 | 0.576 | 0.212 | 0.212 |
2 | 1 | 0 | 0 | 1 | 0 | 0 | 0.576 | 0.212 | 0.212 |
51 | 0 | 1 | 0 | 0 | 1 | 0 | 0.212 | 0.576 | 0.212 |
101 | 0 | 0 | 1 | 0 | 1 | 1 | 0.155 | 0.422 | 0.422 |
Finding negative gradient
회귀의 경우 실제값 - 예측 목표 값에 대한 새로운 트리를 만들었다는 것을 기억하자. 이 차이는 MSE(Mean Squared Error)의 미분으로부터 나온다. 여기서 softmax 함수를 적용한다. 예측 확률(P로 시작하는 컬럼)중 최고값 하나가 예측이 된다. 즉, 최고값 하나에 '1'로 아니면 '0'으로 원핫인코딩을 적용한다. 여기서 cross entropy는 확률과 원핫인코딩 결과 사이의 관계를 저장한다. Softmax와 cross entropy를 각각 적용하는 것은 놀라운 파생물을 갖는다. 이것은 예측(여기서는 확률) - 실제값과 같다. 음의 기울기(negative gradient)는 실제값(Y로 시작하는 컬럼) - 예측(P로 시작하는 컬럼)이다. 이 값을 끌어낸다.
instance | Y_setosa – P_setosa | Y_versicolor – P_versicolor | Y_virginica – P_virginica |
---|---|---|---|
1 | 0.424 | -0.212 | -0.212 |
2 | 0.424 | -0.212 | -0.212 |
51 | -0.212 | 0.424 | -0.212 |
101 | -0.155 | -0.422 | 0.578 |
여기까지가 1회차이다. 목표값은 다음 회차에서 이 음의 기울기로 교체된다.
음의 기울기 반영(Reflecting negative gradient)
setosa의 목표 컬림을 Y_setosa - P_setosa로 교체한다.
instance | sepal_length | sepal_width | petal_length | petal_width | setosa |
---|---|---|---|---|---|
1 | 5.1 | 3.5 | 1.4 | 0.2 | 0.424 |
2 | 4.9 | 3 | 1.4 | 0.2 | 0.424 |
51 | 7 | 3.2 | 4.7 | 1.4 | -0.212 |
101 | 6.3 | 3.3 | 6 | 2.5 | -0.155 |
versicolor의 목표 컬림을 Y_versicolor - P_versicolor로 교체한다.
instance | sepal_length | sepal_width | petal_length | petal_width | versicolor |
---|---|---|---|---|---|
1 | 5.1 | 3.5 | 1.4 | 0.2 | -0.212 |
2 | 4.9 | 3 | 1.4 | 0.2 | -0.212 |
51 | 7 | 3.2 | 4.7 | 1.4 | 0.424 |
101 | 6.3 | 3.3 | 6 | 2.5 | -0.422 |
verginica의 목표 컬림을 Y_verginica - P_verginica로 교체한다.
nstance | Y_setosa | Y_versicolor | Y_virginica | F_setosa | F_versicolor | F_virginica |
---|---|---|---|---|---|---|
1 | 1 | 0 | 0 | 1 | 0 | -0.212 |
2 | 1 | 0 | 0 | 1 | 0 | -0.212 |
51 | 0 | 1 | 0 | 0 | 1 | -0.212 |
101 | 0 | 0 | 1 | 0 | 1 | 0.578 |
이것이 새로운 데이터셋이 된다. 이 새로운 데이터세 대한 3개의 다른 결정 트리를 만들어 위 작업을 반복한다. 연산은 만족스러운 성공을 얻을 때까지 반복한다.
최종 예측
최종적으로 모든 회차의 예측(F로 시작하는 컬럼)을 합한다. 최대 지수 값(maximum index value)이 예측값이다.
10회차동안 144개를 올바르게 분류하고 6개를 잘못 불류했다. 이것은 96%의 정확도로 boosting이전 70%의 정확도보다 큰 개선이 있었다는 의미이다.