← 모델 목록
수업 실습 2026-08-30 · tabular-classification
트리 앙상블 계열 (랜덤 포레스트, 배깅)

RandomForestClassifier (scikit-learn)

랜덤 포레스트 구독 이탈 예측 (ML 미니대회 분류 트랙)
모델
부트스트랩 샘플로 만든 결정 트리 여러 개의 투표로 분류하는 배깅 앙상블. class_weight balanced
사용 목적
수업 ML 미니대회 분류 트랙에서 배깅 모델을 비교하고, 깊이 제한과 Optuna 튜닝이 이탈 탐지를 얼마나 바꾸는지 확인하려고 사용
코드
mnmms/mldl
가중치
없음
val_auc76.1%
f122.3%
recall14.5%
실험3회 · 대표 r1
학습 시간없음
추론 CPU / GPU측정 안 함

데이터

  • 대회 제공 train 90,000 · 양성 10.71%
  • train 72,000 · valid 18,000 (stratify, seed 42)

학습

  • 트리 300개 · class_weight balanced
  • Optuna 100 trials 약 26분 (F1 목적)
  • CPU · scikit-learn 1.9.0

결과

  • valid ROC-AUC 0.761 (기본값이 가장 높음)
  • F1 0.223 → 0.352 (Optuna)
  • Optuna 후 AUC는 0.7605로 그대로

배운 점

  • 깊이 제한 없으면 balanced 효과가 희석됨
  • F1로 튜닝해도 AUC는 오르지 않음
