콘텐츠로 이동

머신러닝

면접에서 자주 나오는 머신러닝 질문들

질문 목록

학습 기본

  • [ ] Cross Validation은 무엇이고 어떻게 해야하나요?
  • [ ] 회귀 / 분류시 알맞은 metric은 무엇일까요?
  • [ ] 알고 있는 metric에 대해 설명해주세요
  • [ ] 정규화를 왜 해야할까요?
  • [ ] Local Minima와 Global Minima에 대해 설명해주세요
  • [ ] 좋은 모델의 정의는 무엇일까요?

차원축소

  • [ ] 차원의 저주에 대해 설명해주세요
  • [ ] dimension reduction기법으로 보통 어떤 것들이 있나요?
  • [ ] PCA의 역할들(축소, 압축, 노이즈 제거)을 설명해주세요
  • [ ] LSA, LDA, SVD 등의 약자와 관계를 설명할 수 있나요?

정규화

  • [ ] L1, L2 정규화에 대해 설명해주세요

개별 알고리즘

  • [ ] Markov Chain을 고등학생에게 설명하려면?
  • [ ] 텍스트 더미에서 주제를 추출하는 방식은?
  • [ ] SVM은 왜 반대로 차원을 확장시키는 방식으로 동작할까요?
  • [ ] SVM은 왜 좋을까요?
  • [ ] 나이브 베이즈(naive bayes)의 장점을 옹호해보세요
  • [ ] Association Rule의 Support, Confidence, Lift에 대해 설명해주세요
  • [ ] K-means의 대표적 의미론적 단점은 무엇인가요?
  • [ ] 스팸 필터에 로지스틱 리그레션을 많이 사용하는 이유는?
  • [ ] OLS(ordinary least squre) regression의 공식은 무엇인가요?

최적화

  • [ ] Newton's Method와 Gradient Descent 방법에 대해 알고 있나요?

앙상블

  • [ ] XGBoost을 아시나요?
  • [ ] 앙상블 방법엔 어떤 것들이 있나요?
  • [ ] 50개의 작은 의사결정 나무는 큰 의사결정 나무보다 괜찮을까요?

평가

  • [ ] ROC 커브에 대해 설명해주실 수 있으신가요?

실무

  • [ ] 서버 100대에서 인공신경망보다 Random Forest를 써야하는 이유는?
  • [ ] 머신러닝적 접근방법과 통계적 접근방법의 차이는?
  • [ ] feature vector란 무엇일까요?

딥러닝 기초

  • [ ] 인공신경망의 일반적인 문제점은 무엇일까요?
  • [ ] 딥러닝 혁신의 근간은 무엇이라고 생각하시나요?

답변

Cross Validation은 무엇이고 어떻게 해야하나요?

한 줄 정의

데이터를 여러 부분으로 나눠 학습/검증을 반복하여 모델의 일반화 성능을 평가하는 기법

왜 필요한가?

문제: Train 성능은 좋은데 Test 성능이 나쁨 → 과적합
해결: 여러 번 검증해서 "진짜 성능" 추정

K-Fold Cross Validation

데이터를 K개로 나눔 (예: K=5)

Fold 1: [검증] [학습] [학습] [학습] [학습]
Fold 2: [학습] [검증] [학습] [학습] [학습]
Fold 3: [학습] [학습] [검증] [학습] [학습]
Fold 4: [학습] [학습] [학습] [검증] [학습]
Fold 5: [학습] [학습] [학습] [학습] [검증]

최종 성능 = 5개 검증 점수의 평균
from sklearn.model_selection import cross_val_score, KFold

kfold = KFold(n_splits=5, shuffle=True, random_state=42)
scores = cross_val_score(model, X, y, cv=kfold)

print(f"평균: {scores.mean():.3f} (±{scores.std():.3f})")

CV 종류

방법 특징 사용 시점
K-Fold 가장 일반적 대부분 상황
Stratified K-Fold 클래스 비율 유지 불균형 분류
Leave-One-Out K=n 데이터 매우 적을 때
Time Series Split 시간순 유지 시계열 데이터
Group K-Fold 그룹 단위 분리 같은 유저 데이터 분리 필요 시
from sklearn.model_selection import StratifiedKFold, TimeSeriesSplit

# 불균형 데이터
skf = StratifiedKFold(n_splits=5)

# 시계열 데이터
tscv = TimeSeriesSplit(n_splits=5)

주의사항

  1. 데이터 누수 방지: 전처리(스케일링 등)는 각 fold 안에서
  2. Shuffle: 데이터 순서에 패턴 있으면 shuffle=True
  3. K 선택: 보통 5 또는 10 (데이터 적으면 큰 K)

면접 포인트

  • 일반화 성능 추정이 목적
  • K-Fold: K번 학습/검증 → 평균
  • Stratified: 클래스 비율 유지

회귀 / 분류시 알맞은 metric은 무엇일까요?

한 줄 정의

회귀: 예측값과 실제값의 차이 | 분류: 예측 클래스의 정확성

회귀 (Regression) Metrics

Metric 수식 특징
MSE Σ(y-ŷ)²/n 큰 오차에 민감
RMSE √MSE 원래 단위로 해석
MAE Σ|y-ŷ|/n 이상치에 덜 민감
MAPE Σ|y-ŷ|/y × 100 상대적 오차 (%)
R² 1 - SS_res/SS_tot 설명력 (0~1)
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score

mse = mean_squared_error(y_true, y_pred)
mae = mean_absolute_error(y_true, y_pred)
r2 = r2_score(y_true, y_pred)

분류 (Classification) Metrics

Metric 수식 언제 사용
Accuracy (TP+TN)/전체 균형 데이터
Precision TP/(TP+FP) FP 비용 클 때 (스팸)
Recall TP/(TP+FN) FN 비용 클 때 (암 진단)
F1 2×P×R/(P+R) P와 R 균형
AUC-ROC 곡선 아래 면적 임계값 무관 비교
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score

accuracy = accuracy_score(y_true, y_pred)
precision = precision_score(y_true, y_pred)
recall = recall_score(y_true, y_pred)
f1 = f1_score(y_true, y_pred)

상황별 선택

상황 권장 Metric
균형 분류 Accuracy, F1
불균형 분류 F1, AUC-ROC, Precision/Recall
이상치 있는 회귀 MAE
비즈니스 보고 MAPE (해석 쉬움)
모델 비교 R², AUC

면접 포인트

  • 불균형 데이터에서 Accuracy는 의미 없음
  • Precision vs Recall: 비용 기준으로 선택
  • 회귀에서 이상치 있으면 MAE

알고 있는 metric에 대해 설명해주세요

Confusion Matrix 기반

              Predicted
              Pos    Neg
Actual Pos [  TP  |  FN  ]
       Neg [  FP  |  TN  ]
Metric 계산 의미
Accuracy (TP+TN)/(TP+TN+FP+FN) 전체 정확도
Precision TP/(TP+FP) 양성 예측 중 실제 양성
Recall (Sensitivity) TP/(TP+FN) 실제 양성 중 맞춘 비율
Specificity TN/(TN+FP) 실제 음성 중 맞춘 비율
F1 Score 2PR/(P+R) Precision과 Recall의 조화평균

ROC-AUC

ROC Curve: FPR(x축) vs TPR(y축)
- FPR = FP/(FP+TN)
- TPR = TP/(TP+FN) = Recall

AUC = ROC 곡선 아래 면적 (0.5~1.0)
- 0.5: 랜덤 예측
- 1.0: 완벽한 분류
from sklearn.metrics import roc_auc_score, roc_curve

auc = roc_auc_score(y_true, y_prob)
fpr, tpr, thresholds = roc_curve(y_true, y_prob)

회귀 Metrics 상세

Metric 특징
MSE 제곱 → 큰 오차 강하게 패널티
RMSE MSE의 제곱근, 원래 단위
MAE 절대값 → 이상치에 강건
MAPE 퍼센트 → 해석 쉬움 (0일 때 문제)
R² 1이면 완벽, 음수 가능 (평균보다 못함)

