🤖 AI/ML

지도 학습

Supervised Learning

레이블된 데이터로 학습하는 ML 방식. 분류, 회귀 문제에 적용. 가장 일반적인 학습 방법.

📖 상세 설명

지도 학습(Supervised Learning)은 입력 데이터(X)와 정답 레이블(Y)이 쌍으로 주어진 데이터셋을 사용하여 입력에서 출력을 예측하는 함수를 학습하는 머신러닝 패러다임입니다. "지도"라는 이름은 정답 레이블이 학습을 가이드(supervise)한다는 의미에서 유래했습니다.

지도 학습은 머신러닝의 가장 오래된 패러다임으로, 1950년대 퍼셉트론부터 현대의 딥러닝까지 핵심 학습 방식입니다. 역사적으로 SVM, 결정 트리, 랜덤 포레스트 등 전통적 ML 알고리즘의 대부분이 지도 학습 기반이며, 딥러닝 혁명을 이끈 ImageNet 분류도 지도 학습입니다. 2020년대 LLM의 RLHF(인간 피드백 강화학습)도 지도 학습 단계(SFT)를 포함합니다.

지도 학습의 핵심 원리는 손실 함수(Loss Function)를 최소화하는 것입니다. 분류 문제에서는 Cross-Entropy Loss, 회귀 문제에서는 MSE(Mean Squared Error)가 주로 사용됩니다. 모델은 예측값과 실제 정답의 차이를 줄이는 방향으로 파라미터를 업데이트하며, 이 과정에서 역전파(Backpropagation)와 경사 하강법(Gradient Descent)이 사용됩니다.

실무에서 지도 학습은 가장 일반적이고 성공적인 ML 접근법입니다. 이미지 분류, 스팸 필터, 감성 분석, 의료 진단, 신용 평가 등 대부분의 산업 AI 애플리케이션이 지도 학습 기반입니다. 다만 고품질 레이블 데이터 확보가 비용과 시간이 많이 드는 병목이며, 이를 해결하기 위해 반지도 학습(Semi-supervised), 약지도 학습(Weak Supervision), 자기지도 학습(Self-supervised) 등의 대안 기법이 발전하고 있습니다.

💻 코드 예제

scikit-learn을 활용한 분류와 회귀 지도 학습 예제:

# 지도 학습 기본 예제 - 분류와 회귀
from sklearn.datasets import load_iris, load_boston
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor
from sklearn.metrics import accuracy_score, classification_report
from sklearn.metrics import mean_squared_error, r2_score
import numpy as np

# ===== 1. 분류 (Classification) =====
print("=" * 50)
print("분류 예제: 붓꽃 품종 분류")
print("=" * 50)

# 데이터 로드
iris = load_iris()
X, y = iris.data, iris.target

# 학습/테스트 분할
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

# 모델 학습
clf = RandomForestClassifier(n_estimators=100, random_state=42)
clf.fit(X_train, y_train)  # 지도 학습: X(입력), y(레이블) 쌍으로 학습

# 예측 및 평가
y_pred = clf.predict(X_test)
print(f"정확도: {accuracy_score(y_test, y_pred):.2%}")
print(f"\n분류 리포트:")
print(classification_report(y_test, y_pred, target_names=iris.target_names))

# 교차 검증
cv_scores = cross_val_score(clf, X, y, cv=5)
print(f"5-Fold CV 평균 정확도: {cv_scores.mean():.2%} (+/- {cv_scores.std()*2:.2%})")

# ===== 2. 회귀 (Regression) =====
print("\n" + "=" * 50)
print("회귀 예제: 주택 가격 예측")
print("=" * 50)

# 샘플 데이터 생성 (Boston 대신 synthetic)
np.random.seed(42)
X_reg = np.random.randn(500, 5)
y_reg = 3*X_reg[:,0] + 2*X_reg[:,1] - X_reg[:,2] + np.random.randn(500)*0.5

X_train_r, X_test_r, y_train_r, y_test_r = train_test_split(
    X_reg, y_reg, test_size=0.2, random_state=42
)

# 회귀 모델 학습
reg = RandomForestRegressor(n_estimators=100, random_state=42)
reg.fit(X_train_r, y_train_r)

# 예측 및 평가
y_pred_r = reg.predict(X_test_r)
print(f"MSE: {mean_squared_error(y_test_r, y_pred_r):.4f}")
print(f"RMSE: {np.sqrt(mean_squared_error(y_test_r, y_pred_r)):.4f}")
print(f"R² Score: {r2_score(y_test_r, y_pred_r):.4f}")

