Lecture 17. 앙상블 기법 (Ensemble Methods)

data_analytics
공개

2026년 4월 30일

  • 트리 하나의 variance를 어떻게 줄이는가? — 배깅(bagging)
  • 데이터가 한정적인데 어떻게 여러 training set을 만드는가? — 부트스트랩(bootstrap)
  • 왜 부트스트랩 샘플은 원 데이터의 약 63.2%만 포함하는가?
  • OOB 오차가 어떻게 교차검증을 대신하는가?
  • 랜덤 포레스트는 배깅을 어떻게 개선하는가?

시험 포인트: 트리 하나는 variance가 커서 성능이 낮다. 배깅(부트스트랩 + 평균)으로 variance를 낮추고, OOB로 CV를 대신하며, 랜덤 포레스트(피처 무작위 선택)로 트리 간 상관을 줄여 더 큰 variance 감소를 얻는다. (부스팅은 별도 영상)

1. 문제: 트리는 variance가 크다

같은 Hitters 데이터의 앞 절반(1~132번)과 뒤 절반(133~263번)으로 만든 트리는 첫 분할 변수부터 완전히 다른 구조가 나온다. training set이 조금만 바뀌어도 모델이 크게 변함 = variance가 큼.

2. 배깅(Bagging) = Bootstrap Aggregating

통계적 근거

독립 표본 \(n\) 개 평균의 분산: \(\sigma^2/n\) → 평균낼수록 변동성 감소

통계의 원리를 그대로 가져온다: 모집단 분산이 \(\sigma^2\) 일 때, 독립 표본 \(n\) 개의 평균 \(\bar{X}\) 의 분산은 \(\sigma^2/n\) 로 줄어든다.

마찬가지로 트리를 한 번이 아니라 여러 training set으로 \(B\) 번 만들어 결과를 평균내면 예측의 variance가 줄어 성능이 좋아진다.

\[ \hat{f}_{\text{avg}}(x) = \frac{1}{B}\sum_{b=1}^{B} \hat{f}_b(x) \]

  • 회귀: \(B\) 개 트리 예측의 평균.
  • 분류: \(B\) 개 트리 예측 클래스의 다수결(majority vote).

현실적 문제: 같은 크기의 새 training set을 또 구하는 건 불가능(있었으면 이미 썼을 것). → 부트스트랩으로 해결.

3. 부트스트랩(Bootstrap)

가진 training set(크기 \(n\))에서 복원 추출(sampling with replacement) 로 크기 \(n\) 인 데이터셋을 다시 만든다. 어떤 데이터는 중복, 어떤 데이터는 누락된다. 이렇게 만든 것이 부트스트랩 샘플.

graph TD
    O["원 데이터셋 (n개)"] -->|복원추출 n번| S1["부트스트랩 샘플 1"]
    O -->|복원추출 n번| S2["부트스트랩 샘플 2"]
    O -->|복원추출 n번| SB["부트스트랩 샘플 B"]
    S1 --> T1["트리 1"]
    S2 --> T2["트리 2"]
    SB --> TB["트리 B"]
    T1 & T2 & TB --> A["평균 / 다수결"]

왜 63.2% — 부트스트랩의 핵심 성질

크기 \(n\) 에서 특정 데이터가 한 번도 안 뽑힐 확률: \[ P(n) = \left(1 - \frac{1}{n}\right)^{n} \xrightarrow{n\to\infty} e^{-1} \approx 0.368 \] 따라서 각 부트스트랩 샘플은 원 데이터의 약 63.2% 를 포함(36.8%는 누락).