Log Loss (Cross-Entropy)

LogLoss = -Σ[y×log(p) + (1-y)×log(1-p)] / n
- 확률 예측의 품질 측정 - 확신 있게 틀리면 큰 패널티

다중 클래스

방식 설명
Macro 클래스별 평균 (균등 가중)
Micro 전체 TP/FP/FN으로 계산
Weighted 클래스 크기로 가중 평균
f1_score(y_true, y_pred, average='macro')  # 불균형 시 권장

면접 포인트

  • Confusion Matrix의 TP/FP/FN/TN 설명
  • AUC는 임계값 무관하게 모델 비교 가능
  • 다중 클래스에서 macro vs micro 차이

정규화를 왜 해야할까요?

한 줄 정의

피처들의 스케일을 맞춰 학습 안정성과 수렴 속도를 높이는 전처리

왜 필요한가?

문제 상황:
- 키: 150~200 (cm)
- 연봉: 3000~10000 (만원)

→ 연봉이 수치적으로 크므로 모델이 연봉에 과도하게 민감
→ Gradient Descent에서 지그재그 현상 발생

정규화 방법

방법 수식 결과 범위 특징
Min-Max (x-min)/(max-min) [0, 1] 이상치에 민감
Z-score (Standardization) (x-μ)/σ 평균0, 분산1 가장 일반적
Robust (x-median)/IQR 가변 이상치에 강건
from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler

# Z-score 정규화 (가장 많이 사용)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)  # fit은 train에만!

정규화가 필수인 알고리즘

필수 불필요
Linear Regression Decision Tree
Logistic Regression Random Forest
SVM XGBoost
KNN (거리 기반) LightGBM
Neural Network
K-means

주의사항

# ❌ 잘못된 방법 (Data Leakage!)
scaler.fit(전체_데이터)

# ✅ 올바른 방법
scaler.fit(train_데이터)
scaler.transform(test_데이터)

면접 포인트

  • 스케일 차이 → 특정 피처에 편향
  • Gradient Descent 수렴 속도 개선
  • Test에는 fit 하면 안 됨 (data leakage)

Local Minima와 Global Minima에 대해 설명해주세요

한 줄 정의

Global Minima: 전체 공간에서 가장 낮은 점 | Local Minima: 주변에서만 가장 낮은 점

시각적 이해

손실함수 L(θ)

    ╭─╮
   ╱   ╲    ╭──╮
  ╱     ╲  ╱    ╲
 ╱       ╲╱      ╲
╱    ↑    ↑       ╲____
   Local  Global
   Minima Minima

왜 문제인가?

Gradient Descent는 기울기=0인 곳에서 멈춤
→ Local Minima에 빠지면 Global Minima를 못 찾음
→ 최적이 아닌 해에서 학습 종료

딥러닝에서는?

실제로는 Local Minima가 큰 문제가 아님!

이유: 1. 고차원 공간: 모든 방향에서 동시에 최솟값이 되기 어려움 2. Saddle Point가 더 문제: 어떤 방향은 최소, 어떤 방향은 최대 3. Local Minima도 충분히 좋음: 대부분 Global과 성능 비슷

Saddle Point (안장점):
    ↗
  ↙   ↘
    ↖
한 방향: 최소 / 다른 방향: 최대

탈출 방법

방법 설명
Momentum 관성으로 작은 골짜기 통과
Learning Rate Scheduling 큰 LR → 작은 LR
Random Restart 여러 초기값에서 시작
Stochastic GD 미니배치 노이즈로 탈출
Adam Optimizer 적응적 학습률

면접 포인트

  • Local: 주변에서만 최소 / Global: 전체에서 최소
  • 딥러닝은 Saddle Point가 더 큰 문제
  • Momentum, SGD로 탈출 가능

좋은 모델의 정의는 무엇일까요?

한 줄 정의

본 적 없는 데이터에서도 좋은 성능을 내는, 일반화된 모델

좋은 모델의 조건

1. 일반화 (Generalization)
   Train 성능 ≈ Test 성능

2. 적절한 복잡도
   과적합(Overfitting) ❌
   과소적합(Underfitting) ❌

3. 비즈니스 목표 달성
   정확도 99%여도 실무에서 못 쓰면 ❌

Bias-Variance Tradeoff

Total Error = Bias² + Variance + Irreducible Noise

                    모델 복잡도 →
         ↑
  Error  │   Bias
         │    ↘
         │       ↘_____
         │              ↗ Variance
         │         ____↗
         │────────●──────────
         │     Sweet Spot
         └──────────────────────→
상태 Bias Variance 해결책
Underfitting 높음 낮음 모델 복잡도 ↑, 피처 추가
Overfitting 낮음 높음 정규화, 데이터 ↑, Dropout
Good Fit 적당 적당 유지

실무 관점의 "좋은 모델"

기준 설명
성능 Metric 기준 충족
해석 가능성 왜 그런 예측인지 설명 가능
추론 속도 서비스 지연 시간 내 응답
학습 비용 합리적인 리소스로 학습 가능
유지보수 재학습, 모니터링 용이
# 좋은 모델 = 일반화 성능 확인
from sklearn.model_selection import cross_val_score

scores = cross_val_score(model, X, y, cv=5)
print(f"평균: {scores.mean():.3f}, 표준편차: {scores.std():.3f}")

# 표준편차가 작아야 안정적인 모델

면접 포인트

  • 일반화: 본 적 없는 데이터에서의 성능
  • Bias-Variance Tradeoff 이해
  • 실무: 성능 + 해석 + 속도 + 비용

차원의 저주에 대해 설명해주세요

한 줄 정의

차원이 높아질수록 데이터가 희소(sparse)해져서 학습이 어려워지는 현상

왜 발생하는가?

1차원: ●●●●●●●●●● (밀집)
2차원: ●  ●    ●
         ●  ●
           ●    ● (분산됨)
3차원: ... (더 분산)

같은 10개의 점이라도
→ 차원이 높아질수록 점들 사이 거리가 멀어짐
→ "가까운 이웃" 개념이 무의미해짐

수학적 직관

단위 초구(hypersphere)의 부피 비율

차원 d가 증가하면:
- 데이터가 주로 경계(boundary) 근처에 분포
- 중심 근처는 거의 비어있음

필요 데이터 수 ∝ exp(d)
→ 차원이 1 증가할 때마다 필요 데이터 기하급수적 증가

KNN에서의 문제

# 고차원에서 KNN이 망가지는 이유
# 모든 점들 사이의 거리가 비슷해짐

import numpy as np

# 차원별 거리 비교
for d in [2, 10, 100, 1000]:
    X = np.random.randn(100, d)
    distances = np.linalg.norm(X[0] - X[1:], axis=1)
    print(f"d={d}: max/min = {distances.max()/distances.min():.2f}")

# 고차원일수록 max/min → 1 (거리 구분 안 됨)

해결책

방법 설명
PCA 분산 큰 축으로 차원 축소
Feature Selection 중요한 피처만 선택
L1 Regularization 불필요 피처 가중치 0으로
t-SNE, UMAP 비선형 차원 축소 (시각화용)
데이터 추가 차원에 비례한 데이터 확보

면접 포인트

  • 고차원 → 데이터 희소 → 거리 개념 무의미
  • KNN, 클러스터링 등 거리 기반 알고리즘에 치명적
  • 해결: 차원 축소 (PCA, Feature Selection)

dimension reduction기법으로 보통 어떤 것들이 있나요?

한 줄 정의

고차원 데이터를 정보 손실 최소화하며 저차원으로 변환하는 기법

주요 기법 분류

차원 축소
├── 선형 (Linear)
│   ├── PCA (Principal Component Analysis)
│   ├── LDA (Linear Discriminant Analysis)
│   └── SVD (Singular Value Decomposition)
│
└── 비선형 (Non-linear)
    ├── t-SNE
    ├── UMAP
    ├── Autoencoder
    └── Kernel PCA

