1️⃣ 앙상블 기법: 배깅과 부스팅을 통해 모델 조합으로 성능 향상
2️⃣ 과적합 vs 과소적합
3️⃣ 하이퍼파라미터 튜닝: GridSearchCV, RandomizedSearchCV 등을 통해 모델 성능 최적화
4️⃣ Feature Importance 시각화를 통해 트리기반의 모델의 경우 어느정도 해석도 가능
앙상블 기법을 통해 여러 모델을 결합하고, 손실 함수를 활용해 예측 오류를 측정하며, 과적합을 방지하고 하이퍼파라미터 튜닝을 통해 모델 성능을 최적화하는 방법을 알아보겠습니다!
여러개의 모델을 조합하여, 하나의 모델보다 더 좋은 예측 성능을 내는 방법

병렬적, 각각 독립적으로 학습, 결과 종합
학습 데이터를 무작위로 여러 부분 샘플(부트스트랩)로 나누어 각각 독립적으로 모델을 학습
예측 시에는 여러 모델의 결과를 평균(회귀) 혹은 다수결(분류)로 결정
(평균을 내서 최종 예측을 한다 = 회귀
가장 많은걸 선택해서 예측 = 분류)

결정 트리 여러 개를 만들 때, 각 트리에 사용하는 피처와 데이터 샘플을 무작위로 선택 (피처 샘플링 + 데이터 샘플링)

결정 트리(Decision Tree)는 데이터를 여러 조건(규칙)으로 분할하여 트리 형태로 예측을 수행하는 머신러닝 모델
트리기반 모델은 회귀와 분류 모두 할 수 있다.
장점
단점
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
# 1. 데이터 로드
data = load_breast_cancer()
X = data.data
y = data.target
# 2. 학습/테스트 분할
X_train, X_test, y_train, y_test = train_test_split(
X, y,
test_size=0.2,
random_state=42,
stratify=y
)
# 3. 랜덤 포레스트 모델 생성
# n_estimators는 사용할 트리의 개수, max_depth는 각 트리의 최대 깊이를 의미하며
# 위 2개의 값을 높일 수록 시간과 연산량은 늘어나지만 더욱 복잡한 특징을 잡을 수 있음
rf_model = RandomForestClassifier(
n_estimators=100,
max_depth=None,
random_state=42
)
# 4. 모델 학습
rf_model.fit(X_train, y_train)
# 5. 예측
y_pred = rf_model.predict(X_test)
# 6. 성능 평가
acc = accuracy_score(y_test, y_pred)
cm = confusion_matrix(y_test, y_pred)
report = classification_report(y_test, y_pred)
print(f"Accuracy: {acc:.4f}")
print("Confusion Matrix:\n", cm)
print("Classification Report:\n", report)
RandomForestClassifier , RandomForestregressor
종속변수만 연속적인 숫자로 하면 됨
load_breast_cancer()를 통해 이진분류용 유방암 진단 데이터셋을 불러온다. 데이터(X)와 라벨(y)을 분리.
train_test_split()으로 학습(train) 세트와 테스트(test) 세트를 8:2 비율로 분할.
random_state로 난수를 고정하고, 클래스 비율이 유지되도록 stratify=y를 지정.
n_estimators는 사용할 트리의 개수, max_depth는 각 트리의 최대 깊이
정확도(Accuracy), 혼동 행렬(Confusion Matrix), 분류 보고서(Classification Report)를 출력해 성능을 평가.
- accuracy_score()로 정확도.
- confusion_matrix()를 통해 실제 라벨 대비 예측 라벨의 분포
- classification_report()로 정밀도(precision), 재현율(recall), F1 점수 등 세부 지표를 확인
순차적으로 모델을 학습하면서 이전 모델이 만든 예측 오류를 보정하도록 설계
각각의 모델은 이전 모델이 틀린 부분에 가중치를 더 둬서 학습

대표 알고리즘
장점
단점
순차적(Sequential)으로 학습하므로 병렬화가 쉽지 않음(속도측면)
하이퍼파라미터가 많고 튜닝이 까다롭다
# 1. 데이터 준비 (Titanic 예시: 범주형 컬럼 존재)
from sklearn.datasets import fetch_openml
import pandas as pd
import numpy as np
# OpenML에서 Titanic 데이터셋 로드
titanic = fetch_openml('titanic', version=1, as_frame=True)
df = titanic.frame
df
# 주요 컬럼만 사용하고, 결측치가 있는 행 제거(XGB와 Light GBM을 위해)
# pclass(객실 등급, 범주형), sex(성별, 범주형), age(나이, 연속형), fare(티켓 요금, 연속형)
# embarked(탑승항구, 범주형), survived(생존 여부, 타깃)
df = df[['pclass', 'sex', 'age', 'fare', 'embarked', 'survived']]
df.dropna(inplace=True)
df
# 입력(X), 타깃(y) 분리
X = df.drop('survived', axis=1)
y = df['survived'].astype(int) # survived 컬럼을 int형으로 변환
print(X.shape)
print(y.shape)