PyTorch를 활용한 딥러닝 지도 학습 예제:

# PyTorch 딥러닝 지도 학습
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset

# 신경망 정의
class SimpleClassifier(nn.Module):
    def __init__(self, input_dim, hidden_dim, num_classes):
        super().__init__()
        self.layers = nn.Sequential(
            nn.Linear(input_dim, hidden_dim),
            nn.ReLU(),
            nn.Dropout(0.3),
            nn.Linear(hidden_dim, hidden_dim),
            nn.ReLU(),
            nn.Dropout(0.3),
            nn.Linear(hidden_dim, num_classes)
        )

    def forward(self, x):
        return self.layers(x)

# 학습 함수
def train_supervised(model, train_loader, criterion, optimizer, epochs=10):
    model.train()
    for epoch in range(epochs):
        total_loss = 0
        correct = 0
        total = 0

        for X_batch, y_batch in train_loader:
            optimizer.zero_grad()

            # Forward pass
            outputs = model(X_batch)
            loss = criterion(outputs, y_batch)

            # Backward pass (역전파)
            loss.backward()
            optimizer.step()

            total_loss += loss.item()
            _, predicted = outputs.max(1)
            total += y_batch.size(0)
            correct += predicted.eq(y_batch).sum().item()

        acc = 100 * correct / total
        print(f"Epoch {epoch+1}/{epochs} - Loss: {total_loss:.4f}, Acc: {acc:.2f}%")

# 사용 예시
model = SimpleClassifier(input_dim=4, hidden_dim=64, num_classes=3)
criterion = nn.CrossEntropyLoss()  # 분류용 손실 함수
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 데이터 준비 (예: Iris)
X_tensor = torch.FloatTensor(X_train)
y_tensor = torch.LongTensor(y_train)
dataset = TensorDataset(X_tensor, y_tensor)
train_loader = DataLoader(dataset, batch_size=16, shuffle=True)

# 학습 실행
train_supervised(model, train_loader, criterion, optimizer, epochs=20)

📊 학습 방식 비교

머신러닝 학습 패러다임 비교:

학습 방식 데이터 요구사항 대표 알고리즘 적용 분야
지도 학습 레이블된 데이터 (X, Y) CNN, RNN, BERT, XGBoost 분류, 회귀, 예측
비지도 학습 레이블 없는 데이터 (X) K-Means, PCA, AutoEncoder 클러스터링, 차원축소
자기지도 학습 레이블 없는 데이터 (X) GPT, BERT, SimCLR 사전학습, 표현학습
강화 학습 환경 피드백 (보상) DQN, PPO, RLHF 게임, 로봇, LLM 정렬
반지도 학습 일부 레이블 + 대량 비레이블 Pseudo-labeling, MixMatch 레이블 부족 상황

🗣️ 실무에서 이렇게 말하세요

💬 회의에서
"이 문제는 지도 학습으로 접근하면 됩니다. 레이블 데이터가 1만 건 있으니 XGBoost로 빠르게 베이스라인 만들고, 성능이 부족하면 딥러닝으로 넘어가죠."
💬 면접에서
"지도 학습의 가장 큰 도전은 레이블 품질과 데이터 분포입니다. 노이즈가 있는 레이블은 모델 성능을 저하시키고, 학습과 배포 환경의 분포 차이(Data Shift)는 실제 서비스에서 성능 저하를 유발합니다."
💬 기술 토론에서
"LLM 시대에도 지도 학습은 여전히 핵심이에요. GPT도 사전학습(자기지도) 후에 SFT(Supervised Fine-Tuning)를 거치고, RLHF의 보상 모델도 인간 선호도 데이터로 지도 학습합니다."

⚠️ 흔한 실수 & 주의사항

레이블 품질 검증 없이 학습

노이즈가 많거나 불일치하는 레이블은 모델 성능을 심각하게 저하시킵니다. 레이블 품질 검수, Inter-annotator Agreement 확인이 선행되어야 합니다.

Data Leakage 무시

테스트 데이터 정보가 학습에 누출되면 과대 평가됩니다. 특히 시계열 데이터에서 미래 정보 누출, 또는 전처리 시 전체 데이터 통계 사용이 흔한 실수입니다.

올바른 접근법

데이터 분할을 먼저 수행하고, 전처리(스케일링, 인코딩)는 학습 데이터만 기준으로 fit 후 테스트에 transform하세요. 시계열은 시간순 분할, 그룹 데이터는 그룹 단위 분할을 사용합니다.

🔗 관련 용어

📚 더 배우기