기법별 특징

기법 원리 용도
PCA 분산 최대화 축 찾기 전처리, 노이즈 제거
LDA 클래스 분리 최대화 분류 전처리
t-SNE 확률 분포 유지 2D/3D 시각화
UMAP 위상 구조 유지 시각화, 클러스터링
Autoencoder 인코더-디코더 학습 특징 추출, 생성

코드 예시

from sklearn.decomposition import PCA
from sklearn.manifold import TSNE
import umap

# PCA - 전처리용
pca = PCA(n_components=50)
X_pca = pca.fit_transform(X)
print(f"설명 분산: {pca.explained_variance_ratio_.sum():.2%}")

# t-SNE - 시각화용 (2D)
tsne = TSNE(n_components=2, perplexity=30)
X_tsne = tsne.fit_transform(X)

# UMAP - 시각화 + 학습용
reducer = umap.UMAP(n_components=2)
X_umap = reducer.fit_transform(X)

선택 기준

목적 추천 기법
ML 파이프라인 전처리 PCA
분류 성능 향상 LDA
고차원 데이터 시각화 t-SNE, UMAP
딥러닝 특징 추출 Autoencoder

면접 포인트

  • PCA: 분산 최대화, 선형, 학습 가능
  • t-SNE/UMAP: 비선형, 시각화용 (학습에 부적합)
  • 선형 vs 비선형 차이 설명 가능해야 함

PCA의 역할들(축소, 압축, 노이즈 제거)을 설명해주세요

한 줄 정의

분산 최대화 방향의 주성분을 찾아 차원 축소/압축/노이즈 제거를 수행

PCA 원리

원본 데이터 (2D)         PCA 변환
    ●   ●                    ●●●●●●●●●
  ●   ●   ●       →         (PC1 방향으로 투영)
    ●   ●

PC1: 분산이 가장 큰 방향
PC2: PC1에 직교하며 그 다음으로 분산 큰 방향

1. 차원 축소 (Dimensionality Reduction)

from sklearn.decomposition import PCA

# 100차원 → 10차원
pca = PCA(n_components=10)
X_reduced = pca.fit_transform(X)

# 또는 분산 비율로 지정 (95% 보존)
pca = PCA(n_components=0.95)
X_reduced = pca.fit_transform(X)
print(f"선택된 차원: {pca.n_components_}")

용도: 고차원 데이터 전처리, 학습 속도 향상, 과적합 방지

2. 데이터 압축 (Compression)

# 이미지 압축 예시 (28x28=784 → 50)
pca = PCA(n_components=50)
X_compressed = pca.fit_transform(X_images)

# 복원
X_reconstructed = pca.inverse_transform(X_compressed)

# 압축률: 784 → 50 (약 6% 용량)

용도: 저장 공간 절약, 전송 효율화

3. 노이즈 제거 (Denoising)

원리:
- 노이즈는 보통 분산이 작은 성분에 포함
- 주요 PC만 남기면 노이즈 제거됨

원본 + 노이즈 → PCA (상위 PC만) → 복원 → 깨끗한 데이터
# 노이즈 제거
pca = PCA(n_components=0.9)  # 분산 90%만 보존
X_denoised = pca.inverse_transform(pca.fit_transform(X_noisy))

면접 포인트

  • 축소: 고차원 → 저차원 (분산 보존)
  • 압축: inverse_transform으로 복원 가능
  • 노이즈 제거: 분산 작은 성분 = 노이즈

LSA, LDA, SVD 등의 약자와 관계를 설명할 수 있나요?

약자 정리

약자 풀네임 분야
SVD Singular Value Decomposition 선형대수 (행렬 분해)
PCA Principal Component Analysis 차원 축소
LSA Latent Semantic Analysis NLP (토픽 모델링)
LDA (1) Linear Discriminant Analysis 차원 축소 (지도학습)
LDA (2) Latent Dirichlet Allocation NLP (토픽 모델링)

관계도

SVD (기반 기술)
 │
 ├── PCA: 공분산 행렬에 SVD 적용
 │
 └── LSA: 문서-단어 행렬에 SVD 적용
            (= Truncated SVD)

LDA (Linear Discriminant Analysis)
 └── 클래스 간 분산 / 클래스 내 분산 최대화

LDA (Latent Dirichlet Allocation)
 └── 확률적 토픽 모델 (SVD와 무관)

SVD와 PCA 관계

# SVD: A = U Σ V^T
# PCA는 내부적으로 SVD 사용

from sklearn.decomposition import PCA, TruncatedSVD

# 동일한 결과 (중심화 차이 있음)
pca = PCA(n_components=10)
svd = TruncatedSVD(n_components=10)

LSA (Latent Semantic Analysis)

from sklearn.decomposition import TruncatedSVD
from sklearn.feature_extraction.text import TfidfVectorizer

# 문서-단어 행렬
tfidf = TfidfVectorizer()
X = tfidf.fit_transform(documents)

# LSA = TruncatedSVD (문서-단어 행렬에 적용)
lsa = TruncatedSVD(n_components=100)
X_topics = lsa.fit_transform(X)

LDA 두 가지 구분

Linear Discriminant Analysis Latent Dirichlet Allocation
분야 차원 축소 NLP 토픽 모델
학습 지도학습 (레이블 필요) 비지도학습
목적 분류 전처리 토픽 추출
# LDA (차원 축소)
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
lda = LinearDiscriminantAnalysis(n_components=2)
X_lda = lda.fit_transform(X, y)  # y 필요 (지도학습)

# LDA (토픽 모델)
from sklearn.decomposition import LatentDirichletAllocation
lda = LatentDirichletAllocation(n_components=10)
X_topics = lda.fit_transform(X)  # 비지도

면접 포인트

  • SVD가 기반 기술, PCA와 LSA가 이를 활용
  • LDA 두 개 구분: 차원축소 vs 토픽모델
  • LSA = TruncatedSVD (NLP 맥락)

L1, L2 정규화에 대해 설명해주세요

한 줄 정의

손실 함수에 가중치 패널티를 추가하여 과적합을 방지하는 기법

수식 비교

원본 Loss: L(θ)

L1 (Lasso): L(θ) + λ Σ|θᵢ|
L2 (Ridge): L(θ) + λ Σθᵢ²

λ: 정규화 강도 (하이퍼파라미터)

핵심 차이

L1 (Lasso) L2 (Ridge)
패널티 절대값 합 제곱 합
효과 일부 가중치 → 0 가중치 작아짐
결과 Sparse (희소) Dense (균등 축소)
용도 Feature Selection 과적합 방지

기하학적 이해

L1: 마름모 제약                L2: 원형 제약
      ◇                              ○
   ↗     ↘                         ↗   ↘
  ↑   ●   ↓    최적점이           ↑  ●  ↓   최적점이
   ↖     ↙    꼭짓점(축)에         ↖   ↙    원 위에
      ◇       → 가중치=0              ○      → 가중치 작음

● = 원래 최적점

코드 예시

from sklearn.linear_model import Lasso, Ridge, ElasticNet

# L1 (Lasso) - 피처 선택
lasso = Lasso(alpha=0.1)
lasso.fit(X_train, y_train)
print(f"0인 가중치: {(lasso.coef_ == 0).sum()}")

# L2 (Ridge) - 과적합 방지
ridge = Ridge(alpha=1.0)
ridge.fit(X_train, y_train)

# Elastic Net - L1 + L2 결합
elastic = ElasticNet(alpha=0.1, l1_ratio=0.5)  # 0.5 = L1:L2 반반

언제 무엇을 쓸까?

상황 선택
피처가 많고 일부만 중요 L1 (Lasso)
다중공선성 있음 L2 (Ridge)
피처 선택 + 안정성 Elastic Net
딥러닝 과적합 L2 (Weight Decay)

면접 포인트

  • L1: Sparse → Feature Selection
  • L2: 가중치 작게 → 과적합 방지
  • 기하학적 해석: 제약 조건 형태 차이

Markov Chain을 고등학생에게 설명하려면?

