pythonML

[pythonML] 배깅(Bagging)이란? | 배깅(Bagging)의 동작 원리 | 배깅을 사용한 모델 학습 코드

독립성이 강한 ISFP 2024. 8. 28. 12:21
728x90
반응형

배깅(Bagging)이란?

배깅은 동일한 알고리즘을 사용하여 여러 개의 개별 모델을 구성하는 방법입니다. 각 학습자는 원본 데이터에서 랜덤으로 샘플링(행(row)을 랜덤으로 선택)된 서브셋을 사용해 학습되며, 최종 예측은 이들의 예측을 평균내거나 다수결 투표로 결정됩니다. 대표적인 예로는 "랜덤 포레스트"가 있습니다. 

Bagging, 또는 Boostrap Aggregating은 앙상블 학습에서 사용되는 기법 중 하나인데요. 이 기법은 주로 모델의 분산을 줄이고 예측 성능을 향상하기 위해 사용되죠. Bagging은 랜덤포레스트와 유사하지만, 중요한 차이가 있습니다. 랜덤 포레스트는 각 결정 트리(Decision Tree)가 일부 피처만을 사용해 학습되는 반면, Bagging은 모든 피처를 사용합니다.


배깅(Bagging)의 동작 원리

배깅은 다음과 같은 단계를 통해 동작합니다.

 

1. 부트스트랩 재샘플 생성

원본 학습 데이터에서 랜덤 하게 중복을 허용하여 여러 샘플(헹 - row)을 만듭니다. 이 과정에서 특정 데이터 포인트(행 - row)는 여러 번 샘플링될 수 있습니다.

 

예를 들어, 원본 학습 데이터가 다음과 같은 5개의 데이터 포인트(행)로 구성되어 있다고 가정해 봅시다.

데이터 포인트 (행) 특징1 특징2 레이블
1 0.5 1.2 A
2 0.3 0.8 B
3 0.9 1.5 A
4 0.4 0.7 B
5 0.8 1.1 A

 

Bagging에서는 이 데이터에서 중복을 허용해 샘플을 만듭니다. 예를 들어, 부트스트랩 샘플 1은 다음과 같이 구성될 수 있습니다.

데이터 포인트 (행) 특징1 특징2 레이블
2 0.3 0.8 B
3 0.9 1.5 A
2 0.3 0.8 B
5 0.8 1.1 A
1 0.5 1.2 A

이와 같이 부트스트랩 샘플을 여러 개 만들고, 각 샘플에 대해 별도의 모델을 학습시킵니다.

 

2. 개별 모델 학습

생성된 각 샘플에 대해 동일한 알고리즘을 적용해 모델을 학습시킵니다. 예를 들어, 각 샘플에 대해 하나의 결정 트리(Decision Tree)를 학습시킬 수 있습니다.

 

예를 들어 세 개의 부트스트랩 샘플을 만들었다면, 세 개의 모델을 각각 학습시킵니다.

  • 모델 1: 부트스트랩 샘플 1을 사용해 학습
  • 모델 2: 부트스트랩 샘플 2를 사용해 학습
  • 모델 3: 부트스트랩 샘플 3을 사용해 학습

각 모델은 독립적으로 학습되며, 동일한 알고리즘을 사용하지만 다른 데이터로 학습되기 때문에 서로 다른 예측을 할 수 있습니다.

 

3. 예측 결합

최종 예측은 개별 모델의 예측을 결합하여 도출됩니다. 회귀 문제의 경우 평균값을 사용하고, 분류 문제의 경우 다수결 투표를 통해 최종 결과를 결정합니다.

 

예를 들어, 새로운 데이터 포인트에 대해 각 모델이 다음과 같은 예측을 했다면,

  • 모델 1: A
  • 모델 2: B
  • 모델 3: A

Bagging은 이 예측들을 결합합니다. 분류 문제라면 다수결 투표를 통해 최종 예측을 결정합니다. 이 예시에서는 A가 두 번 예측되었기 때문에 최종 결과는 A가 됩니다.


요약

  • 1단계: 원본 데이터에서 중복을 허용한 여러 개의 샘플(행)을 만듭니다.
  • 2단계: 각 샘플로 개별 모델을 학습시킵니다.
  • 3단계: 각 모델의 예측을 결합하여 최종 예측을 생성합니다.

이러한 과정이 Bagging의 핵심입니다.


장점

  • 간단한 구현: Bagging은 복잡한 수학적 개념 없이도 쉽게 구현할 수 있습니다. Scikit-learn과 같은 라이브러리를 사용하면 코드 작성이 간편합니다.
  • 분산 감소: 고차원 데이터에서 발생하는 분산을 줄이는 데 효과적입니다. 이는 모델이 새로운 데이터에 대한 일반화 성능을 향상하는 데 도움이 됩니다.
  • 누락된 데이터 처리: 누락된 데이터가 있어도 모델링이 가능하며, Out-of-Bag Error를 통해 모델의 오류를 unbiased하게 추정할 수 있습니다.

단점

  • 계산 비용: 여러 모델을 병렬로 학습시키기 때문에 계산 비용이 많이 듭니다.
  • 해석의 어려움: 예측을 평균화하거나 다수결을 통해 결합하므로, 최종 결과를 해석하는 데 어려움이 있을 수 있습니다.

결론

Bagging은 단일 모델이 가진 단점을 보완하기 위한 기법으로, 특히 분산이 높은 모델에서 뛰어난 성능을 발휘합니다. 그러나 계산 자원이 많이 소모되며, 결과 해석이 복잡해질 수 있습니다. 이러한 특성을 이해하고 사용 사례에 맞는 적절한 기법을 선택하는 것이 중요합니다.


배깅을 사용한 모델 학습