4. 배깅 적용 시 주의점

  • 가지치기 불필요: 각 트리는 \(T_0\)(큰 트리) 그대로 사용. 큰 트리는 bias↓·variance↑인데, 배깅이 variance만 낮추고 bias는 그대로 두므로, 굳이 가지치기로 bias를 올릴 필요가 없다.
  • \(B\) 가 커도 과적합 안 됨: \(B\) ↑ → variance 계속 감소(다시 증가하지 않음). 보통 50~500 사이. 단, 각 트리가 유사한 데이터에서 나와 완전 독립이 아니므로 variance 감소 효과에 한계가 있다(무한정 좋아지지 않음).
  • 해석 가능성 저하: 트리 하나의 직관적 해석은 잃는다.

5. OOB(Out-of-Bag) 오차 추정

각 부트스트랩 샘플에 포함되지 않은 약 1/3 데이터가 OOB 데이터. 특정 데이터 \(i\) 는 그를 포함하지 않은 약 \(B/3\) 개 트리에게 미지의 데이터다.

  • 데이터 \(i\)OOB 예측 = \(i\) 를 안 쓴 트리들의 예측 평균.
  • 모든 데이터의 OOB 예측 ↔︎ 실제값 → OOB 오차(회귀 MSE, 분류 error rate).
  • OOB 오차는 CV를 명시적으로 하지 않고도 test 오차를 추정 → 모델 선택·튜닝에 사용. (Hitters에서 OOB RMSE와 test RMSE의 패턴이 유사, OOB가 변동 더 작음)

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

배깅의 한계: 어떤 피처가 타깃에 강하게 영향을 주면 대부분 트리가 그 피처로 루트를 분할 → 트리들이 비슷해짐(상관 ↑) → variance 감소 효과 제한.

mtry (m)

분류: \(\sqrt{p}\) 회귀: \(p/3\) (튜닝 대상)

해결: 각 분할마다 전체 \(p\) 개 피처가 아니라 무작위로 \(m(<p)\) 개만 후보로 두고 그중 best를 선택. 트리마다 무작위성이 추가되어 트리 간 상관이 줄고, 독립에 가까워져 variance 감소 효과가 커진다.

  • 개별 트리 성능은 약간 떨어질 수 있으나, 더 큰 variance 감소로 전체 성능이 향상.
  • \(m\) 은 튜닝 대상(CV 또는 OOB로 결정). \(m=p\) 면 곧 배깅.

7. 부스팅(Boosting)

이 절은 녹화 강의 + 슬라이드(PDF) 기준으로 정리.

부스팅도 여러 트리를 결합한다는 점은 배깅과 같지만, 트리를 서로 독립적으로 학습하지 않고 순차적으로(sequentially) 학습한다. 앞 트리가 설명하지 못한 부분을 다음 트리가 보완하는 방식이다. 핵심은 타깃 \(y_i\) 가 아니라 현재 잔차(residual) \(r_i\) 에 트리를 적합한다는 것.

핵심 아이디어

\(y_i\) 에 과적합되는 큰 트리 1개 대신, \(y_i\) 를 천천히 학습하는 작은 트리들을 순차로.

회귀 트리 부스팅 알고리즘 (Boosting for Regression Trees)

  1. 초기화: \(\hat{f}(x)=0\), 모든 \(i\) 에 대해 잔차 \(r_i = y_i\) \((i=1,\dots,n)\).
  2. \(b=1,2,\dots,B\) 에 대해 반복:
      1. 데이터 \((X, r)\)\(d\) 개 split(\(d{+}1\)개 leaf)을 가지는 작은 트리 \(\hat{f}^{\,b}\) 를 적합.
      1. 축소율 \(\lambda\) 로 모델 갱신: \(\hat{f}(x) \leftarrow \hat{f}(x) + \lambda \hat{f}^{\,b}(x)\).
      1. 잔차 갱신: \(r_i \leftarrow r_i - \lambda \hat{f}^{\,b}(x_i)\quad(i=1,\dots,n)\).
  3. 최종 모델: \(\displaystyle \hat{f}(x) = \sum_{b=1}^{B} \lambda\, \hat{f}^{\,b}(x)\).