한 줄 정의

현재 상태만으로 다음 상태가 결정되는 확률 과정

고등학생 설명

날씨 예측 게임!

오늘 맑음 → 내일 날씨는?
- 맑음: 70%
- 비: 30%

핵심: 어제 날씨는 상관없음!
     "오늘"만 보고 "내일" 예측

이것이 마르코프 성질:
"과거는 잊고, 현재만 봐!"

시각적 예시

         0.7
    ┌─────────┐
    │   ↓     │
    ▼         │
  [맑음] ────────→ [비]
    ↑    0.3      │
    │             │
    └─────────────┘
          0.4        0.6 (비→비)

전이 확률 행렬 P:
         맑음   비
    맑음 [0.7  0.3]
    비   [0.4  0.6]

왜 유용한가?

1. 단순함: 전체 이력 대신 현재만 기억
2. 계산 가능: 행렬 곱으로 n일 후 예측

P² = 2일 후 확률
P^n = n일 후 확률

실생활 예시

분야 예시
검색엔진 PageRank (웹페이지 이동)
자연어 다음 단어 예측
금융 신용등급 변화
게임 상태 기반 AI
import numpy as np

# 전이 행렬
P = np.array([[0.7, 0.3],   # 맑음 → 맑음/비
              [0.4, 0.6]])   # 비 → 맑음/비

# 3일 후 확률
P_3days = np.linalg.matrix_power(P, 3)
print(P_3days)

면접 포인트

  • 마르코프 성질: 현재만으로 미래 결정
  • 전이 행렬: 상태 간 이동 확률
  • 응용: PageRank, 언어 모델

텍스트 더미에서 주제를 추출하는 방식은?

한 줄 정의

토픽 모델링: 문서 집합에서 숨겨진 주제(토픽)를 자동으로 발견하는 기법

주요 방법

방법 원리 특징
LDA 확률적 생성 모델 가장 대표적, 해석 용이
LSA SVD 기반 빠름, 수학적 단순
NMF 비음수 행렬 분해 희소 표현, 해석 용이
BERTopic BERT + 클러스터링 최신, 고품질

LDA (Latent Dirichlet Allocation)

문서 = 토픽들의 혼합
토픽 = 단어들의 확률 분포

문서1: 토픽A(60%) + 토픽B(40%)
토픽A: "경제", "주식", "금리" 높은 확률
토픽B: "정치", "선거", "투표" 높은 확률
from sklearn.decomposition import LatentDirichletAllocation
from sklearn.feature_extraction.text import CountVectorizer

# 문서-단어 행렬
vectorizer = CountVectorizer(max_features=1000, stop_words='english')
X = vectorizer.fit_transform(documents)

# LDA
lda = LatentDirichletAllocation(n_components=10, random_state=42)
lda.fit(X)

# 각 토픽의 상위 단어 출력
feature_names = vectorizer.get_feature_names_out()
for topic_idx, topic in enumerate(lda.components_):
    top_words = [feature_names[i] for i in topic.argsort()[:-10:-1]]
    print(f"토픽 {topic_idx}: {', '.join(top_words)}")

BERTopic (최신)

from bertopic import BERTopic

# 간단한 사용법
topic_model = BERTopic(language="korean")
topics, probs = topic_model.fit_transform(documents)

# 토픽 확인
topic_model.get_topic_info()

선택 가이드

상황 추천
빠른 프로토타입 LSA, NMF
해석 가능성 중요 LDA
고품질 필요 BERTopic
한국어 BERTopic (다국어 지원)

면접 포인트

  • LDA: 문서=토픽 혼합, 토픽=단어 분포
  • LSA vs LDA: 행렬분해 vs 확률모델
  • 최신 트렌드: BERTopic (BERT 임베딩 활용)

SVM은 왜 반대로 차원을 확장시키는 방식으로 동작할까요?

한 줄 정의

저차원에서 선형 분리 불가능한 데이터를 고차원에서 선형 분리 가능하게 만들기 위해

핵심 아이디어

2D에서 분리 불가능:           3D로 올리면 분리 가능:
                                    ↑ z
    ○ ○ ○                          │    ○ ○ ○
  ○ ● ● ● ○      →                │  ● ● ●   (평면으로 분리!)
    ○ ○ ○                          │    ○ ○ ○
                                    └────────→ x,y

φ(x) = (x₁, x₂, x₁²+x₂²)  ← 차원 확장 함수

Kernel Trick

문제: 고차원 계산 비용이 너무 큼

해결: Kernel Trick!
- 고차원에서 내적 = 저차원에서 커널 함수 계산
- φ(x)·φ(y) = K(x, y)

실제로 고차원으로 변환하지 않고
고차원에서의 효과를 얻음!

주요 커널

커널 수식 특징
Linear x·y 선형 분리 가능할 때
Polynomial (x·y + c)^d 다항식 경계
RBF (Gaussian) exp(-γ|x-y|²) 무한 차원, 가장 많이 사용
from sklearn.svm import SVC

# RBF 커널 (기본값) - 무한 차원으로 매핑
svm_rbf = SVC(kernel='rbf', C=1.0, gamma='scale')

# 선형 커널 - 고차원 매핑 없음
svm_linear = SVC(kernel='linear', C=1.0)

# 다항식 커널
svm_poly = SVC(kernel='poly', degree=3)

왜 "반대로"인가?

일반적 접근: 차원의 저주 → 차원 축소
SVM 접근:    선형 분리 불가 → 차원 확장

But! Kernel Trick으로 실제 계산은 저차원
→ 고차원의 이점 + 저차원의 효율성

면접 포인트

  • 목적: 선형 분리 불가 → 고차원에서 선형 분리
  • Kernel Trick: 실제 변환 없이 고차원 효과
  • RBF 커널: 무한 차원, 범용적

SVM은 왜 좋을까요?

한 줄 정의

마진 최대화 + Kernel Trick으로 이론적 기반이 탄탄하고 일반화 성능이 우수

SVM의 장점

장점 설명
마진 최대화 결정 경계와 데이터 간 거리 최대 → 일반화 ↑
Kernel Trick 비선형 문제 해결 가능
고차원에 강함 피처 수 > 샘플 수여도 잘 동작
이론적 기반 통계적 학습 이론 (VC dimension)
과적합 저항 정규화 파라미터 C로 조절

마진 최대화

      ○         │         ●
   ○     ○      │      ●     ●
      ○     ← margin →     ●
   ○     ○      │      ●     ●
      ○         │         ●
              결정경계

SVM: margin을 최대화하는 결정경계 찾기
→ 새 데이터에 대한 오분류 확률 ↓

언제 SVM을 쓸까?

적합 부적합
중소규모 데이터 대규모 데이터 (느림)
고차원 데이터 노이즈 많은 데이터
이진 분류 확률 추정 필요 시
텍스트 분류 실시간 추론 필요 시

한계점

1. 대용량 데이터 → O(n²~n³) 학습 시간
2. 확률 출력 어려움 (Platt scaling 필요)
3. 하이퍼파라미터 튜닝 (C, gamma) 민감
4. 해석 어려움 (블랙박스)

면접 포인트

  • 마진 최대화 → 일반화 성능
  • Kernel Trick → 비선형 분리
  • 대용량에는 부적합 (딥러닝, XGBoost 대체)

나이브 베이즈(naive bayes)의 장점을 옹호해보세요

한 줄 정의

피처 간 조건부 독립 가정으로 계산을 단순화한 확률적 분류기

"Naive"의 의미

Naive (순진한) 가정:
P(x₁, x₂, ... | y) = P(x₁|y) × P(x₂|y) × ...

"피처들이 서로 독립이다"

현실에서는 거의 틀린 가정이지만...
놀랍게도 실전에서 잘 동작함!

장점 (옹호)

장점 설명
빠름 학습 O(nd), 추론 O(d)
적은 데이터 OK 각 피처별로 따로 추정
확률 출력 P(y|x) 직접 제공
고차원 OK 텍스트 분류에 특히 강점
해석 가능 각 피처의 기여도 확인 가능
온라인 학습 새 데이터 추가 쉬움