개요용도 의도한 용도: 미니대회에서 배깅 모델을 비교하고 깊이 제한·하이퍼파라미터 튜닝 효과 확인 대상 사용자: 해당 없음 (학습…

용도

  • 의도한 용도: 미니대회에서 배깅 모델을 비교하고 깊이 제한·하이퍼파라미터 튜닝 효과 확인
  • 대상 사용자: 해당 없음 (학습용)
  • 의도하지 않은 용도: 실제 구독 이탈 예측 (합성 데이터)

모델 정보

항목 값
베이스 모델 직접 구현 (처음부터 학습)
크기 · 변형 r1 RandomForestClassifier(n_estimators=300, random_state=42, class_weight='balanced')
리비전 scikit-learn 1.9.0, optuna 4.9.0 (uv.lock 기준)
아키텍처 결정 트리 300개의 다수결
학습 방식 처음부터 학습
프롬프트 · 에이전트 구성 해당 없음
데이터결정 트리 카드 와 같은 데이터·분할·전처리입니다 (train 90,000 → fit 72,000 / valid 18,000,…

결정 트리 카드와 같은 데이터·분할·전처리입니다 (train 90,000 → fit 72,000 / valid 18,000, 전처리 후 53열, 양성 10.71%).

항목 값
확보 방식 공개 데이터셋 그대로 (수업 대회 제공 합성 데이터)
출처 mini-competition/participant/classification/train.csv
직접 수집 내용 해당 없음
이용 조건 확인 해당 없음 (수업 자료)
규모 train 90,000 / test 25,000
분할 fit 72,000 / valid 18,000 (stratify, 시드 42)
레이블·클래스 분포 이탈 10.71%
전처리 결측 중앙값·'missing', payment_method 제거, StandardScaler + OneHot
개인정보·민감정보 처리 해당 없음 (합성 데이터)
학습하이퍼파라미터 실행별로 위 실험 기록 참고. 공통 class_weight='balanced' , random_state=42 …
항목 값
하이퍼파라미터 실행별로 위 실험 기록 참고. 공통 class_weight='balanced', random_state=42
에폭 / 스텝 해당 없음
학습 시간 r3 Optuna 100 trials 약 26.5분 (노트북 Optuna 로그 17:28:56 ~ 17:55:23). r1·r2 단독 학습 시간 [미확인]
하드웨어 CPU (scikit-learn). 장비 이름 [미확인]
프레임워크 scikit-learn 1.9.0, optuna 4.9.0, pandas 3.0.5
시드 · 재현 방법 valid 분할 시드 42 (stratify). Optuna 샘플러 시드는 지정하지 않음
결과valid 18,000명 기준, 노트북 출력입니다. r1 기본 0.7606 0.223 0.145 0.484 0.892 r2 m…

valid 18,000명 기준, 노트북 출력입니다.

실행 ROC-AUC F1 recall precision accuracy
r1 기본 0.7606 0.223 0.145 0.484 0.892
r2 max_depth 4 0.7450 0.319 0.624 0.215 0.716
r3 Optuna 100 trials 0.7605 0.352 0.539 0.261 0.787
  • 혼동행렬 r1 [[15776, 297], [1648, 279]], r2 [[11677, 4396], [725, 1202]], r3 [[13135, 2938], [889, 1038]]
  • 대표 실행은 대회 지표(ROC-AUC) 기준으로 r1로 두었습니다 (사용자 확인 필요)

추론 성능 (CPU / GPU)

측정 안 함.

장비 장비 이름 배치 크기 지연 시간 (샘플당, p50 / p95) 처리량 (샘플/초) 메모리 사용
CPU [미확인] - 측정 안 함 측정 안 함 측정 안 함
GPU 해당 없음 (scikit-learn은 CPU 전용) - - - -
실험 기록3회 측정 · 대표 r1

같은 모델을 설정·분류기를 바꿔 3번 측정한 기록입니다. ★ r1이(가) 대표 결과(맨 위 수치)입니다.

직전 실행에서 바뀐 설정지표 최고값
실행날짜바뀐 점n_estimatorsmax_depthmin_samples_leafclass_weighttuningval_aucf1recallprecision학습 시간
★ r1
기본 (깊이 제한 없음)
2026-08-30기준300none1balancednone76.1%22.3%14.5%48.4%-
r2
max_depth 4
2026-08-30max_depth를 4로 제한30041balancednone74.5%31.9%62.4%21.5%-
r3
Optuna 100 trials
2026-08-30Optuna로 n_estimators·max_depth(2~12)·min_samples_leaf를 F1 목적으로 100회 탐색
best는 trial 24 (노트북 Optuna 로그)
438124balancedoptuna-f1-10076.0%35.2%53.9%26.1%26.5분
val_auc 변화 실행 순서대로 · 높을수록 좋음 · 축 일부 생략
r1 · 기본 (깊이 제한 없음)
76.1%
r2 · max_depth 4
74.5%
r3 · Optuna 100 trials
76.0%
한계 · 배운 점한계 알려진 실패 유형: r1은 이탈 1,927명 중 279명만 찾음 (recall 0.14) 편향 / 공정성 이슈: 해당 없…

한계

  • 알려진 실패 유형: r1은 이탈 1,927명 중 279명만 찾음 (recall 0.14)
  • 편향 / 공정성 이슈: 해당 없음 (합성 데이터)
  • 성능이 떨어지는 입력 조건: [미확인]
  • 다음 날 시간 분할 검증에서 랜덤 포레스트 앙상블은 CatBoost보다 약해(AUC 0.7707 vs 0.7840) 채택하지 않음 (tuning_experiments.py 실험 5 주석)

배운 점

  • 노트북 해석: max_depth를 주지 않으면 트리가 깊게 자라 다수 클래스 패턴을 촘촘히 학습해 class_weight='balanced' 효과가 희석됨 → max_depth=4로 recall이 0.14 → 0.62
  • F1을 목적으로 튜닝한 r3은 F1은 최고지만 AUC는 기본값과 같음. 대회 지표(ROC-AUC)와 튜닝 목적을 맞춰야 함 (노트북 "⚠️" 셀)
사용 방법코드 셀 2개
In [1]기본 학습 (r1)
from sklearn.ensemble import RandomForestClassifier

model_rf = RandomForestClassifier(n_estimators=300, random_state=42, class_weight='balanced')
model_rf.fit(X_train, y_train)
rf_pred = model_rf.predict(X_val)
print(confusion_matrix(y_val, rf_pred))
print('F1 Score :', f1_score(y_val, rf_pred))
Out[1] 출력 보기
[[15776   297]
 [ 1648   279]]
F1 Score : 0.22293248102277266
In [2]Optuna로 튜닝 (r3)
def objective_rf(trial):
    n_estimators = trial.suggest_int('n_estimators', 50, 500)
    max_depth = trial.suggest_int('max_depth', 2, 12)
    min_samples_leaf = trial.suggest_int('min_samples_leaf', 1, 50)

    model = RandomForestClassifier(
        n_estimators=n_estimators,
        max_depth=max_depth,
        min_samples_leaf=min_samples_leaf,
        class_weight='balanced',
        random_state=42
    )
    model.fit(X_train, y_train)
    pred = model.predict(X_val)
    return f1_score(y_val, pred)

study_rf = optuna.create_study(direction='maximize')
study_rf.optimize(objective_rf, n_trials=100)
print('best f1 :', study_rf.best_value)
print('best params :', study_rf.best_params)
Out[2] 출력 보기
best f1 : 0.35168558360155855
best params : {'n_estimators': 438, 'max_depth': 12, 'min_samples_leaf': 4}

같은 과제·데이터셋 비교 tabular-classification · 수업 미니대회: 60-day Subscription Churn (합성) · 4개

굵은 이름이 이 모델입니다. 주황 테두리가 그룹 안 최고값입니다.

val_auc 높을수록 좋음 · 축 일부 생략