각 단계는 \(y_i\) 가 아니라 직전까지 못 맞춘 잔차를 설명하는 트리를 학습 → 예측함수를 점진적으로 개선하는 가법 모형(additive modeling). (슬라이드 예: feature 1개 회귀에서 트리 1,024개·\(d{=}1\) 로 red 예측함수가 blue 실제함수 \(f(x)=\sin x\) 에 점점 수렴.)

graph LR
    R0["잔차 r=y"] --> T1["트리 1<br/>(작은 d)"]
    T1 -->|"r ← r − λf¹"| R1["잔차 갱신"]
    R1 --> T2["트리 2"]
    T2 -->|"r ← r − λf²"| R2["…"]
    R2 --> TB["트리 B"]
    T1 & T2 & TB --> F["f(x)=Σ λfᵇ(x)"]

파라미터 3개

  • \(\lambda\) (shrinkage / learning rate): 학습 속도. 보통 0.001~0.3. \(\lambda\) 가 작을수록 더 천천히 학습 → 성능이 더 좋아질 수 있지만 더 많은 트리(\(B\)↑)가 필요.
  • \(B\) (트리 수): 배깅과 달리 \(B\) 가 지나치게 크면 과적합 발생. → 주어진 \(\lambda\) 에 대해 CV로 적절한 \(B\) 선택.
  • \(d\) (트리당 split 수): 개별 트리 복잡도. 보통 3~8, \(d{=}1\)(stump)로도 충분히 좋은 경우 많음. 트리 하나가 최대 \(d\)개 변수의 상호작용을 반영 → interaction depth라 부름.
강의 보충 (교수님 추가 설명) — λ는 보통 고정, B를 튜닝

\(\lambda\) 는 bias·variance와 직접적인 관계를 보여주는 파라미터가 아니다. 그래서 \(\lambda\) 에 대한 성능(test error) 곡선이 \(B\) 처럼 U자형(최솟값을 갖는 형태)으로 나오지 않는다. 게다가 \(\lambda\)\(B\) 를 동시에 그리드로 튜닝하면 계산 비용이 너무 크다. 따라서 실무에선 보통 \(\lambda\) 를 관습적 범위(예: 0.001~0.3)에서 하나로 고정해두고 \(B\) 만 CV로 튜닝한다. (\(\lambda\) 를 아예 안 본다기보다, 정밀 탐색을 생략하고 표준값을 쓰는 쪽.)

배깅 vs 부스팅

  • 배깅: variance가 높은 트리(깊은 트리)를 여러 개 학습해 평균 → 전체 모델의 variance를 줄여 예측을 안정화.
  • 부스팅: bias가 높은(학습력 약한, 작은 \(d\)) 트리를 순차 결합, 이전 모델이 못 맞춘 부분을 단계마다 보완 → 진행될수록 전체 모델의 bias를 점차 감소.

비유: 배깅 = 흔들리는 나무들을 평균내 숲 전체를 안정화 / 부스팅 = 약한 나무를 하나씩 점점 더 잘 키워 정확해짐.

  • 배깅 = 부트스트랩 샘플마다 트리를 만들어 평균/다수결 → variance 감소.
  • 부트스트랩: 복원추출로 크기 \(n\) 샘플 재생성. 각 샘플은 원 데이터의 약 63.2% 포함(\((1-1/n)^n \to e^{-1}\)).
  • 배깅 트리는 가지치기 불필요, \(B\) 커도 과적합 없음(50~500).
  • OOB 오차(누락된 1/3로 평가)가 CV를 대신.
  • 랜덤 포레스트: 분할마다 피처 \(m<p\) 무작위 선택 → 트리 상관↓ → variance 더 감소.
  • 부스팅: 작은 트리를 순차적으로 잔차에 적합 → bias 감소. 파라미터 \(\lambda\)(학습률)·\(B\)(트리 수, 너무 크면 과적합→CV)·\(d\)(interaction depth). \(\lambda\) 는 고정하고 \(B\) 를 튜닝.
맨 위로