왜 잘 동작하나?

1. 분류에서는 P(y|x) 순위만 중요
   → 확률의 절대값이 틀려도 순위가 맞으면 OK

2. 추정 오차가 서로 상쇄
   → 과대추정 + 과소추정 ≈ 평균

3. 고차원에서 복잡한 모델보다 안정적
   → Bias ↑ but Variance ↓

대표 사용 사례

from sklearn.naive_bayes import MultinomialNB

# 스팸 필터 (텍스트 분류의 클래식)
spam_classifier = MultinomialNB()
spam_classifier.fit(X_tfidf, y_labels)

# 감성 분석, 문서 분류 등
사용 사례 이유
스팸 필터 빠름, 새 스팸 패턴 빠른 적응
문서 분류 고차원 텍스트에 강함
실시간 분류 추론 속도 빠름
베이스라인 빠르게 성능 기준점 확보

면접 포인트

  • Naive 가정 틀려도 실전에서 잘 동작
  • 빠름 + 적은 데이터 + 확률 출력
  • 텍스트 분류의 강력한 베이스라인

Association Rule의 Support, Confidence, Lift에 대해 설명해주세요

한 줄 정의

장바구니 분석에서 아이템 간 연관성을 측정하는 세 가지 지표

예시 상황

규칙: {맥주} → {기저귀}
"맥주를 사면 기저귀도 산다"

전체 거래: 1000건
맥주 구매: 200건
기저귀 구매: 300건
맥주+기저귀 동시 구매: 100건

세 가지 지표

지표 수식 의미 예시 값
Support P(A∩B) 동시 발생 빈도 100/1000 = 10%
Confidence P(B|A) A 샀을 때 B 살 확률 100/200 = 50%
Lift P(B|A)/P(B) 연관성 강도 0.5/0.3 = 1.67

각 지표 해석

Support = 10%
→ 전체 거래 중 10%가 맥주+기저귀 동시 구매
→ 너무 낮으면 희귀한 규칙 (신뢰도 ↓)

Confidence = 50%
→ 맥주 산 사람 중 50%가 기저귀도 구매
→ 마케팅 타겟팅에 유용

Lift = 1.67
→ 맥주 구매가 기저귀 구매를 1.67배 증가시킴
→ 1보다 크면 양의 연관, 1이면 무관, 1 미만이면 음의 연관

Lift 해석

Lift > 1: 양의 연관 (A→B 촉진)
Lift = 1: 독립 (연관 없음)
Lift < 1: 음의 연관 (A→B 억제)

코드 예시

from mlxtend.frequent_patterns import apriori, association_rules

# Apriori로 빈발 아이템셋 찾기
frequent_items = apriori(df, min_support=0.05, use_colnames=True)

# 연관 규칙 생성
rules = association_rules(frequent_items, metric="lift", min_threshold=1.0)

# Support, Confidence, Lift 확인
print(rules[['antecedents', 'consequents', 'support', 'confidence', 'lift']])

면접 포인트

  • Support: 얼마나 자주 (빈도)
  • Confidence: 얼마나 확실히 (조건부 확률)
  • Lift: 얼마나 의미있게 (독립 대비 증가율)

K-means의 대표적 의미론적 단점은 무엇인가요?

한 줄 정의

구형(spherical) 클러스터 가정과 K 사전 지정 등의 제약

주요 단점

단점 설명
K 사전 지정 클러스터 수를 미리 알아야 함
구형 클러스터 가정 비구형 클러스터 못 찾음
크기 균등 가정 크기 다른 클러스터에 약함
초기값 민감 초기 중심점에 따라 결과 달라짐
이상치 민감 평균 기반이라 이상치 영향 큼

구형 클러스터 문제

K-means가 잘 되는 경우:        K-means가 실패하는 경우:

    ●●●    ○○○                   ●●●●●●●●●●●●●
    ●●●    ○○○                   ○○○○○○○○○○○○○
    ●●●    ○○○                   (선형 클러스터)

    (구형 클러스터)              ●●●
                                ●   ●
                               ○○○○○ ●
                                ●   ●
                                 ●●●
                               (동심원 클러스터)

대안

문제 대안 알고리즘
K 모름 DBSCAN, Mean Shift
비구형 DBSCAN, Spectral Clustering
크기 다름 DBSCAN, GMM
이상치 K-medoids, DBSCAN
from sklearn.cluster import KMeans, DBSCAN

# K-means: K 필요
kmeans = KMeans(n_clusters=3)

# DBSCAN: K 불필요, 비구형 OK
dbscan = DBSCAN(eps=0.5, min_samples=5)

"의미론적" 단점

K-means는 "의미 있는" 그룹을 찾는 게 아니라
"거리가 가까운" 그룹을 찾음

예: 고객 세그먼트
- K-means: 숫자적으로 가까운 고객 그룹
- 원하는 것: 비즈니스 의미 있는 고객 그룹
→ 해석이 어렵고 비즈니스 의미 없을 수 있음

면접 포인트

  • K 사전 지정 필요
  • 구형 클러스터 가정 (비구형 실패)
  • 의미론적: 거리 기반 ≠ 비즈니스 의미

스팸 필터에 로지스틱 리그레션을 많이 사용하는 이유는?

한 줄 정의

확률 출력, 해석 가능성, 빠른 학습이 스팸 필터 요구사항과 일치

스팸 필터 요구사항 vs 로지스틱 회귀

요구사항 로지스틱 회귀가 적합한 이유
확률 필요 0~1 확률 출력 (임계값 조절 가능)
빠른 추론 선형 연산만 → 실시간 처리
해석 필요 어떤 단어가 스팸 판단에 기여했는지
업데이트 새 스팸 패턴에 빠른 재학습
고차원 TF-IDF 희소 벡터 처리 가능

확률 기반 임계값 조절

from sklearn.linear_model import LogisticRegression

model = LogisticRegression()
model.fit(X_train, y_train)

# 확률 출력
proba = model.predict_proba(X_test)[:, 1]

# 임계값 조절로 FP/FN 트레이드오프 제어
# 정상 메일 스팸 처리 방지 (높은 임계값)
y_pred = (proba > 0.9).astype(int)

# 스팸 놓침 방지 (낮은 임계값)
y_pred = (proba > 0.5).astype(int)

해석 가능성

# 스팸/햄 판단 근거 확인
feature_names = vectorizer.get_feature_names_out()
coef = model.coef_[0]

# 스팸 키워드 (가중치 높음)
spam_keywords = [(feature_names[i], coef[i])
                 for i in coef.argsort()[-10:]]
# ['무료', '당첨', '클릭', '지금바로', ...]

# 정상 키워드 (가중치 낮음/음수)
ham_keywords = [(feature_names[i], coef[i])
                for i in coef.argsort()[:10]]

다른 알고리즘과 비교

알고리즘 확률 해석 속도 스팸 필터 적합성
Logistic Regression ✅ ✅ ✅ ⭐⭐⭐
Naive Bayes ✅ ✅ ✅ ⭐⭐⭐
SVM △ ❌ ○ ⭐⭐
Random Forest ✅ △ △ ⭐⭐
딥러닝 ✅ ❌ ❌ ⭐

면접 포인트

  • 확률 출력 → 임계값 조절 (FP/FN 트레이드오프)
  • 해석 가능 → 어떤 단어가 스팸 판단에 기여
  • 빠름 → 실시간 이메일 처리

OLS(ordinary least square) regression의 공식은 무엇인가요?

한 줄 정의

잔차 제곱합(RSS)을 최소화하는 회귀 계수를 찾는 방법

수식

목표: RSS = Σ(yᵢ - ŷᵢ)² = Σ(yᵢ - Xᵢβ)² 최소화

해 (Closed-form solution):
β = (X^T X)^(-1) X^T y

여기서:
- X: 설계 행렬 (n × p)
- y: 타겟 벡터 (n × 1)
- β: 회귀 계수 (p × 1)