종속/독립 분리
# 2. 데이터 전처리
# XGBoost/LightGBM은 숫자형 입력만 허용하므로, 범주형 칼럼을 인코딩
from sklearn.preprocessing import LabelEncoder
cat_cols = ['sex', 'embarked'] # 범주형으로 간주할 컬럼들
for col in cat_cols:
le = LabelEncoder()
X[col] = le.fit_transform(X[col])
X

LabelEncoder를 사용해 sex, embarked 등 범주형 컬럼들을 수치화.# 3. 학습/테스트 데이터 분할
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
X, y,
test_size=0.2,
random_state=42,
stratify=y
)
print(X_train.shape)
print(y_train.shape)
print(X_test.shape)
print(y_test.shape)
마찬가지 회귀, 분류 가능
XGBRegressor로 회귀 가능
# 4. XGBoost 실습
# (설치가 필요할 수 있습니다) ! pip install xgboost
from xgboost import XGBClassifier
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
xgb_model = XGBClassifier(random_state=42)
xgb_model.fit(X_train, y_train)
y_pred_xgb = xgb_model.predict(X_test)
print("=== XGBoost ===")
print("Accuracy:", accuracy_score(y_test, y_pred_xgb))
print("Confusion Matrix:\n", confusion_matrix(y_test, y_pred_xgb))
print("Classification Report:\n", classification_report(y_test, y_pred_xgb))

XGBClassifier를 생성 후 fit으로 학습predict 결과와 실제값을 비교해 정확도, 혼동행렬, 분류 보고서를 출력# 5. LightGBM 실습
# (설치가 필요할 수 있습니다) ! pip install lightgbm
from lightgbm import LGBMClassifier
lgb_model = LGBMClassifier(random_state=42)
lgb_model.fit(X_train, y_train)
y_pred_lgb = lgb_model.predict(X_test)
print("\n=== LightGBM ===")
print("Accuracy:", accuracy_score(y_test, y_pred_lgb))
print("Confusion Matrix:\n", confusion_matrix(y_test, y_pred_lgb))
print("Classification Report:\n", classification_report(y_test, y_pred_lgb))

LGBMClassifier를 생성 후 동일한 절차로 학습/예측/평가코랩사용자도 무조건 설치해야함
# 설치 필수!
! pip install catboost
# 6. CatBoost 실습 (범주형 특성 직접 지정 예시)
# -> 별도의 인코딩 없이도 'cat_features' 인덱스를 지정 가능
# 이전 예시에선 이미 LabelEncoder로 숫자로 바꿨지만,
# CatBoost는 원본 범주형(문자열) 상태로도 학습 가능.
from catboost import CatBoostClassifier
# CatBoost용 데이터 준비: 원본 df에서 결측 제거(위에서 한 것 동일)
df_cat = titanic.frame[['pclass', 'sex', 'age', 'fare', 'embarked', 'survived']].dropna()
X_cat = df_cat.drop('survived', axis=1)
y_cat = df_cat['survived'].astype(int)
X_cat

범주형 변수 그대로 있음
# cat_features 인덱스: 'sex', 'embarked' 컬럼(원본 df에서의 컬럼 인덱스)
# DataFrame 사용 시에는 컬럼 이름이 아니라 "열의 위치"를 지정해야 함
# - pclass : 0, sex: 1, age: 2, fare: 3, embarked: 4
cat_features_idx = [1, 4]
X_cat_train, X_cat_test, y_cat_train, y_cat_test = train_test_split(
X_cat, y_cat, test_size=0.2, random_state=42, stratify=y_cat
)
cat_model = CatBoostClassifier(
cat_features=cat_features_idx,
verbose=1, # 학습과정 확인 가능
random_state=42
)
cat_model.fit(X_cat_train, y_cat_train)
y_pred_cat = cat_model.predict(X_cat_test)
print("\n=== CatBoost ===")
print("Accuracy:", accuracy_score(y_cat_test, y_pred_cat))
print("Confusion Matrix:\n", confusion_matrix(y_cat_test, y_pred_cat))
print("Classification Report:\n", classification_report(y_cat_test, y_pred_cat))

