정형 데이터를 다루는 데 가장 뛰어난 성과를 내는 알고리즘이 앙상블 학습(ensemble learning)이다. 이 알고리즘은 대부분 결정 트리를 기반으로 만들어져 있다.

랜덤 포레스트(Random Forest)

랜덤 포레스트는 앙상블 학습의 대표적인 모델로 안정적인 성능을 보인다. 이름 자체로 유추할 수 있듯이 랜덤 포레스트는 결정 트리를 랜덤하게 만들어 결정 트리의 숲을 만든다. 그리고 각 결정 트리의 예측을 사용해 최종 예측을 만든다.

하나의 나무는 하나의 결정 트리, 나무가 모여있는 숲이 바로 랜덤 포레스트이다.

먼저 랜덤 포레스트는 각 트리를 훈련하기 위한 데이터를 랜덤하게 만들어야 한다. 우리가 입력한 학습용 데이터에서 랜덤하게 샘플을 추출하여 학습용 데이터를 만든다. 이 때 한 샘플이 중복될 수 있다.

예를 들어, 1천개의 샘플이 들어있는 가방에서 100개의 샘플을 뽑는다. 그렇다면 먼저 1개를 뽑고, 뽑았던 샘플을 다시 가방에 넣는다. 그리고 다시 1개를 뽑는다.
이런 식으로 계속 반복한다. 이렇게 만들어진 샘플을 부트스트랩 샘플(Bootstrap Sample)이라 한다. 기본적으로 부트스트랩 샘플은 학습용 데이터의 크기와 같게 만든다.
1천개의 샘플이 들어있는 가방에서 중복하여 1천개의 샘플을 뽑는다.

부트스트랩이란?
데이터셋에서 중복을 허용하여 데이터를 샘플링하는 방식을 의미함.

또한 트리의 각 노드를 분할할 때 전체 특성 중에서 일부 특성을 무작위로 고른 후, 이 중에서 최선의 분할을 찾는다.

분류 모델인 RandomForestClassfier는 기본적으로 전체 특성 개수의 제곱근만큼의 특성을 선택한다. 즉 4개의 특성이 있다면 각 노드마다 2개의 특성을 랜덤하게 선택하여 사용한다.

다만 회귀 모델인 RandomForestRegressor는 전체 특성을 사용한다.

사이킷런(Sklearn)의 랜덤 포레스트는 기본적으로 100개의 결정 트리를 이런 방식으로 훈련한다. 그 후에 분류일 때는 각 트리의 클래스별 확률을 평균하여 가장 높은 확률을 가진 클래스를 예측으로 삼는다.
회귀일 때는 단순히 각 트리의 예측을 평균한다.

랜덤 포레스트는 랜덤하게 선택한 샘플과 특성을 사용하기 때문에 학습용 데이터셋에 과대적합 되는 것을 막아주며, 검증 셋과 테스트 셋에서 안정적인 성능을 얻을 수 있다.

데이터 준비

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_X, test_X, train_y, test_y = train_test_split(data, target, test_size=0.2, random_state=42)

cross_validate() 함수를 이용해 교차 검증을 수행함.

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_X, train_y, return_train_score=True, n_jobs=-1)
#return_train_score=True=> validate의 점수 뿐만 아니라, 학습용 데이터셋에 대한 점수도 같이 반환함.
#학습용 셋과 검증용 셋의 점수를 비교하면 과대적합을 파학하는 데 용이함.

print(np.mean(scores['train_score']), np.mean(scores['test_score']))
#출력값: 0.9973541965122431 0.8905151032797809

출력된 결과를 보면 학습용 데이터셋에 과대적합한 것으로 보임.

RandomForestClassfier에는 이전에 학습용 데이터셋에서 중복을 허용하여 부트스트랩 샘플을 만들어 결정 트리를 훈련한다고 했다. 이 때 부트스트랩 샘플에 포함되지 않고 남는 샘플이 있다. 이러한 샘플을 OOB(Out of Bag) 샘플이라 한다. 이 OOB 샘플을 사용하여 부트스트랩 샘플을 이용하여 학습시킨 모델을 마치 Validate Set처럼 평가할 수 있다.

rf = RandomForestClassifier(oob_score=True, n_jobs=-1, random_state=42)
rf.fit(train_X, train_y)

print(rf.oob_score_)
#출력값: 0.8934000384837406

교차 검증에서 얻은 점수와 매우 비슷한 결과가 나왔다. OOB점수를 이용하면 교차 검증을 대신할 수 있어, 더 많은 샘플을 사용할 수 있다.

profile
노력하는 개발자

0개의 댓글