유도 과정

RSS = (y - Xβ)^T (y - Xβ)

∂RSS/∂β = -2X^T(y - Xβ) = 0

X^T y = X^T Xβ

β = (X^T X)^(-1) X^T y

코드 구현

import numpy as np

# numpy로 OLS 직접 구현
def ols_closed_form(X, y):
    """OLS closed-form solution"""
    # β = (X^T X)^(-1) X^T y
    return np.linalg.inv(X.T @ X) @ X.T @ y

# sklearn 사용
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(X, y)
# model.coef_ 가 β (계수)

OLS 가정

가정 위반 시 문제
선형성 비선형 관계 못 잡음
독립성 계수 추정 편향
등분산성 신뢰구간 부정확
정규성 검정 통계량 신뢰 ↓
다중공선성 없음 (X^TX)^-1 불안정

다중공선성 문제

X^T X가 특이(singular)하거나 조건수(condition number)가 크면:
→ (X^T X)^(-1) 계산 불안정
→ 계수 추정치 분산 폭발

해결: Ridge, Lasso 정규화

면접 포인트

  • 공식: β = (X^T X)^(-1) X^T y
  • RSS 최소화로 유도
  • 다중공선성 → (X^TX)^-1 불안정 → 정규화 필요

Newton's Method와 Gradient Descent 방법에 대해 알고 있나요?

한 줄 정의

GD: 1차 미분(기울기)만 사용 | Newton: 2차 미분(곡률)까지 사용

업데이트 공식

Gradient Descent:
θ_new = θ - α × ∇f(θ)
        └─ 학습률   └─ 1차 미분

Newton's Method:
θ_new = θ - H^(-1) × ∇f(θ)
            └─ 헤시안 역행렬 (2차 미분)

비교

특성 Gradient Descent Newton's Method
수렴 속도 느림 (1차 수렴) 빠름 (2차 수렴)
계산 비용 O(n) O(n³) 헤시안 계산
메모리 O(n) O(n²) 헤시안 저장
스케일링 대규모 OK 소규모만 가능
학습률 필요 불필요 (자동 조절)

직관적 이해

GD: 기울기 방향으로 내려감
    "눈 감고 경사를 느끼며 걷기"
    - 경사만 알고, 얼마나 걸을지는 학습률로 결정

Newton: 곡률까지 고려
    "지형 곡률을 보고 최적 스텝 계산"
    - 볼록하면 크게, 가파르면 작게 자동 조절

           GD                    Newton
         ↘                        ↘
      ↘                              ↘
   ↘                                    ●
↘  (많은 스텝)                    (적은 스텝)

코드 비교

# Gradient Descent
def gradient_descent(f, grad_f, x0, lr=0.01, n_iter=100):
    x = x0
    for _ in range(n_iter):
        x = x - lr * grad_f(x)
    return x

# Newton's Method
def newton_method(f, grad_f, hess_f, x0, n_iter=10):
    x = x0
    for _ in range(n_iter):
        x = x - np.linalg.inv(hess_f(x)) @ grad_f(x)
    return x

실무에서의 선택

딥러닝: GD 계열 (SGD, Adam)
        → 수백만 파라미터, 헤시안 불가능

소규모 최적화: Newton 또는 Quasi-Newton (BFGS)
              → scikit-learn의 solver='lbfgs'

Newton의 근사: L-BFGS
             → 헤시안 근사로 메모리 절약

면접 포인트

  • GD: 1차 미분, 느리지만 스케일 가능
  • Newton: 2차 미분, 빠르지만 계산 비용 큼
  • 딥러닝 = GD / 소규모 = Newton (또는 L-BFGS)

XGBoost을 아시나요?

한 줄 정의

Gradient Boosting의 최적화된 구현으로, 정규화와 병렬처리를 추가한 앙상블 기법

XGBoost의 특징

특징 설명
정규화 L1, L2 정규화로 과적합 방지
병렬처리 피처 단위 병렬 → 빠른 학습
결측치 처리 자동 결측치 처리
가지치기 max_depth로 트리 크기 제한
Early Stopping 검증 성능 기반 조기 종료

Gradient Boosting 원리

1. 초기 모델 f₀(x) = 평균값
2. 잔차(residual) 계산: r₁ = y - f₀(x)
3. 잔차를 예측하는 트리 h₁(x) 학습
4. 모델 업데이트: f₁(x) = f₀(x) + η·h₁(x)
5. 반복

최종: F(x) = f₀ + η·h₁ + η·h₂ + ... + η·hₘ

XGBoost 목적 함수

Obj = Σ L(yᵢ, ŷᵢ) + Σ Ω(fₖ)
      └─ 손실        └─ 정규화

Ω(f) = γT + ½λΣw²
       └─ 리프 수  └─ 리프 가중치 L2

코드 예시

import xgboost as xgb
from sklearn.model_selection import train_test_split

# 데이터 준비
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2)
dtrain = xgb.DMatrix(X_train, label=y_train)
dval = xgb.DMatrix(X_val, label=y_val)

# 파라미터
params = {
    'objective': 'binary:logistic',
    'max_depth': 6,
    'learning_rate': 0.1,
    'subsample': 0.8,
    'colsample_bytree': 0.8,
    'reg_lambda': 1.0,  # L2
    'reg_alpha': 0.0,   # L1
}

# 학습 (Early Stopping)
model = xgb.train(
    params, dtrain,
    num_boost_round=1000,
    evals=[(dval, 'val')],
    early_stopping_rounds=50
)

XGBoost vs LightGBM vs CatBoost

XGBoost LightGBM CatBoost
속도 빠름 더 빠름 중간
결측치 자동 자동 자동
범주형 수동 인코딩 지원 네이티브 지원
성장 방식 level-wise leaf-wise level-wise

면접 포인트

  • Gradient Boosting + 정규화 + 병렬처리
  • 목적함수: 손실 + 정규화 (γT + λw²)
  • 테이블 데이터 경진대회의 표준 모델

앙상블 방법엔 어떤 것들이 있나요?

한 줄 정의

여러 모델의 예측을 결합하여 단일 모델보다 좋은 성능을 얻는 기법

앙상블 유형

앙상블
├── Bagging (Bootstrap Aggregating)
│   └── Random Forest
│
├── Boosting
│   ├── AdaBoost
│   ├── Gradient Boosting
│   ├── XGBoost
│   └── LightGBM
│
├── Stacking
│   └── 메타 모델로 결합
│
└── Voting
    ├── Hard Voting (다수결)
    └── Soft Voting (확률 평균)

Bagging vs Boosting

Bagging Boosting
학습 방식 병렬 (독립) 순차 (의존)
샘플링 Bootstrap (복원추출) 가중치 조절
목표 분산(Variance) 감소 편향(Bias) 감소
과적합 강건함 주의 필요
대표 Random Forest XGBoost, LightGBM
Bagging:
데이터 → [샘플1] → 모델1 ↘
      → [샘플2] → 모델2 → 평균/투표 → 결과
      → [샘플3] → 모델3 ↗

Boosting:
데이터 → 모델1 → 오차 → 모델2 → 오차 → 모델3 → 합산
                ↑ 틀린 것에 집중

Stacking

Level 0 (Base Models):
데이터 → [RF, XGB, SVM, NN] → 예측들

Level 1 (Meta Model):
예측들 → [Logistic Regression] → 최종 예측

핵심: Base 모델의 예측을 피처로 사용
from sklearn.ensemble import StackingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from xgboost import XGBClassifier

stacking = StackingClassifier(
    estimators=[
        ('rf', RandomForestClassifier()),
        ('xgb', XGBClassifier())
    ],
    final_estimator=LogisticRegression()
)

Voting

from sklearn.ensemble import VotingClassifier

# Hard Voting: 다수결
hard_vote = VotingClassifier(
    estimators=[('rf', rf), ('svm', svm), ('xgb', xgb)],
    voting='hard'
)

