ML Fundamentals를 실무 흐름으로 이해하기
머신러닝이 무엇인지 큰 그림부터, 학습 방식·핵심 알고리즘·신경망·평가지표·과적합·하이퍼파라미터 튜닝·MLOps까지 — LLM을 배우기 전에 다져야 할 ML 기초를 처음부터 끝까지 쉽지만 깊이 있게 정리합니다. 이 가이드는 개념을 나열하기보다, 실제 프로젝트에서 판단해야 하는 순서대로 내용을 따라갈 수 있게 구성했습니다.
머신러닝이 무엇인지 큰 그림부터, 학습 방식·핵심 알고리즘·신경망·평가지표·과적합·하이퍼파라미터 튜닝·MLOps까지 — LLM을 배우기 전에 다져야 할 ML 기초를 처음부터 끝까지 쉽지만 깊이 있게 정리합니다.
머신러닝이 무엇인지 큰 그림부터, 학습 방식·핵심 알고리즘·신경망·평가지표·과적합·하이퍼파라미터 튜닝·MLOps까지 — LLM을 배우기 전에 다져야 할 ML 기초를 처음부터 끝까지 쉽지만 깊이 있게 정리합니다. 이 가이드는 개념을 나열하기보다, 실제 프로젝트에서 판단해야 하는 순서대로 내용을 따라갈 수 있게 구성했습니다.
모델과 프롬프트만 보지 않고, 데이터 흐름, 평가, 배포 이후의 운영 지표까지 한 번에 연결해서 봅니다.
글로 읽은 내용을 머릿속에 오래 남기려면 먼저 흐름을 그림으로 잡는 편이 좋습니다. 아래 두 그림은 ML Fundamentals를 학습할 때 계속 되돌아볼 수 있는 기준 지도입니다.
ML Fundamentals를 처음 펼칠 때는 세부 명령보다 큰 그림이 먼저입니다. 이 섹션에서는 앞으로 배울 개념들이 어떤 문제를 풀기 위해 등장했는지부터 잡아봅니다.
| 계층 | 정의 | 예시 |
|---|---|---|
| AI (인공지능) | 사람처럼 인식·판단·행동하는 시스템 전체 | 체스 엔진, 음성 비서, 추천 시스템 |
| ML (머신러닝) | 데이터로부터 규칙을 학습하는 AI의 하위 분야 | 스팸 필터, 신용 평가 모델 |
| DL (딥러닝) | 다층 신경망으로 복잡한 패턴을 학습하는 ML의 하위 분야 | 이미지 분류(CNN), 음성 인식 |
| LLM (거대 언어모델) | Transformer 기반으로 언어를 학습한 DL의 한 갈래 | GPT, Claude, LLaMA |
학습 방식 3형제 (+1)은 선택지가 갈리는 지점입니다. 표를 기준으로 각 방법의 쓰임새와 운영상의 차이를 비교해두면 이후 판단이 훨씬 쉬워집니다.
| 방식 | 정답 데이터 | 대표 문제 | 예시 |
|---|---|---|---|
| 지도학습 (Supervised) | 입력-정답 쌍 필요 | 분류, 회귀 | 스팸 분류, 주가 예측 |
| 비지도학습 (Unsupervised) | 정답 없음 | 군집화, 차원 축소 | 고객 세그먼트, 이상 탐지 |
| 강화학습 (Reinforcement) | 보상 신호 | 순차적 의사결정 | RLHF, 게임 AI, 로봇 제어 |
| 자기지도학습 (Self-Supervised) | 데이터 자체가 정답 | 표현 학습 | LLM 사전학습(다음 토큰 예측) |
여기서는 ML 파이프라인 6단계: 데이터가 모델이 되기까지을 실제 코드와 함께 확인합니다. 예제를 그대로 따라 하기보다, 입력과 출력, 그리고 바뀌기 쉬운 부분이 어디인지 보면서 읽어보세요.
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
# 1~2. 데이터 로드
df = pd.read_csv("customers.csv")
X, y = df.drop(columns=["churn"]), df["churn"]
# 3. 데이터 분리 먼저! (전처리 파라미터는 train에서만 학습)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, stratify=y, random_state=42
)
scaler = StandardScaler().fit(X_train) # train으로만 fit
X_train_s = scaler.transform(X_train)
X_test_s = scaler.transform(X_test) # test는 transform만
# 4. baseline 모델부터
model = LogisticRegression(max_iter=1000)
model.fit(X_train_s, y_train)
# 5. 평가
y_pred = model.predict(X_test_s)
print(classification_report(y_test, y_pred))| 단계 | 무엇을 하나 | 흔한 함정 |
|---|---|---|
| 1. 문제 정의 | 분류/회귀/군집 중 무엇인지, 성공 기준(지표)을 먼저 정함 | 지표 없이 "정확하게 맞히기"만 목표로 잡음 |
| 2. 데이터 수집 | 문제와 관련된 데이터를 모음 | 레이블링 기준이 사람마다 달라 데이터 품질이 들쭉날쭉 |
| 3. 전처리 & 피처 엔지니어링 | 결측치 처리, 정규화, 범주형 인코딩, 파생 변수 생성 | 테스트 데이터 정보가 전처리 과정에 섞이는 데이터 누수(leakage) |
| 4. 모델 학습 | baseline부터 시작해 점진적으로 복잡한 모델로 | 검증 없이 바로 복잡한 딥러닝 모델부터 시도 |
| 5. 평가 | 적절한 지표로 성능 측정, 에러 사례 분석 | 정확도(accuracy) 하나만 보고 판단(클래스 불균형 시 위험) |
| 6. 배포 & 모니터링 | 실서비스에 반영하고 성능 저하를 지속 관찰 | 배포 후 데이터 분포가 변하는 드리프트를 방치 |
핵심 알고리즘 지도은 선택지가 갈리는 지점입니다. 표를 기준으로 각 방법의 쓰임새와 운영상의 차이를 비교해두면 이후 판단이 훨씬 쉬워집니다.
| 알고리즘 | 유형 | 한 줄 원리 | 특징 |
|---|---|---|---|
| 선형 회귀 | 지도(회귀) | 입력의 가중합으로 연속값을 예측 | 해석 쉬움, 빠름, baseline으로 우선 시도 |
| 로지스틱 회귀 | 지도(분류) | 가중합을 시그모이드로 0~1 확률로 변환 | 이진 분류의 표준 baseline |
| 결정트리 / 랜덤포레스트 | 지도학습 | 질문을 반복해 데이터를 가지치기하듯 분할 | 표 형태 데이터에 강함, 전처리 부담 적음 |
| 그래디언트 부스팅 (XGBoost 등) | 지도학습 | 이전 트리의 오차를 다음 트리가 보완 | Kaggle 대회 단골 우승 모델군 |
| k-NN | 지도학습 | 가장 가까운 k개 이웃의 다수결/평균으로 예측 | 단순 거리 기반, 대규모 데이터엔 느림 |
| SVM | 지도학습 | 두 클래스를 가장 넓게 나누는 경계선을 찾음 | 중소규모 고차원 데이터에 강함 |
| k-means | 비지도학습 | 중심점을 반복 이동시켜 군집을 형성 | 거리 기반 군집화, 군집 수 k를 미리 지정 |
| PCA | 비지도학습 | 분산이 가장 큰 방향으로 축을 재구성 | 고차원 데이터를 저차원으로 압축(차원 축소) |
여기서는 신경망 기초을 실제 코드와 함께 확인합니다. 예제를 그대로 따라 하기보다, 입력과 출력, 그리고 바뀌기 쉬운 부분이 어디인지 보면서 읽어보세요.
import torch
import torch.nn as nn
# ── 가장 단순한 MLP(다층 퍼셉트론) ────────────────
class SimpleMLP(nn.Module):
def __init__(self, in_dim: int, hidden_dim: int, out_dim: int):
super().__init__()
self.net = nn.Sequential(
nn.Linear(in_dim, hidden_dim),
nn.ReLU(), # 비선형 활성화 함수
nn.Linear(hidden_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, out_dim),
)
def forward(self, x: torch.Tensor) -> torch.Tensor:
return self.net(x)
model = SimpleMLP(in_dim=10, hidden_dim=32, out_dim=1)
x = torch.randn(4, 10) # 배치 크기 4, 특성 10개
y_pred = model(x) # forward pass — 순전파
print(y_pred.shape) # torch.Size([4, 1])
# backward()를 호출하면 각 가중치의 gradient가 자동 계산됨(역전파)
loss = y_pred.sum()
loss.backward()| 활성화 함수 | 특징 | 주 사용처 |
|---|---|---|
| Sigmoid | 출력을 0~1로 압축, 기울기 소실 문제 있음 | 이진 분류의 마지막 층 |
| ReLU | 음수는 0, 양수는 그대로 — 계산이 빠르고 기울기 소실이 적음 | 은닉층의 기본 선택 |
| GELU | ReLU를 부드럽게 만든 형태 | Transformer 계열 모델 |
| Softmax | 여러 값을 합이 1인 확률 분포로 변환 | 다중 분류의 마지막 층 |
CNN·RNN 한눈에: Transformer 이전의 딥러닝은 선택지가 갈리는 지점입니다. 표를 기준으로 각 방법의 쓰임새와 운영상의 차이를 비교해두면 이후 판단이 훨씬 쉬워집니다.
| 구조 | 핵심 아이디어 | 주 용도 | 한계 |
|---|---|---|---|
| CNN (합성곱 신경망) | 작은 필터가 이미지를 슬라이딩하며 지역적 패턴(선, 모서리)을 감지 | 이미지 분류, 객체 탐지 | 먼 거리의 관계 포착이 상대적으로 약함 |
| RNN / LSTM | 이전 시점의 은닉 상태를 다음 시점 입력에 함께 사용해 순서 정보를 반영 | 시계열 예측, 초기 기계번역 | 문장이 길어지면 앞부분 정보를 잊어버리고, 순차 처리라 느림 |
| Transformer | Self-Attention으로 모든 위치를 한 번에 서로 비교 — 멀어도 관계를 직접 포착 | 언어모델(LLM), 최신 비전 모델(ViT) | 입력 길이의 제곱에 비례해 연산량 증가 |
여기서는 손실함수와 최적화을 실제 코드와 함께 확인합니다. 예제를 그대로 따라 하기보다, 입력과 출력, 그리고 바뀌기 쉬운 부분이 어디인지 보면서 읽어보세요.
import torch.nn as nn
import torch.optim as optim
model = SimpleMLP(in_dim=10, hidden_dim=32, out_dim=1)
criterion = nn.MSELoss()
optimizer = optim.AdamW(model.parameters(), lr=1e-3)
for epoch in range(100):
optimizer.zero_grad() # 이전 gradient 초기화
y_pred = model(x_train)
loss = criterion(y_pred, y_train)
loss.backward() # 역전파로 gradient 계산
optimizer.step() # gradient 방향으로 가중치 업데이트
if epoch % 20 == 0:
print(f"epoch {epoch}: loss={loss.item():.4f}")| 구분 | 자주 쓰는 선택 | 용도 |
|---|---|---|
| 회귀 손실 | MSE (평균제곱오차) | 연속값 예측(가격, 온도 등) |
| 분류 손실 | Cross-Entropy | 클래스 분류, LLM의 다음 토큰 예측 |
| 옵티마이저 | SGD | 단순하고 가벼움, 학습률 튜닝에 민감 |
| 옵티마이저 | Adam / AdamW | 대부분의 딥러닝·LLM 학습에서 기본 선택 |
여기서는 모델을 어떻게 채점하나: 평가지표을 실제 코드와 함께 확인합니다. 예제를 그대로 따라 하기보다, 입력과 출력, 그리고 바뀌기 쉬운 부분이 어디인지 보면서 읽어보세요.
from sklearn.metrics import confusion_matrix, precision_score, recall_score, f1_score
y_true = [1, 0, 1, 1, 0, 1, 0, 0]
y_pred = [1, 0, 0, 1, 0, 1, 1, 0]
tn, fp, fn, tp = confusion_matrix(y_true, y_pred).ravel()
print(f"TP={tp} FP={fp} FN={fn} TN={tn}")
print(f"precision={precision_score(y_true, y_pred):.2f}")
print(f"recall={recall_score(y_true, y_pred):.2f}")
print(f"f1={f1_score(y_true, y_pred):.2f}")| 문제 유형 | 지표 | 의미 |
|---|---|---|
| 분류 | Accuracy (정확도) | 전체 중 맞힌 비율 — 클래스가 균형잡혀 있을 때만 신뢰 가능 |
| 분류 | Precision (정밀도) | "양성"이라 예측한 것 중 실제 양성 비율 — 오탐(false positive)이 비쌀 때 중요 |
| 분류 | Recall (재현율) | 실제 양성 중 모델이 찾아낸 비율 — 놓치면 안 되는 경우(질병, 사기)에 중요 |
| 분류 | F1 Score | Precision과 Recall의 조화평균 — 둘의 균형을 한 숫자로 표현 |
| 분류 | ROC-AUC | 임계값을 바꿔가며 본 전체적인 분류 성능(1에 가까울수록 좋음) |
| 회귀 | MAE / RMSE | 예측값과 실제값의 평균적인 차이(RMSE는 큰 오차에 더 민감) |
| 회귀 | R² (결정계수) | 모델이 데이터 분산을 얼마나 설명하는지(1에 가까울수록 좋음) |
과적합과 정규화은 선택지가 갈리는 지점입니다. 표를 기준으로 각 방법의 쓰임새와 운영상의 차이를 비교해두면 이후 판단이 훨씬 쉬워집니다.
| 기법 | 작동 방식 |
|---|---|
| Train/Val/Test 분리 | 검증 데이터로 과적합 시점을 조기에 감지 |
| K-겹 교차검증 (K-Fold CV) | 데이터를 K등분해 번갈아 검증에 써서 평가의 신뢰도를 높임 |
| Dropout | 학습 중 일부 뉴런을 무작위로 꺼서 특정 뉴런 의존을 방지 |
| L1/L2 정규화 | 가중치 크기에 페널티를 부과해 모델을 단순하게 유지 |
| Early Stopping | 검증 손실이 더 이상 개선되지 않으면 학습을 조기 종료 |
| 데이터 증강 | 학습 데이터를 변형·확장해 일반화 능력을 높임 |
여기서는 하이퍼파라미터 튜닝을 실제 코드와 함께 확인합니다. 예제를 그대로 따라 하기보다, 입력과 출력, 그리고 바뀌기 쉬운 부분이 어디인지 보면서 읽어보세요.
from sklearn.model_selection import RandomizedSearchCV
from sklearn.ensemble import RandomForestClassifier
param_dist = {
"n_estimators": [100, 200, 400],
"max_depth": [None, 5, 10, 20],
"min_samples_split": [2, 5, 10],
}
search = RandomizedSearchCV(
RandomForestClassifier(random_state=42),
param_distributions=param_dist,
n_iter=20, cv=5, scoring="f1", random_state=42,
)
search.fit(X_train, y_train)
print(search.best_params_)| 방법 | 설명 | 언제 쓰나 |
|---|---|---|
| Grid Search | 가능한 조합을 모두 격자로 나열해 전수 탐색 | 탐색 범위가 작을 때 |
| Random Search | 조합을 무작위로 샘플링해 탐색 | Grid Search보다 효율적, 대부분의 경우 기본 선택 |
| Bayesian Optimization | 이전 결과를 바탕으로 다음 탐색 지점을 똑똑하게 선택 | 학습 비용이 커서 시도 횟수를 아껴야 할 때 |
이 섹션은 실무 ML 워크플로우을 실무 관점에서 정리합니다. 개념을 외우기보다, 어떤 상황에서 이 기준을 꺼내 쓸지에 초점을 맞춰보세요.
배포와 MLOps 개관은 선택지가 갈리는 지점입니다. 표를 기준으로 각 방법의 쓰임새와 운영상의 차이를 비교해두면 이후 판단이 훨씬 쉬워집니다.
| 개념 | 설명 |
|---|---|
| 모델 서빙 | 학습된 모델을 API 형태로 감싸 실시간 예측 요청에 응답 |
| 데이터 드리프트 | 실서비스 입력 데이터의 분포가 학습 당시와 달라지는 현상 |
| 모델 드리프트 | 드리프트 등으로 인해 시간이 지나며 모델 성능이 서서히 저하되는 현상 |
| A/B 테스트 / 섀도우 배포 | 새 모델을 일부 트래픽에만 적용하거나 실사용에 영향 없이 결과만 비교 |
| 버전 관리 | 데이터·코드·모델 아티팩트를 함께 버전 관리해 재현성을 확보 |