cat_features) 가능cat_features 인덱스를 설정(카테고리 변수 설정)CatBoostClassifier로 학습 후, 예측 결과를 평가verbose: 학습하는 과정을 볼 수 있게 함. 숫자만큼 학습할 때 마다 출력해줌일반화가 안 된 상황
앙상블은 과적합 방지에 좋음(일반화가 잘 된 결론을 냄)
학습 데이터에는 지나치게 최적화되었지만, 새로운 데이터(테스트/실제 환경)에는 성능이 떨어지는 현상
원인
모델의 파라미터(자유도)가 너무 많아서 복잡도 과다(모델이 지나치게 복잡)
특이한 데이터가 일부 존재할 수 있음
학습 데이터 수가 충분하지 않음
너무 많은 에폭(딥러닝 등)으로 학습
에폭 = iteration, 반복횟수
노이즈가 많은 훈련 데이터에서 패턴을 ‘과하게’ 학습
해결방법
규제-정규화-(Regularization) 기법
L1, L2 정규화 : 가중치(모델 파라미터)에 패널티를 줘서 과도한 학습 억제
릿지/라쏘 등.
penalty에 l1/l2 적용
드롭아웃(Dropout, 딥러닝에 주로 사용)
학습 시 일부 뉴런을 확률적으로 비활성화 → 과적합 완화
랜덤포레스트느낌.
데이터 증강(Data Augmentation)
테크닉을 써서 데이터 수를 늘림
- 이미지 데이터의 경우, 회전·이동·반전 등으로 새 데이터를 생성
- 자연어 데이터에도 유사한 패턴으로 증강 가능
- 신호 데이터의 경우 가우시안 노이즈를 추가하여 증강 가능
조기 종료(Early Stopping)
학습 도중 검증 손실이 증가하기 시작하면 학습을 중단
앙상블(Ensemble)
서로 다른 모델을 결합하여 과적합 위험을 줄임
모델이 데이터의 패턴을 충분히 학습하지 못해, 학습 데이터조차도 충분히 맞추지 못하는 현상
해결방법
파라미터는 모델이 정해주는 값(x앞에 붙는 값)
모델이 학습을 시작하기 전에 사람이 설정해야 하는 값 = 하이퍼 파라미터
ex) 결정 트리의 최대 깊이(max_depth), 학습 횟수 등
Training Set: 모델 학습에 직접 사용
Validation Set: 하이퍼파라미터 튜닝이나 모델 선택을 위해 사용
하이퍼파라미터 평가할 때 사용.
Test Set: 최종 성능 평가(훈련/검증 단계에 절대 포함되면 안 됨)
데이터를 훈련 세트와 검증 세트(fold)로 여러 번 겹치지 않게 나누어 사용
장점: 데이터가 적은 상황에서도 안정적인 성능 평가 가능
1️⃣ Grid Search
2️⃣ Randomized Search
3️⃣ 베이지안 최적화(Bayesian Optimization)
어느정도 이유를 가지고 그럴싸한 조합을 가지고 시도
Grid SearchCV 코드
cv = cross validation
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
# 1. 데이터 로드
iris = load_iris()
X = iris.data
y = iris.target
# 2. 학습/테스트 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(
X, y,
test_size=0.2,
random_state=42,
stratify=y
)
# 3. 하이퍼 파라미터 후보군 설정
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [None, 5, 10]
}
# 4. GridSearchCV 생성
rf = RandomForestClassifier(random_state=42)
grid_search = GridSearchCV(
estimator=rf,
param_grid=param_grid,
cv=5, # 교차검증(fold) 횟수
scoring='accuracy',
n_jobs=-1, # 병렬 처리(가능한 모든 코어 사용)
)
# 5. 학습(그리드서치 수행)
grid_search.fit(X_train, y_train)
# 6. 최적 파라미터 및 성능 확인
print("Best Parameters:", grid_search.best_params_)
print("Best CV Score:", grid_search.best_score_)
# 7. 테스트 데이터 성능 확인
best_model = grid_search.best_estimator_
y_pred = best_model.predict(X_test)
test_acc = accuracy_score(y_test, y_pred)
print("Test Accuracy:", test_acc)
stratify=y를 통해 클래스 비율이 유지되도록 함param_grid에 정의한 파라미터 후보군(param_grid)을 넣기.cv=5로 5-Fold 교차검증을 수행.scoring='accuracy'로 정확도를 기준으로 최적 파라미터를 찾기.n_jobs=-1로 가능한 모든 CPU 코어를 사용해 계산을 병렬화.fit(X_train, y_train)을 통해 주어진 파라미터 후보군 각각에 대해 모델을 학습하고 교차검증 성능을 비교.best_params_는 최고 성능을 낸 파라미터 조합.best_score_는 교차검증에서의 최고 정확도.best_estimator_는 최적 파라미터로 학습된 모델을 의미.주요기법
Feature Importance 코드 예시
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
# 1. 데이터 로드
iris = load_iris()
X = iris.data
y = iris.target
feature_names = iris.feature_names
# 2. 학습/테스트 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(
X, y,
test_size=0.2,
random_state=42,
stratify=y
)
# 3. 랜덤 포레스트 모델 학습
rf = RandomForestClassifier(random_state=42)
rf.fit(X_train, y_train)
# 4. 피처 중요도 추출
importances = rf.feature_importances_
# 5. 시각화
plt.bar(range(len(importances)), importances)
plt.xticks(range(len(importances)), feature_names, rotation=45)
plt.xlabel("Feature")
plt.ylabel("Importance")
plt.title("Feature Importances in RandomForest")
plt.tight_layout()
plt.show()
# 가장 중요한 변수
most_important_idx = importances.argmax()
most_important_feature = feature_names[most_important_idx]
print("가장 중요한 변수:", most_important_feature)