# Soft Voting: 확률 평균 (보통 더 좋음)
soft_vote = VotingClassifier(
    estimators=[('rf', rf), ('svm', svm), ('xgb', xgb)],
    voting='soft'
)

면접 포인트

  • Bagging: 병렬, 분산↓ (Random Forest)
  • Boosting: 순차, 편향↓ (XGBoost)
  • Stacking: 메타 모델로 결합
  • 다양성(diversity)이 앙상블 성공의 핵심

50개의 작은 의사결정 나무는 큰 의사결정 나무보다 괜찮을까요?

한 줄 답변

대부분의 경우 YES! 작은 트리 앙상블(Random Forest)이 큰 단일 트리보다 일반화 성능이 좋음

왜 작은 트리들이 더 나은가?

큰 단일 트리:
- 높은 Variance (과적합)
- 훈련 데이터에 딱 맞춤
- 새 데이터에 취약

작은 트리 앙상블:
- 개별 트리는 약한 학습기
- 평균/투표로 Variance 감소
- 일반화 성능 ↑

Bias-Variance 관점

큰 단일 트리 작은 트리 앙상블
Bias 낮음 약간 높음
Variance 높음 낮음 (평균 효과)
과적합 심함 적음
일반화 나쁨 좋음

수학적 근거

n개 독립 모델의 평균:

Var(평균) = Var(개별) / n

50개 트리의 분산 = 1개 트리의 분산 / 50
→ 분산이 대폭 감소!

(단, 트리 간 상관관계 있으면 효과 감소)

Random Forest의 추가 트릭

from sklearn.ensemble import RandomForestClassifier

rf = RandomForestClassifier(
    n_estimators=50,        # 50개의 작은 트리
    max_depth=10,           # 깊이 제한 (작은 트리)
    max_features='sqrt',    # 피처 서브샘플링 → 트리 다양성
    bootstrap=True          # 데이터 서브샘플링
)
작은 트리 + 피처 서브샘플링
→ 트리 간 상관관계 ↓
→ 앙상블 효과 ↑

예외 상황

작은 트리 앙상블이 안 좋을 때:
1. 해석 가능성이 중요할 때 (단일 트리가 해석 쉬움)
2. 추론 속도가 매우 중요할 때 (50배 느림)
3. 메모리 제약이 심할 때

면접 포인트

  • Variance 감소: 평균으로 분산 줄임
  • 다양성: 부트스트랩 + 피처 서브샘플링
  • 단, 해석 가능성은 단일 트리가 유리

ROC 커브에 대해 설명해주실 수 있으신가요?

한 줄 정의

임계값 변화에 따른 TPR(민감도)와 FPR의 관계를 나타낸 곡선

핵심 개념

ROC: Receiver Operating Characteristic

X축: FPR = FP / (FP + TN)  (1 - Specificity)
Y축: TPR = TP / (TP + FN)  (Recall, Sensitivity)

각 점 = 특정 임계값(threshold)에서의 (FPR, TPR)

ROC 커브 해석

         TPR
          ↑
        1 │    ●───────● 완벽한 모델 (AUC=1)
          │   ╱
          │  ╱  좋은 모델
          │ ╱
          │╱     ╱
          ●────● 랜덤 (AUC=0.5)
          └──────────→ FPR
          0           1

왼쪽 위로 볼록할수록 좋은 모델

AUC (Area Under Curve)

AUC = ROC 곡선 아래 면적

AUC = 1.0: 완벽한 분류
AUC = 0.9: 매우 좋음
AUC = 0.8: 좋음
AUC = 0.7: 보통
AUC = 0.5: 랜덤 (의미 없음)
AUC < 0.5: 예측 뒤집으면 나음

코드 예시

from sklearn.metrics import roc_curve, roc_auc_score
import matplotlib.pyplot as plt

# ROC 커브 데이터
fpr, tpr, thresholds = roc_curve(y_true, y_prob)

# AUC 계산
auc = roc_auc_score(y_true, y_prob)

# 시각화
plt.plot(fpr, tpr, label=f'ROC (AUC={auc:.3f})')
plt.plot([0, 1], [0, 1], 'k--', label='Random')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.legend()
plt.show()

ROC vs PR Curve

ROC Curve PR Curve
축 FPR vs TPR Recall vs Precision
불균형 데이터 낙관적 (TN 많으면 FPR↓) 민감하게 반영
추천 상황 균형 데이터 불균형 데이터
불균형 데이터에서:
- ROC AUC가 높아도 PR AUC가 낮을 수 있음
- 양성 클래스가 중요하면 PR Curve 사용

최적 임계값 찾기

# Youden's J statistic
optimal_idx = np.argmax(tpr - fpr)
optimal_threshold = thresholds[optimal_idx]

# 또는 비용 기반으로 선택
# FP 비용과 FN 비용에 따라 다르게

면접 포인트

  • 임계값 무관 모델 비교 가능
  • AUC: 0.5 = 랜덤, 1.0 = 완벽
  • 불균형 데이터에서는 PR Curve가 더 적합

서버 100대에서 인공신경망보다 Random Forest를 써야하는 이유는?

한 줄 답변

병렬화 용이성과 통신 오버헤드 최소화 때문

Random Forest의 분산 처리 장점

Random Forest 분산 학습:

서버1: 트리 1~10 학습 (독립)
서버2: 트리 11~20 학습 (독립)
...
서버100: 트리 991~1000 학습 (독립)

→ 각 서버가 독립적으로 학습
→ 서버 간 통신 불필요!
→ 마지막에 모델만 모아서 앙상블

Neural Network의 분산 처리 어려움

신경망 분산 학습 (Data Parallel):

서버1: 배치1 → gradient1 ↘
서버2: 배치2 → gradient2 → 평균 → 파라미터 업데이트
...                       ↗     (모든 서버 동기화)
서버100: gradient100

문제:
- 매 스텝마다 gradient 동기화 필요
- 통신 병목 (수백MB~GB 전송)
- 하나 느리면 전체가 기다림

비교

Random Forest Neural Network
병렬화 Embarrassingly Parallel 동기화 필요
통신 거의 없음 매우 많음
확장성 선형 확장 통신 병목
장애 허용 일부 실패해도 OK 동기화 깨짐
구현 난이도 쉬움 복잡함

실무 상황

서버 100대 상황:
- 네트워크 지연, 불안정성 존재
- 일부 서버 장애 가능
- 단순한 아키텍처 선호

Random Forest가 적합:
✅ 각 서버 독립 작업
✅ 장애 허용
✅ 통신 최소
✅ 쉬운 구현

Neural Network 문제:
❌ 동기화 필요
❌ 통신 병목
❌ All-reduce 구현 복잡
❌ 장애 시 전체 영향

분산 NN이 필요하면?

# Horovod, PyTorch DDP 등 전문 프레임워크 필요
import horovod.torch as hvd
hvd.init()

# 또는 Parameter Server 아키텍처
# 또는 Ray, Spark ML 파이프라인

면접 포인트

  • Embarrassingly Parallel: RF 트리는 완전 독립
  • 통신 오버헤드: NN은 gradient 동기화 필요
  • 단순 분산 환경에서는 RF가 훨씬 효율적

머신러닝적 접근방법과 통계적 접근방법의 차이는?

한 줄 정의

통계: 데이터 이해와 추론 | ML: 예측 성능 최적화

핵심 차이

관점 통계적 접근 머신러닝 접근
목표 이해, 추론, 인과관계 예측 성능
모델 가정 기반 (정규성 등) 데이터 기반
해석 계수 의미 중요 블랙박스 허용
평가 p-value, 신뢰구간 정확도, AUC
데이터 적은 데이터도 가능 많은 데이터 필요

예시: 집값 예측

통계적 접근:
- "방 개수가 집값에 미치는 영향은?"
- 선형회귀, 계수 해석, p-value 확인
- "방이 1개 늘면 집값 $10,000 증가 (p<0.05)"

