Tab study에서 배운 트리의 앙상블에 대해 정리해보려한다.
정형 데이터 vs 비정형 데이터
정형 데이터란?
정형 데이터는 어떠한 구조로 되어 있는 데이터로 CSV나 데이터베이스 혹은 엑셀에 저장하기 쉬운 데이터를 말합니다.
비정형 데이터란?
비정형 데이터는 데이터베이스나 엑셀로 표현하기 어려운 데이터들을 말한다. 예를 들어, 디지털 사진, 디지털 음악 등이 있다.
앙상블 학습(ensemble learning)
대부분의 머신러닝 알고리즘은 정형 데이터에 잘 맞는다. 이 정형 데이터에서 가장 뛰어난 성과를 내는 알고리즘은 앙상블 학습(ensemble learning)이다.
앙상블 학습 기법인 Voting vs Bagging vs boosting
Voting 방식
voting방식은 단어의 뜻을 보면 알 수 있듯이, 서로 다른 알고리즘으로 예측한 후 결과를 투표를 해 최종 예측 결과를 산출하는 방식이다.
- Hard voting : 다수의 classifier 간 다수결의 원칙으로 예측 결과를 결정
- Soft voting : 다수의 classifier들의 class 확률을 평균을 내어 결정
Bagging 방식
Bagging 방식은 전체 학습 데이터에서 개별 데이터 세트들로 샘플링 하고, 대부분 결정 트리 알고리즘을 사용한다. 샘플링 된 개별 데이터 서브세트를 가지고 같은 (결정 트리) classifier이 학습을 하고, 각각의 class에 대한 확률을 평균을 내서 최종 예측값을 도출한다. 즉, Bagging의 방식의 가장 중요한 부분은 Sampling이다.
- Bagging 방식 : 랜덤 포레스트
Boosting 방식
Boosting 방식은 Bagging 방식과 유사한 방식으로 진행된다. 하지만 boosting은 순차적으로 학습이 진행되고, 이전 분류기의 학습 결과를 토대로 다음 분류기의 학습 데이터의 샘플 가중치를 조정해 학습을 진행하는 방법이다.
즉, Bagging은 각각 분류기의 학습이 독립적이지만 Boosting은 상호 영향을 준다.
- 부스팅
- 그래디언트 부스팅(Gradient Boosting)
- XgBoost
- LightGBM
랜덤 포레스트(Random Forest)
랜덤 포레스트는 앙상블 학습의 대표로 안정적인 성능을 보여준다. 랜덤 포레스트는 배깅 방식을 사용하는 대표적인 모델이다.
랜덤 포레스트는 랜덤하게 선택한 샘플과 특성을 사용하기 때문에 훈련 세트에 과대적합되는 것을 막아주고 검증 세트와 테스트 세트에서 안정적인 성능을 얻을 수 있다.
- 분류 모델의 랜덤 포레스트 : Randomforestclassifier
- 회귀 모델의 랜덤 포레스트 : RandomForestRegressor
랜덤 포레스트 훈련 방법
부트스태랩 샘플(bootstrap sample)
랜덤 포레스트는 각 트리를 훈련하기 위한 데이터를 랜덤하게 만드는데, 이때 부트스트랩 샘플을 사용한다.
부트스트랩 방식은 데이터 세트에서 중복을 허용하여 데이터를 샘플링하는 방식이다.
랜덤 포레스트 코드로 알아보기
데이터 셋
1
2
3
4
5
6
7
8
9
10
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
wine = pd.read_csv('https://bit.ly/wine_csv_data')
data = wine[['alcohol', 'sugar', 'pH']].to_numpy()
target = wine['class'].to_numpy()
train_input, test_input, train_target, test_target = train_test_split(data, target, test_size=0.2, random_state=42)
랜덤 포레스트 교차 검증 해보기
1
2
3
4
5
6
from sklearn.model_selection import cross_validate
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(n_jobs=-1, random_state=42)
scores = cross_validate(rf, train_input, train_target, return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']))
1
0.9973541965122431 0.8905151032797809
특성 중요도 확인
1
2
rf.fit(train_input, train_target)
print(rf.feature_importances_)
1
[0.23167441 0.50039841 0.26792718]
그레디언트 부스팅(gradient boosting)
그레디언트 부스팅은 깊이가 얕은 결정 트리를 사용하여 이전 트리의 오차를 보완하는 방식으로 앙상블 하는 방법이다.
scikit-learn에 GradientBoostingClassifier로 사용할 수 있다.
그레디언트 부스팅은 깊이가 얕은 경사하강법을 사용하기 때문에 과대적합에 강하고 일반적으로 높은 일반화 성능을 기대할 수 있다.
1
2
3
4
from sklearn.ensemble import GradientBoostingClassifier
gb = GradientBoostingClassifier(random_state=42)
scores = cross_validate(gb, train_input, train_target, return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']))
1
0.8881086892152563 0.8720430147331015
거의 과대적합(overfitting)이 일어나지 않았다.
XGBoost
XGBoost는 그레디언트 부스팅 알고리즘의 단점을 보완한 알고리즘이다. XGBoost는 그레디언트 부스팅을 기반으로 한 알고리즘이지만 훨씬 빠르고, early stopping등의 규제로 과대적합을 방지할 수 있다.
LightGBM
XGBoost는 써보면 알겠지만 모델을 학습하는데 엄청난 시간이 걸린다. LightGBM은 이런 단점을 보완한 알고리즘이다.
LightGBM은 대용량 데이터 처리가 가능하고 메모리를 적게 사용하며 빠르지만, 너무 적은 수의 데이터를 사용하면 과대적합이 일어날 수 있다.
느낀점
Tab 스터디를 통해 머신러닝에서 성능이 좋게 평가되는 앙상블 기법을 이용한 여러가지 모델들을 배워보았다. 각 앙상블 방식에 따라 나눠지는 모델을 잘 기억하고 요새 lightGBM을 많이 쓴다는대, 더 열심히 공부해봐야겠다.