랜덤 포레스트, 나무가 이루는 숲
Ensemble
배깅은 Variance를 줄이는데 효과적입니다. 복잡성이 높은 모델들의 분산을 낮춰줄 수 있는 것이죠. Higher Complexity & Low Bias & High Variance를 가진 모델중 하나인 Decision Tree를 사용합니다. 배깅기법을 이용하고 변수를 랜덤하게 선택함으로써 여러트리를 만듭니다. (배깅만을 이용한 Decision Tree 모델과는 다릅니다) Random Froest의 이름에 그 뜻이 다 담겨있습니다. Random하게만든 Forest입니다 ! 이 포스트는 앞선 포스트를 기반으로 작성되었습니다.
Bagging
먼저 배깅기법을 사용하여 샘플을 뽑습니다. 복원추출을 통하여 여러 개의 Bootstrap set이 나오고, 각각의 세트에서 Decision Tree를 만들 것입니다. OOB(Out of Bag)은 나중에 검증과 변수의 중요도를 내는데 쓰입니다.
Select in Varialbes at random
단순히 복원추출으로만 끝나는 것이 아닙니다. 랜덤포레스트에서는 다양성을 확보하기위해 변수를 제한합니다. 예를들어 $x_1$,$x_2$,$x_3$,$x_4$라는 변수가 있다면, 첫 번쨰 트리에서는 $x_1$,$x_2$만사용하고 두번째 트리에서는 $x_1$,$x_3$만, 세번째트리에서는 $x_1$,$x_4$만,... 사용하게됩니다. 각 트리는 주어진 변수들만 가지고 예측을 해야하기 때문에 정확도가 떨어집니다. 그래서 Weak Model이라고도 불립니다. 그런데 이렇게 예측의 정확도가 떨어지는 모델들을 모은다고해서 성능이 좋아질까요? Random Forest는 "Yes"라고 답합니다. 재밌지 않나요? 모든 부분에서 대체적으로 잘하는 사람 한 명보다 다른 것은 못하더라도 딱 하나만 잘하는 사람들을 모아서 답을 도출한 것이 더 좋은 결과를 내는 것과 같습니다. 집단 지성의 힘이 랜덤포레스트에 녹아들어있습니다.
여러개의 작은 나무들이 낸 결과를 투표합니다. 그리고 그 투표의 결과로 답을 도출합니다 !
Error
랜덤포레스트에서 형성된 나무들은 Over-fit을 하는 경향이 있습니다. Pruning(가지치기)를 하지 않기 때문입니다. 일반화에대한 오류가 있을텐데, 오류를 구하는 식은 다음과 같습니다.
$\bar{p}$는 트리들 간에 Correlation Coeficient를 의미합니다. 앙상블에서 중요한 것은 다양성이었습니다. 트리가 서로 상관관계에 있다면 분자가 증가하고 에러가 증가합니다.
$s^{2}$는 각 트리가 예측한 범주에대한 확률간의 차입니다. 예를들어 Model A가 어떤 데이터를 1이라고 예측한 확률이 0.8이고 0이라고 예측한 확률이 0.2일때 이 차이(margin)은 0.6이 됩니다. 이차이가 증가할 수록 Error는 감소하게 됩니다.
Importance_
각 트리는 변수를 제한하고 사용하게 됩니다. 예를들어 10개의 변수가 있고 각 트리마다 5개씩 변수를 사용한다고 했을 때, 첫번째 트리에서는 $x_1$,$x_2$,$x_3$,$x_4$,$x_5$를 사용한다고 합시다. 이 변수를 통해서 split을 하는데, 한번도 사용되지 않는 변수는 그 중요도가 떨어지고, 여러번사용된 변수는 중요도가 높다고 할 수 있습니다. OOB를 통해서 각 변수가 OOB Error을 얼마나 줄이는가에대한 평균($\bar{d}_i$)과 그분산(${s_i}^2$)를 통해 중요도를 구할 수 있습니다.
$Importance_i = \frac{\bar{d_i}}/s_i$
In Python
## Get Importance_
# pipeline
pipe = make_pipeline(
OneHotEncoder(use_cat_names=True),
SimpleImputer(),
DecisionTreeClassifier(random_state=2, criterion='gini',max_depth=9))
# fit & access
pipe.fit(X_train,y_train)
model_dt = pipe.named_steps['decisiontreeclassifier']
# visualization
importances = pd.Series(model_dt.feature_importances_, X_train.columns)
plt.figure(figsize=(5,15))
importances.sort_values().plot.barh();
참고자료
'인공지능 > 앙상블' 카테고리의 다른 글
[Ensemble] XGBoost, 극한의 가성비 (2) | 2021.02.14 |
---|---|
[Ensemble] Gradient Boosting, 차근차근 (0) | 2021.02.12 |
[Ensemble] Ada Boost, 모델의 오답노트 (0) | 2021.02.11 |
[Ensemble] 배깅, 언제나 처음처럼 (2) | 2021.02.10 |
[Ensemble] 백지장도 맞들면 낫다, 앙상블 OVERVIEW (0) | 2021.02.10 |
댓글