본문 바로가기
Book Review/[혼공머신] 리뷰

트리 앙상블

by 3n952 2023. 1. 16.

앙상블 기법 중 트리 앙상블에 대해 공부하고 해당 내용을 리뷰해보겠습니다!


-앙상블 학습

머신러닝의 다양한 알고리즘 중 가장 강력한 알고리즘은 무엇일까요?

어떠한 데이터를 다루는지, 문제를 다루는 지에 따라 차이가 있겠지만 일반적으로 앙상블 알고리즘이 가장 강력할 것 입니다.

 

앙상블 학습(Ensemble learning)이란, 여러개의 모델 분류기를 생성하고, 그 예측을 결합하여 결과를 예측하는 머신러닝 기법입니다.

즉, 여러 모델을 결합하여 하나의 강력한 모델로서 더 나은 결과를 예측하는 것입니다.

앙상블 학습은 특히 정형 데이터가 주어졌을 때 매우 강력한 힘을 발휘합니다.

 

이번 포스팅에서는 사이킷런에서 제공하는 결정 트리 기반의 앙상블 학습을 알아보겠습니다.

 

 

1. 랜덤 포레스트(Random Forest)

 

랜덤 포레스트는 결정 트리 기반 앙상블 학습의 대표 중 하나입니다.

안정적인 성능을 보이기 때문입니다.

 

랜덤 포레스트는 결정 트리를 랜덤하게 만들어 결정 트리의 숲을 만듭니다.

그 후 각 결정 트리의 예측을 사용해 최종 예측을 만드는 형식입니다.

그림 1을 보면 더욱 쉽게 이해할 수 있습니다.

 

그림1) 랜덤 포레스트

사이킷런에서 제공하는 랜덤 포레스트는 다음과 같이 훈련과 예측이 이뤄집니다.

 

먼저 각 트리를 훈련하기 위한 데이터를 랜덤하게 만듭니다.

입력한 훈련 데이터에서 랜덤하게 샘플을 추출하여 데이터를 만들며, 중복되어 추출도 용인합니다.

훈련셋이 100개로 이뤄졌다면 훈련셋에서 중복을 포함한 100개를 추출하는 방식입니다.

이렇게 만들어진 샘플을 부트스트랩 샘플(bootstrap sample)이라고 부릅니다.(=복원 추출)

 

RandomForestClassifier는 분류 모델로 기본적으로 전체 특성 개수의 제곱근 만큼의 특성을 선택하여 최선의 분할을 찾습니다.

반면 RandomForestRegressor는 회귀 모델로 전체 특성을 사용합니다.

 

사이킷런의 랜덤 포레스트는 기본적으로 100개의 결정 트리를 이런 방식으로 훈련합니다.

부트스트랩 샘플과 특성 선택, 분할만 기억하면 됩니다. 

분류일 때는 각 트리의 클래스별 확률을 평균하여 가장 높은 확률을 가진 클래스를 예측하며,

회귀일 때는 각 트리의 예측을 평균하여 스칼라 값을 예측합니다.

 

코드로 실습을 해보겠습니다.

이전 결정 트리에서 사용했던 와인 데이터셋으로 와인을 분류해 보겠습니다.

코드는 다음과 같습니다.

import pandas as pd
import numpy as np
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)

from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(n_jobs = -1 , random_state = 42)
rf.fit(train_input, train_target)

 

훈련을 했으니 모델을 평가해보아야 할 것입니다.

이전에는 교차 검증을 진행했으나, 랜덤 포레스트의 RandomForestClassifier에는 비슷한 기능을 하는 매개변수가 있습니다.

oob_score=True의 매개변수를 사용하면 됩니다.

oob란 out of bag로 훈련셋에서 무작위로 뽑은 100개를 제외한 나머지 샘플들을 의미합니다.

이 데이터 샘플이 검증 데이터의 역할을 하는 것과 같습니다.

실제 교차 검증과 비교하여 값을 확인해보겠습니다.

코드는 다음과 같습니다.

#oob_score
rf = RandomForestClassifier(oob_score = True, n_jobs = -1 , random_state = 42)
rf.fit(train_input, train_target)
print(rf.oob_score_)

#cross_validate
from sklearn.model_selection import cross_validate
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']))

두 값 모두 약 0.89로 비슷한 값을 갖는 것을 확인할 수 있습니다.

 