머신러닝 접근:
- "집값을 가장 정확히 예측하는 모델은?"
- XGBoost, 신경망 등 시도
- "RMSE가 가장 낮은 모델 선택"
- 왜 그 예측인지는 덜 중요

철학적 차이

통계:
"데이터가 어떤 확률 분포에서 생성되었는가?"
→ 모집단 추정, 가설 검정

머신러닝:
"어떤 함수가 입력을 출력으로 가장 잘 매핑하는가?"
→ 예측 오차 최소화, 일반화

현실에서는 융합

실무에서:
1. 탐색적 분석 (통계) → 데이터 이해
2. 피처 엔지니어링 (통계 + ML)
3. 모델링 (ML) → 예측
4. 해석 (통계 + XAI) → 설명

예: 금융 대출 모델
- ML로 신용 예측
- 통계적 해석으로 규제 준수 (왜 거절했는지 설명)

언제 무엇을?

상황 적합한 접근
인과관계 규명 통계
가설 검정 통계
예측 성능 중요 ML
데이터 적음 통계
해석 불필요 ML
규제 환경 통계 + 해석 가능 ML

면접 포인트

  • 통계: 이해, 추론, 인과관계 (p-value)
  • ML: 예측 성능 (RMSE, AUC)
  • 실무는 둘의 융합이 필요

feature vector란 무엇일까요?

한 줄 정의

샘플의 특성(feature)들을 숫자 벡터로 표현한 것

직관적 이해

사람 데이터:
- 이름: "철수" (문자열 - 모델이 못 읽음)
- 키: 175 (숫자)
- 몸무게: 70 (숫자)
- 성별: "남" (범주형)

Feature Vector로 변환:
[175, 70, 1]  ← 모델이 입력으로 받을 수 있는 형태
 키  몸무게 성별(남=1)

왜 필요한가?

ML 모델 = 수학 함수
→ 숫자만 처리 가능!

모든 데이터를 숫자 벡터(feature vector)로 변환해야 함

이미지: 픽셀값 → [0.2, 0.5, 0.1, ...]
텍스트: 단어 → [TF-IDF 벡터] 또는 [임베딩]
범주형: One-hot → [0, 1, 0, 0]

Feature Vector 생성 예시

import numpy as np
from sklearn.preprocessing import StandardScaler, OneHotEncoder

# 숫자형 특성
numerical = np.array([[175, 70], [160, 55]])

# 범주형 특성
categorical = np.array([['남'], ['여']])
encoder = OneHotEncoder(sparse=False)
cat_encoded = encoder.fit_transform(categorical)

# 합쳐서 Feature Vector
feature_vectors = np.hstack([numerical, cat_encoded])
# [[175, 70, 1, 0],   ← 철수의 feature vector
#  [160, 55, 0, 1]]   ← 영희의 feature vector

다양한 데이터 타입

데이터 Feature Vector 변환 방법
숫자형 그대로 (정규화 권장)
범주형 One-hot, Label Encoding
텍스트 TF-IDF, Word2Vec, BERT
이미지 픽셀값, CNN 특징
시계열 통계량, 시퀀스 인코딩

Feature Vector vs Embedding

Feature Vector: 수동 설계된 특성
- 도메인 지식 필요
- 해석 가능

Embedding: 학습된 특성
- Word2Vec, BERT 등
- 자동 학습
- 더 풍부한 의미

둘 다 "숫자 벡터"라는 점은 동일

면접 포인트

  • 모든 데이터를 숫자 벡터로 표현
  • 각 요소가 하나의 feature
  • 피처 엔지니어링 = 좋은 feature vector 만들기

인공신경망의 일반적인 문제점은 무엇일까요?

한 줄 정의

블랙박스, 데이터 요구량, 계산 비용, 과적합 등의 한계

주요 문제점

문제 설명
블랙박스 왜 그런 예측인지 설명 어려움
데이터 요구 많은 레이블 데이터 필요
계산 비용 GPU 필수, 학습 시간/비용 큼
하이퍼파라미터 튜닝이 많고 어려움
과적합 복잡한 모델, 과적합 쉬움
불안정성 초기화, 순서에 따라 결과 달라짐

블랙박스 문제

입력 → [???] → 출력

"왜 이 환자가 고위험인가요?"
→ 설명 못함

규제 환경 (금융, 의료):
- 의사결정 근거 제시 필요
- 블랙박스 모델 사용 제한

해결 시도: XAI (SHAP, LIME, Attention)

데이터 요구량

일반적으로:
- 파라미터 수의 10~100배 데이터 필요
- GPT-3: 1750억 파라미터 → 수천억 토큰 학습

적은 데이터에서:
- 과적합
- 노이즈 학습

해결: Transfer Learning, Few-shot Learning

계산 비용

학습:
- GPT-3: ~$5M 학습 비용
- 일반 모델도 GPU 수일~수주

추론:
- 실시간 서비스 시 지연
- 모바일/엣지 배포 어려움

해결: 양자화, 가지치기, 지식 증류

과적합 대응

# 다양한 정규화 기법 필요
model = Sequential([
    Dense(128, activation='relu'),
    Dropout(0.5),           # Dropout
    BatchNormalization(),   # Batch Norm
    Dense(64, activation='relu',
          kernel_regularizer=l2(0.01)),  # L2
])

# + Early Stopping, Data Augmentation

전통 ML vs 신경망

상황 전통 ML 신경망
적은 데이터 ✅ ❌
해석 필요 ✅ ❌
빠른 추론 ✅ △
비정형 데이터 ❌ ✅
SOTA 성능 △ ✅

면접 포인트

  • 블랙박스: 설명 불가 → XAI로 보완
  • 데이터/계산 비용: 많은 리소스 필요
  • 과적합: Dropout, BN 등 정규화 필수

딥러닝 혁신의 근간은 무엇이라고 생각하시나요?

한 줄 정의

데이터, 컴퓨팅 파워, 알고리즘의 동시 발전

세 가지 근간

딥러닝 혁신 = 데이터 × 컴퓨팅 × 알고리즘

               2012년 이전        2012년 이후
데이터         적음               빅데이터, 인터넷
컴퓨팅         CPU               GPU, TPU
알고리즘       얕은 네트워크      깊은 네트워크, 새 기법

1. 데이터 폭발

- ImageNet: 1400만 장의 레이블 이미지
- 인터넷: 웹 크롤링으로 대규모 데이터 수집
- SNS/모바일: 사용자 생성 데이터

"딥러닝은 데이터를 먹고 자란다"

2. 컴퓨팅 파워

GPU 병렬 연산:
- CPU: 순차 처리, 4~16 코어
- GPU: 병렬 처리, 수천 코어

행렬 연산에 최적화:
- 딥러닝 = 대규모 행렬 연산
- GPU가 CPU 대비 100배 이상 빠름

클라우드 컴퓨팅:
- AWS, GCP로 누구나 접근 가능

3. 알고리즘 혁신

연도 혁신 영향
2006 DBN 사전학습 딥네트워크 학습 가능
2012 AlexNet (ReLU, Dropout) CV 혁명
2014 GAN, Adam 생성모델, 안정적 학습
2015 ResNet (Skip Connection) 매우 깊은 네트워크
2017 Transformer NLP 혁명 → LLM
2020+ Scaling Law 크면 클수록 좋다

역사적 관점

1차 AI 겨울 (1970s): 퍼셉트론의 한계
2차 AI 겨울 (1990s): 학습 어려움

돌파구 (2012):
- AlexNet이 ImageNet에서 압도적 성능
- GPU 활용, ReLU, Dropout

이후 폭발적 성장

최근 트렌드: Scaling Law

"모델과 데이터를 키우면 성능이 계속 향상"

GPT-3: 1750억 파라미터
GPT-4: 수조 파라미터 (추정)

→ 컴퓨팅 + 데이터의 중요성 재확인

면접 포인트

  • 삼박자: 데이터 + 컴퓨팅(GPU) + 알고리즘
  • 2012 AlexNet: 딥러닝 부흥의 시작
  • Scaling Law: 크기가 성능을 결정