[머신러닝] 앙상블 학습
앙상블 학습 소개
앙상블 학습은 머신러닝에서의 중요한 전략 중 하나로, 여러 학습 알고리즘을 조합해 사용하여 예측 성능을 개선하는 기법입니다. 간단히 말해서, 여러 개의 모델을 함께 사용하여 개별 모델들보다 더 좋은 예측력을 달성하는 방식입니다. 이 접근법은 "다수결" 원칙과 유사하게, 여러 모델의 예측을 종합함으로써 더 안정적이고 정확한 예측을 할 수 있도록 돕습니다.
앙상블 학습의 정의
앙상블 학습은 여러 개별 모델(기본 학습기)을 조합하여 하나의 예측 모델을 만드는 기법입니다. 이러한 방법은 개별 모델의 오류를 상쇄하고, 일반화 능력을 증가시키며, 과적합을 줄이는 효과가 있습니다. 주요 목표는 다양한 모델들의 강점을 결합하여 최종 모델의 성능을 향상시키는 것입니다.
앙상블 학습이 필요한 이유
앙상블 학습은 여러 이유로 필요하고 중요합니다. 우선, 단일 모델은 특정 유형의 데이터에 대해 잘 작동할 수 있으나 다른 유형에서는 성능이 떨어질 수 있습니다. 앙상블 기법은 이러한 한계를 극복하고 보다 일관된 성능을 달성하게 해줍니다. 또한, 다양한 모델들이 가진 고유한 특성과 강점을 결합함으로써 예측의 정확도를 높일 수 있습니다. 예를 들어, 어떤 모델은 특정 유형의 패턴을 감지하는 데 강점을 가질 수 있으며, 다른 모델은 다른 유형의 패턴을 더 잘 감지할 수 있습니다. 앙상블 학습은 이러한 모델들을 조합하여 보다 포괄적인 시야를 제공합니다.
앙상블 학습의 주요 유형
앙상블 학습에는 주로 세 가지 유형이 있습니다: 배깅, 부스팅, 스태킹입니다.
-
배깅(Bagging): 배깅은 Bootstrap Aggregating의 줄임말로, 여러 개별 모델들이 다양한 데이터 셋의 부분 집합에서 독립적으로 학습된 후, 그 결과를 종합하여 최종 결과를 도출하는 방식입니다. 대표적인 예로 랜덤 포레스트가 있습니다.
-
부스팅(Boosting): 부스팅은 약한 학습기(weak learner)들을 순차적으로 학습시키면서, 이전 학습기가 잘못 예측한 사례에 더 많은 가중치를 부여하여 오류를 점진적으로 줄여나가는 방식입니다. 대표적인 부스팅 알고리즘에는 AdaBoost, Gradient Boosting 등이 있습니다.
-
스태킹(Stacking): 스태킹은 여러 다른 모델들의 예측 결과를 새로운 데이터 세트로 취급하고, 이를 입력으로 하여 최종 예측을 수행하는 메타 모델(meta-model)을 학습시키는 방식입니다. 이 방법은 모델 간의 상호 보완적인 특성을 활용할 수 있으며, 성능 향상을 위한 다양한 모델 조합을 탐색할 수 있습니다.
이러한 앙상블 기법들은 서로 다른 원리와 접근 방식을 가지고 있지만, 공통적으로 여러 모델의 강점을 조합하여 전체적인 성능을 향상시키는 것을 목표로 합니다. 이를 통해 단일 모델로는 얻기 어려운 높은 정확도와 안정성을 달성할 수 있습니다.
배깅(Bagging)의 이해
배깅(Bagging), 즉 부트스트랩 집계(Bootstrap Aggregating)는 앙상블 학습의 한 형태로, 높은 분산을 가진 모델, 특히 결정 트리와 같이 과적합되기 쉬운 모델의 성능을 개선하는 데 유용한 방법입니다. 배깅은 각기 다른 서브셋에서 복원 추출(부트스트랩) 방식으로 훈련 데이터를 임의로 샘플링하여 다수의 예측기를 생성하고, 그 예측기들의 결과를 평균화함으로써 전체적인 모델의 분산을 줄이고 안정성을 높입니다.
배깅의 개념과 작동 원리
배깅의 핵심 개념은 부트스트랩, 즉 임의 추출에 기반합니다. 원래 훈련 데이터셋에서 동일한 크기의 여러 서브셋을 임의로, 그리고 반복해서 선택합니다(이 때 한 샘플이 여러 번 선택될 수 있습니다). 각 서브셋으로 독립적인 모델을 훈련시킨 뒤, 이 모델들의 예측 결과를 집계하여 최종 결과를 도출합니다. 분류 문제에서는 투표 방식(가장 많은 표를 받은 클래스 선택)을, 회귀 문제에서는 평균을 사용하게 됩니다.
랜덤 포레스트: 배깅의 대표적 예시
랜덤 포레스트는 배깅을 사용하여 결정 트리들의 앙상블을 구성하는 가장 대표적인 예입니다. 여러 결정 트리를 서로 다른 데이터 샘플로 훈련시키고 그 결과를 집계하여 최종 결정을 내리는 방법입니다.
랜덤 포레스트의 특징 및 장점
- 고차원 데이터에도 잘 작동하며, 데이터의 특성을 자동으로 선택하여 효과적인 특성 조합을 찾을 수 있습니다.
- 다양한 데이터에 대해 유연하게 적용 가능하며, 과적합을 방지하고 분산을 줄이는 데 탁월한 성능을 보입니다.
- 병렬 처리가 가능해 대용량 데이터 처리에 적합하며, 내부적으로 교차 검증을 별도로 수행하지 않아도 일반화 오차를 평가할 수 있는 Out-of-Bag(OOB) 오차 추정 기능을 제공합니다.
랜덤 포레스트 실습
Python의 scikit-learn 라이브러리를 사용해 랜덤 포레스트 모델을 쉽게 구현할 수 있습니다. 아래는 간단한 예시 코드입니다.
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# 가상의 분류 데이터셋 생성
X, y = make_classification(n_samples=1000, n_features=20,
n_informative=15, n_redundant=5, random_state=42)
# 훈련 데이터와 테스트 데이터 분리
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)
# 랜덤 포레스트 분류기 생성 및 훈련
random_forest = RandomForestClassifier(n_estimators=100, random_state=42)
random_forest.fit(X_train, y_train)
# 예측 및 성능 평가
predictions = random_forest.predict(X_test)
accuracy = accuracy_score(y_test, predictions)
print(f"Accuracy: {accuracy:.2f}")
이 코드는 랜덤 포레스트를 사용하여 분류 문제를 해결하는 기본적인 절차를 보여줍니다. 여기서는 100개의 결정 트리를 사용하며, make_classification
함수를 사용해 가상의 데이터를 생성합니다. 훈련 후, 모델의 정확도를 평가하여 모델의 성능을 확인할 수 있습니다.
부스팅(Boosting)은 강력한 머신러닝 알고리즘을 구성하기 위해 여러 약한 모델(weak learners)을 순차적으로 훈련시키는 앙상블 기법입니다. 각각의 모델은 이전 모델이 실수한 부분에 더 많은 주의를 기울여 훈련됩니다. 부스팅은 주로 분류와 회귀 문제에서 사용되며, 정확도를 향상시키는 데 중점을 둡니다.
부스팅의 개념과 작동 원리
부스팅은 여러 약한 모델을 순차적으로 연결하여 강력한 학습 모델을 만드는 기법입니다. 초기 단계에서는 모든 데이터 샘플에 동일한 가중치를 부여합니다. 첫 번째 모델이 훈련된 후, 잘못 분류된 데이터 포인트의 가중치가 증가되며, 이러한 데이터에 대해 두 번째 모델이 훈련됩니다. 이 과정은 여러 모델에 걸쳐 반복됩니다. 이 방식은 알고리즘이 이전 모델들이 잘못 분류한 데이터 포인트에 집중하게 하여, 전체 모델의 성능을 향상시킵니다.
주요 부스팅 알고리즘
AdaBoost의 특징 및 장점
AdaBoost(Adaptive Boosting)는 부스팅 기법 중 가장 인기 있는 알고리즘 중 하나입니다. AdaBoost는 이전 모델이 잘못 분류한 샘플에 더 높은 가중치를 부여하는 방식으로 작동하며, 각 단계에서 모델은 전체 데이터 세트를 사용해 학습합니다. 이 알고리즘은 분류 문제에 효과적이며, 사용이 쉽고, 다양한 데이터 세트에 대해 좋은 성능을 보입니다.
Gradient Boosting의 특징 및 장점
Gradient Boosting은 손실 함수의 그래디언트를 이용하여 모델을 훈련시키는 방법입니다. 이 방식은 AdaBoost와 유사하지만, 손실 함수의 오차를 직접 수정하여 모델의 성능을 향상시킵니다. Gradient Boosting은 유연성이 높아 많은 종류의 문제와 데이터 세트에 적용할 수 있으며, 높은 정확도를 제공합니다. 그러나, 파라미터 튜닝이 중요하며, 오버피팅에 주의해야 합니다.
XGBoost의 특징 및 실습
XGBoost(eXtreme Gradient Boosting)는 Gradient Boosting을 기반으로 하며, 대규모 분산 컴퓨팅 환경에서도 뛰어난 성능과 속도를 제공합니다. XGBoost는 결측치 처리, 트리 가지치기, 정규화 등과 같은 내장 기능을 통해 과적합을 방지하고 성능을 개선합니다.
Python을 사용한 XGBoost 실습 예제:
import xgboost as xgb
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
# 데이터 불러오기 및 전처리
boston = load_boston()
X, y = boston.data, boston.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# XGBoost 모델 학습
xg_reg = xgb.XGBRegressor(objective ='reg:squarederror', colsample_bytree = 0.3, learning_rate = 0.1,
max_depth = 5, alpha = 10, n_estimators = 10)
xg_reg.fit(X_train,y_train)
# 예측 및 성능 평가
preds = xg_reg.predict(X_test)
rmse = mean_squared_error(y_test, preds, squared=False)
print("RMSE: %f" % (rmse))
이 코드는 XGBoost를 사용하여 보스턴 주택 가격 데이터셋에 대한 회귀 모델을 학습하고 평가합니다. XGBRegressor
는 XGBoost의 회귀 모델을 위한 클래스입니다. 여기서 objective
는 손실 함수를, colsample_bytree
, learning_rate
, max_depth
, alpha
, n_estimators
는 XGBoost의 다양한 하이퍼파라미터를 설정합니다.
스태킹(Stacking)은 여러 다른 모델을 결합하여 예측을 수행하는 고급 앙상블 기법 중 하나입니다. 이 방법의 핵심은 개별 모델의 예측값을 새로운 데이터 세트로 사용하여, 최종 예측을 위해 다른 모델(메타 모델 또는 블렌더)을 훈련하는 것입니다. 여기서는 스태킹의 개념과 작동 원리, 장점 및 한계, 그리고 실습을 통한 적용 방법을 소개합니다.
스태킹의 개념과 작동 원리
스태킹은 여러 기본 모델(base models)의 예측값을 입력으로 사용하여 최종 예측을 생성하는 메타 모델(meta-model) 또는 블렌더(blender)를 훈련함으로써 작동합니다. 이 과정은 두 단계로 이루어집니다:
-
첫 번째 단계: 여러 기본 모델들이 초기 훈련 데이터에 대해서 각각 학습을 수행합니다. 각 모델은 훈련 데이터에 대해 예측을 수행하고, 이 예측값들은 새로운 데이터 세트를 형성합니다. 이 때, 각 기본 모델이 서로 다른 알고리즘을 사용할 수 있으며, 다양성을 추구하는 것이 좋습니다.
-
두 번째 단계: 생성된 새로운 데이터 세트(첫 번째 단계의 예측값)를 입력으로 사용하여, 메타 모델(또는 여러 메타 모델)을 훈련합니다. 메타 모델은 최종 예측을 위해 기본 모델의 예측을 합치는 방법을 학습합니다.
스태킹의 장점과 한계
장점:
- 다양한 모델의 장점을 결합할 수 있어, 단일 모델만 사용했을 때보다 뛰어난 예측 성능을 달성할 가능성이 높습니다.
- 기본 모델의 예측에 대한 오차를 보정하는 역할을 하여, 예측의 정확도를 향상시킬 수 있습니다.
한계:
- 스태킹의 과정이 복잡하고, 최적의 기본 모델과 메타 모델을 찾기 위한 실험이 필요합니다.
- 모델 훈련과 예측 시간이 길어질 수 있으며, 과적합(overfitting)의 위험이 있습니다.
스태킹 실습: 기본 모델 적용 및 결과 예측
아래 예시는 간단한 스태킹을 Python과 scikit-learn을 이용하여 구현하는 방법을 보여줍니다.
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.ensemble import StackingRegressor
from sklearn.linear_model import LinearRegression
from sklearn.tree import DecisionTreeRegressor
from sklearn.svm import SVR
# 데이터 로드
X, y = load_boston(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 기본 모델 정의
base_models = [
('lr', LinearRegression()),
('dt', DecisionTreeRegressor()),
('svr', SVR())
]
# 스태킹 모델 정의
stacked_model = StackingRegressor(
estimators=base_models,
final_estimator=LinearRegression()
)
# 모델 훈련
stacked_model.fit(X_train, y_train)
# 결과 예측
predictions = stacked_model.predict(X_test)
# 예측값 출력
print(predictions)
이 스크립트는 먼저 load_boston
데이터 세트를 로드하고, 이를 훈련 및 테스트 세트로 분리합니다. 그리고 세 가지 다른 기본 모델(LinearRegression
, DecisionTreeRegressor
, SVR
)을 사용하여 스태킹을 구성하고, LinearRegression
을 최종 예측을 위한 메타 모델로 사용합니다. 이러한 프로세스를 통해, 스태킹이 여러 기본 모델의 예측을 어떻게 결합하여 최종 예측을 생성하는지 파악할 수 있습니다.