본문 바로가기

언어/참고

11/17 데이터마이닝 (부스팅, 스태킹)

부스팅은 기본적으로 weak learner를 학습하여 sequential한 tree를 만듦. 그렇다고 parallel한 tree를 만들지 못하는 것은 아님.

 

부스팅은 최근 개발된 xgboost, lightgbm, catboost를 주로 사용하게 되는데, 이 3가지 부스팅 방법 모두 parallel한 프로세스를 increment해서 속도가 빠른 편.

하지만 부스팅은 사용하는 hyperparameter 개수가 많아서 튜닝이 상당히 오래 걸린다는 단점이 있음.

 

부스팅의 특징

부스팅은 트리가 sequential하게 생성됨 -> 각각의 트리가 이전의 트리에서 얻은 정보를 사용함 -> 과적합 가능성이 높음

부스팅에는 부트스트랩 샘플링 같은 과정이 없는 대신 subset을 사용할 수는 있음.

부스팅의 하이퍼파라미터로 1. 트리의 수를 나타내는 B, 2. shirinkage parameter (learning rate)인 lambda, 3. 개별 트리 내에서 분할되는 수인 d가 있고 다른 하이퍼파라미터도 있음.

여기서 learning rate를 크게 하면 그 속도는 빠르지만 최적값을 잘 찾지 못함. 작게 하면 최적값을 잘 찾지만 찾는데 시간이 오래 걸림. 그래서 초반에 lr을 크게 하고, 점차 lr을 줄이는 방법을 자주 사용하고 이를 adaptive라고 하나봄.

 

그래디언트 부스팅은 gradient descent를 사용하여 Loss function을 최소화하는 파라미터를 찾음.

그래디언트 부스팅은 loss function의 negative gradient에 적합한다고 할 수 있음.

R의 함수로는 gbm을 씀.

하이퍼 파라미터로 트리의 개수 n.trees, 트리의 깊이를 나타내는 interaction.depth, 학습률인 shirinkage, 모든 샘플을 쓰는 것이 아니라 설정한 비율의 subsample을 사용하는 subsamplig rate를 나타내는 bag.fraction, 마지막으로 최적의 트리 개수를 찾기 위한 cv를 수행하는 cv.folds가 있다.

 

그래디언트 부스팅에서 파생된 다른 방법 - xgboost, lightgbm, catboost

 

xgboost의 특징: 그냥 loss function만 쓰는 것이 아니라 penalty term(r & lambda)를 추가하여 트리의 크기가 커지는 것과 터미널 노드의 수가 많아지는 것을 견제하는 특징을 가짐. -> 과적합 방지

 

lightgbm의 특징: 1. Leaf-wise tree growth - 기존 트리는 level-wise 트리인데, 이 경우 각 레벨의 전체 노드가 계속 갈라지는 트리가 만들어짐. 반면, leaf-wise tree는 각 레벨의 모든 노드가 갈라지는 것이 아니라 특정 노드만 갈라지고 나머지 노드는 갈라지지 않게 만듦.

2. Gradient-Based One-Side Sampling (GOSS): 과적합을 방지하기 위한 subsampling을 진행할 때, 랜덤하게 subsample을 추출하는 것이 아니라 gradient가 큰 표본을 샘플링하는 방식.

3. Exclusive Feature Bundling (EFB): 서로 exclusive한 변수를 하나로 묶어서 변수로 사용함. -> 변수 개수가 효과적으로 줄어서 빠른 연산에 도움이 됨.

 

대충 파생된 방법들이 통계적인 근거로 달라진 것이 아니라 잔머리를 써서 최대한 효율을 끌어올린 것이라고 보면 됨.

 

catboost의 특징: 시계열 데이터와 categorical한 feature가 있을 때 성능이 좋은 부스팅 방법. 범주형 독립변수를 잘 다룸.

 

* caret패키지의 train 함수에서 method로 지정되지 않은 것도 customize function으로 직접 지정하여 만들 수 있다는 점 참고

 

 

스태킹: 여러 모형을 다 모아서 쓰는 방법.

모형을 다 가져와서 쓰기 때문에 computational cost가 큰 편이다.

가져온 모델 중에서 가장 좋은 성능을 보이는 모델과 성능이 같거나 약간 더 좋아지기 때문에 super learner라고도 말한다.

 

이론상 flow chart는 다음과 같다.

 

1. 데이터를 k-fold로 나눠서 모형을 적합한다고 할 때. 각 fold를 제외한 데이터로 가져온 모든 모형을 훈련시키고 그 fold로 predict한 값들을 따로 저장하고 이를 level-1 data라고 한다.

 

2. level-1 데이터로 스태킹의 meta learner를 학습시킨다. (meta learner로도 선형회귀모형부터 랜덤포레스트, knn 등등의모형을 사용할 수 있다.)

 

3. baseline의 final model에 test data를 사용하여 level-1 data처럼 만든다.

 

4. 3에서 만든 데이터를 2에서 학습시킨 meta learner에 넣어 predict하는데 사용한다.

 

R에서는 caret패키지의 caretList라는 함수로 여러 모델을 동시에 학습시킬 수 있고, 개별 튜닝도 조절할 수 있다.

resamples 함수를 사용하면 k-fold 전체의 cv 결과를 한번에 모아서 확인할 수 있다.

dotplot으로 resampling한 데이터의 RMSE로 시각화하면 예쁘다.

caretList로 동시에 학습시킨 모형 간의 상관관계를 modelCor 함수로 확인할 수 있다. 이때, 서로 높은 상관관계를 보이는 모델일수록 앙상블 효과가 좋지 않다.

caretList로 한번에 모형을 학습시키고 한번에 예측도 가능한데, regression은 상관없지만 classification은 post.prob.이 산출되므로 ifelse문으로 직접 클래스를 정해주는 과정이 필요하다.

스태킹을 하기 위해서는 caretList로 한번에 학습시킨 오브젝트를 caretEnsemble 함수에 집어넣으면 선형회귀를 사용한 스태킹이 진행된다.

선형회귀방법을 사용한 경우 summary로 산출되는 결과를 보면, 각 모형 앞에 붙는 계수를 확인할 수 있다.

이는 선형 회귀모형에 caretList 넣어서 적합시켜도 같은 결과가 나온다.

분류 문제에 caretEnsemble을 쓰면 meta learner로 glm (로지스틱회귀)를 사용한 결과가 산출된다.

 

caretStack이라는 함수의 object로 caretList 오브젝트를 넣고 method로 무언가를 지정해주면 지정해준 방법을 사용한 스태킹이 바로 진행된다.

이때는 trControl을 지정해줘야 튜닝이 진행된다.