2. 엑스트라 트리(Extra tree)

 

엑스트라 트리는 랜덤 포레스트와 거의 유사합니다. 기본적으로 100개의 결정 트리를 훈련한다는 점에서 부터,

결정 트리가 제공하는 대부분의 매개변수를 지원한다는 점까지 비슷합니다.

다만 차이점은 엑스트라 트리는 부트스트랩 샘플을 사용하지 않는다는 점입니다.

각각의 결정 트리를 만들 때 전체 훈련 세트를 사용합니다.

대신에 노드를 분할할 때 가장 좋은 분할을 찾는 것이 아니라 무작위로 분할합니다.

 

가장 좋은 분할과 무작위로 분할한다의 개념은 다음과 같이 정리할 수 있습니다.

랜덤포레스트는 주어진 모든 feature에 대한 정보 이득을 계산하고 가장 높은 정보 이득(information gain)을 가지는 feature를 Split Node로 선택하고 그것들은 전부 비교해서 가장 최선의 feature를 선정합니다.(이전 포스트에 설명함.) => 가장 좋은 분할을 찾아 노드를 분할 및 구성

이 과정을 통해 성능이 좋은 결정트리를 만들 수 있지만 연산량이 많이 든다는 단점이 있습니다. 

 

반면에 엑스트라 트리는 Split을 할 때 무작위로 feature를 선정합니다. feature중에 아무거나 고른 다음 그 feature에 대해서 최적의 Node를 분할합니다. => 무작위로 노드를 분할

성능이 낮아지지만 생각보다 준수한 성능을 보이고 과대적합을 막고 검증 세트의 점수를 높이는 효과가 있습니다. 그리고 속도가 빠르다는 장점이 있습니다. 

 

엑스트라 트리의 실습 코드는 다음과 같습니다.

#엑스트라 트리
from sklearn.ensemble import ExtraTreesClassifier

et = ExtraTreesClassifier(n_jobs = -1, random_state = 42)
scores = cross_validate(et, train_input, train_target, return_train_score = True, n_jobs = -1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']))

 

3. 그레이디언트 부스팅(gradient boosting) GBM


그레이디언트 부스팅은 깊이가 얕은 결정 트리를 사용하여 이전 트리의 오차를 보완하는 방식으로 앙상블 하는 기법입니다.

GBM이라고 불리기도 합니다.

경사 하강법을 사용하여 트리를 앙상블에 추가하는 방식을 사용합니다.(경사 하강법 포스팅 참고)

깊이가 얕은 결정 트리를 사용하기 때문에 과대적합에 강하고 일반적으로 높은 일반화 성능을 보여준다는 점이 장점입니다.

 

사이킷런의 GradientBoostingClassifier로 와인 데이터셋의 교차 검증 점수를 확인해 보겠습니다.

코드는 다음과 같습니다.

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']))

그레이디언트 부스팅은 결정 트리의 개수를 늘려도 과대적합에 매우 강합니다.

학습률을 증가시키고 트리의 개수를 늘려 성능을 조금 더 향상시켜보겠습니다.

코드는 다음과 같습니다.

#성능 향상: 학습률 높이고 트리 개수 증가
gb = GradientBoostingClassifier(n_estimators = 500, learning_rate = 0.2, random_state = 42)

 

이번 포스팅에서는 트리의 앙상블 기법인 랜덤 포레스트, 엑스트라 트리, 그레이디언트 부스팅에 대해 알아 보았습니다.

직전 포스팅에서 그리드 서치, 랜덤 서치를 통해 하이퍼파라미터 튜닝을 진행했었습니다.

트리의 앙상블에 하이퍼파라미터 튜닝을 적용하면 최고 수준의 성능을 내는 머신러닝 모델을 얻을 수 있을 것 입니다.

 

다음 포스팅에서는 그레이디언트 부스팅의 성능을 향상 시킨 히스토그램 기반 그레이디언트 부스팅에 대해 알아보겠습니다.

 

'Book Review > [혼공머신] 리뷰' 카테고리의 다른 글

K-Means clustering  (2) 2023.01.31
GBM기반 앙상블: XGboost, LightGBM  (0) 2023.01.16
트리 알고리즘: 결정 트리  (0) 2023.01.10
확률적 경사 하강법  (2) 2023.01.04
로지스틱 회귀  (0) 2023.01.04