`scikit-learn` 라이브러리를 사용하여 배깅(Bagging)을 구현한 예시 코드입니다. 이 예시에서는 의사결정나무(Decision Tree)를 기본 학습기로 사용하여 배깅을 수행합니다.

# 필요한 라이브러리 임포트
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 데이터셋 로드 
data = load_breast_cancer()
X, y = data.data, data.target

# 데이터셋을 학습용과 테스트용으로 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 기본 학습기로 사용할 결정 트리 모델 정의
base_model = DecisionTreeClassifier()

# 배깅을 사용하여 여러 개의 결정 트리 모델을 학습시키는 BaggingClassifier 정의
bagging_model = BaggingClassifier(base_model, 
                                  random_state=22, 
                                  n_estimators=248, 
                                  bootstrap=True, 
                                  oob_score=True, 
                                  bootstrap_features=True)

# 모델 학습 & 예측
bagging_model.fit(X_train, y_train)
y_pred = bagging_model.predict(X_test)

# 정확도 계산
accuracy = accuracy_score(y_test, y_pred)
print(f"Bagging 모델의 정확도: {accuracy:.2f}")

> Bagging 모델의 정확도: 0.96

BaggingClassifier 인자

BaggingClassifier(base_model, 
                  random_state=22, 
                  n_estimators=248, 
                  bootstrap=True, 
                  oob_score=True, 
                  bootstrap_features=True)

base_model

- 배깅에 사용될 기본 학습기를 지정합니다. 여기서는 `DecisionTreeClassifier()`를 기본 학습기로 사용했습니다. 각 부트스트랩 샘플에 대해 이 기본 학습기를 학습시켜 개별 모델을 만듭니다.
- 기본값: DecisionTreeClassifier() (기본적으로 결정 트리가 사용됩니다.)

n_estimators

- 배깅에 사용할 개별 모델의 수를 지정합니다.  모델 수를 늘리면 일반적으로 성능이 좋아질 수 있지만, 계산 비용도 증가합니다. 248개의 모델을 사용하여 보다 안정적인 예측을 목표로 합니다. (n_estimators=248으로 설정하면 248개의 부트스트랩 샘플이 생성됩니다. 이 248개의 서로 다른 부트스트랩 샘플을 사용하여 248개의 개별 모델(결정 트리)이 각각 학습됩니다.)
- 기본값: 10 (기본적으로 10개의 개별 모델을 학습시킵니다.)

bootstrap=True

- 부트스트랩 샘플링을 사용할지를 결정합니다. `True`로 설정하면 원본 데이터에서 중복을 허용한 무작위 샘플링을 수행합니다. 배깅의 핵심 개념 중 하나로, 각 모델이 서로 다른 데이터 샘플을 학습하게 만들어 모델 간 다양성을 증가시킵니다.
- 기본값: True

oob_score=True

- OOB(Out-Of-Bag) 샘플을 사용해 모델의 성능을 평가할지를 결정합니다. OOB 샘플은 특정 부트스트랩 샘플에 포함되지 않은 데이터를 의미합니다. `True`로 설정하면, 각 모델이 학습되지 않은 샘플을 사용해 성능을 평가합니다. 이는 별도의 검증 세트를 사용하지 않고도 모델의 성능을 추정할 수 있는 방법입니다.
- 기본값: False (기본적으로 OOB 평가를 수행하지 않습니다.)

bootstrap_features=True
- 피처 부트스트랩핑을 사용할지를 결정합니다. `True`로 설정하면 피처(특징) 공간에서도 부트스트랩 샘플링이 이루어집니다. 피처의 무작위 샘플링을 통해 개별 모델 간의 다양성을 더욱 높이고, 과적합을 방지하는 데 도움이 됩니다.
- 기본값: False (기본적으로 모든 피처를 사용하여 학습합니다.)


Bagging 실제 활용 코드

<1> Bagging, ET, LGBM -> StratifiedKFold
출처:   https://dacon.io/competitions/official/235902/codeshare/6197

Model_List = [
    ensemble.BaggingClassifier(),
    ensemble.ExtraTreesClassifier(),
    LGBMClassifier(n_estimators=1000),
]

#############################

predictions = []
for model in Model_List:
  kfold = StratifiedKFold(n_splits=5, random_state=3, shuffle=True)

  n_iter= 0
  pred_test = []
  cv_accuracy = []
  for idx, (train_idx, test_idx) in enumerate(kfold.split(train_x, train_y)):
    X_train, X_test = train_x[list(train_idx), :], train_x[list(test_idx), :]
    y_train, y_test = train_y[list(train_idx)], train_y[list(test_idx)]
    print(model)
    model.fit(X_train, y_train)

    n_iter +=1
    fold_pred =model.predict(X_test)
    accuracy = np.round(accuracy_score(y_test, fold_pred), 4)

    cv_accuracy.append(accuracy)
    
    pred_test.append(model.predict(test_x))
  print(model)
  print('\n 평균검증 정확도 : ', np.mean(cv_accuracy))  
  pred_test_sum = np.array(pred_test[0]) + np.array(pred_test[1]) +  np.array(pred_test[2]) + np.array(pred_test[3]) +  np.array(pred_test[4])
  print(pred_test_sum/5)
  prediction = pred_test_sum/5
  predictions.append(prediction)
<2> Optuna -> bagging
출처: https://dacon.io/competitions/official/235902/codeshare/6177

bag_rf_50 = ensemble_model(model_rf, n_estimators = 50, fold=5, optimize = 'AUC')
prediction_models.append(bag_rf_50)

pycaret 적용 후,
ensemble_model 함수에서 n_estimators를 지정하면, 기본적으로 배깅(Bagging)이 적용.

 

728x90
반응형