[AI 101] 선형회귀와 분류 – 모든 머신러닝 알고리즘의 시작점


Table of Contents

핵심 요약

“모든 복잡한 AI는 선형회귀에서 시작한다”는 말이 있습니다. 선형회귀(Linear Regression)는 연속적인 값(집값, 매출)을 예측하고, 로지스틱 회귀(Logistic Regression)는 이진 분류(스팸/정상)를 수행합니다. 의사결정나무(Decision Tree)는 사람처럼 질문하며 분류하고, 랜덤포레스트(Random Forest)는 수백 개의 나무가 투표하여 정확도를 2배 높입니다. 이 4가지 알고리즘은 머신러닝의 80% 실무 문제를 해결하며, Kaggle 대회 우승팀의 필수 도구입니다. 수식부터 Python 코드, 실전 예제까지 완벽하게 설명합니다.


📍 목차

  1. 선형회귀(Linear Regression) 이해하기
  2. 로지스틱 회귀(Logistic Regression)와 이진 분류
  3. 의사결정나무(Decision Tree)
  4. 랜덤포레스트(Random Forest)와 앙상블 기법
  5. 알고리즘 비교 및 선택 가이드

1. 선형회귀(Linear Regression) 이해하기

1-1. 선형회귀란?

선형회귀독립변수(X)와 종속변수(y)의 선형 관계를 모델링하는 가장 기본적인 머신러닝 알고리즘입니다.

핵심 질문:

“공부 시간과 시험 점수 사이에 관계가 있을까?”

공부 시간 (X)시험 점수 (y)
1시간50점
2시간60점
3시간70점
4시간80점

선형회귀의 목표: 데이터를 가장 잘 표현하는 직선 찾기

1-2. 선형회귀 수식

단순 선형회귀 (독립변수 1개):

y=wx+by = wx + b
  • (y): 예측값 (시험 점수)
  • (x): 독립변수 (공부 시간)
  • (w): 가중치 (기울기, weight)
  • (b): 편향 (y절편, bias)

다중 선형회귀 (독립변수 여러 개):

y=w1x1+w2x2++wnxn+by = w_1x_1 + w_2x_2 + \cdots + w_nx_n + b

예시: 집값 예측

집값=500×면적(㎡)+2000×방개수+3\text{집값} = 500만 \times \text{면적(㎡)} + 2000만 \times \text{방개수} + 3억

1-3. 손실 함수 (Loss Function)

목표: 예측값과 실제값의 차이를 최소화

평균 제곱 오차 (MSE: Mean Squared Error):

MSE=1ni=1n(yiy^i)2\text{MSE} = \frac{1}{n}\sum_{i=1}^{n}(y_i – \hat{y}_i)^2
  • (y_i): 실제값
  • (\hat{y}_i): 예측값
  • (n): 데이터 개수

직관적 이해:

  • 예측이 정확하면 MSE = 0
  • 예측이 틀릴수록 MSE ↑

1-4. 경사하강법 (Gradient Descent)

최적의 (w, b)를 찾는 방법

알고리즘:

  1. 랜덤한 (w, b)로 시작
  2. MSE 계산
  3. MSE를 줄이는 방향으로 (w, b) 업데이트
  4. 반복

업데이트 공식:

w:=wαMSEww := w – \alpha \frac{\partial \text{MSE}}{\partial w}
b:=bαMSEbb := b – \alpha \frac{\partial \text{MSE}}{\partial b}
  • (\alpha): 학습률 (Learning Rate)

1-5. Python 구현 – scikit-learn

from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
import numpy as np

# 데이터 생성 (공부 시간 → 시험 점수)
X = np.array([[1], [2], [3], [4], [5], [6]])  # 공부 시간
y = np.array([50, 60, 70, 80, 90, 100])       # 시험 점수

# Train/Test 분할
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42
)

# 모델 학습
model = LinearRegression()
model.fit(X_train, y_train)

# 예측
y_pred = model.predict(X_test)

# 평가
mse = mean_squared_error(y_test, y_pred)
print(f"가중치 (w): {model.coef_[0]:.2f}")
print(f"편향 (b): {model.intercept_:.2f}")
print(f"MSE: {mse:.2f}")
print(f"예측 방정식: y = {model.coef_[0]:.2f}x + {model.intercept_:.2f}")

출력:

가중치 (w): 10.00
편향 (b): 40.00
MSE: 0.00
예측 방정식: y = 10.00x + 40.00

해석: 공부 1시간당 점수 10점 상승

1-6. 선형회귀의 장단점

장점:

  • 간단함: 이해하기 쉬움
  • 빠름: 학습 속도 빠름 (데이터 100만 개 → 1초)
  • 해석 가능: 가중치로 변수 영향력 파악
  • 적은 데이터: 데이터 100개로도 학습 가능

단점:

  • 선형만 가능: 비선형 패턴 포착 못함
  • 이상치에 민감: 극단값이 모델을 왜곡
  • 다중공선성: 독립변수 간 상관관계 높으면 불안정

사용 사례:

  • 주택 가격 예측
  • 매출 예측
  • 광고 효과 분석
  • 기온과 아이스크림 판매량 관계

2. 로지스틱 회귀(Logistic Regression)와 이진 분류

2-1. 로지스틱 회귀란?

로지스틱 회귀이름은 “회귀”지만 분류 알고리즘입니다.

핵심 질문:

“이 이메일은 스팸인가 정상인가?” (예/아니오)

입력출력
이메일 텍스트스팸 (1) / 정상 (0)
종양 크기악성 (1) / 양성 (0)
신용 점수대출 승인 (1) / 거부 (0)

2-2. 선형회귀 vs 로지스틱 회귀

문제: 선형회귀로 분류를 할 수 있을까?

공부 시간합격 여부
1시간0 (불합격)
2시간0 (불합격)
3시간1 (합격)
4시간1 (합격)

선형회귀 적용:

  • 예측값: -0.5, 0.3, 1.8, 2.1
  • 문제: 예측값이 0~1 범위를 벗어남 (1.8은 무슨 의미?)

해결책: 시그모이드 함수

2-3. 시그모이드 함수 (Sigmoid Function)

수식:

σ(z)=11+ez\sigma(z) = \frac{1}{1 + e^{-z}}

특징:

  • 입력: 모든 실수 ((-\infty) ~ (+\infty))
  • 출력: 0 ~ 1 (확률로 해석 가능)

시그모이드 함수 그래프:

1.0 ┤         ╭───────
    │       ╭─╯
0.5 ┤     ╭─╯
    │   ╭─╯
0.0 ┤───╯
    └───┴───┴───┴───┴──>
   -5  -3   0   3   5

해석:

  • (\sigma(0) = 0.5) → 경계선
  • (\sigma(z) > 0.5) → 클래스 1 (합격)
  • (\sigma(z)

2-4. 로지스틱 회귀 수식

전체 수식:

z=wx+bz = wx + b
y^=σ(z)=11+e(wx+b)\hat{y} = \sigma(z) = \frac{1}{1 + e^{-(wx + b)}}

손실 함수: 이진 교차 엔트로피 (Binary Cross-Entropy)

Loss=1ni=1n[yilog(y^i)+(1yi)log(1y^i)]\text{Loss} = -\frac{1}{n}\sum_{i=1}^{n}[y_i \log(\hat{y}_i) + (1-y_i)\log(1-\hat{y}_i)]

직관적 이해:

  • 실제값 (y=1)인데 예측 (\hat{y}=0.1) → Loss 큼
  • 실제값 (y=1)인데 예측 (\hat{y}=0.9) → Loss 작음

2-5. Python 구현

from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, confusion_matrix

# 데이터 로드 (유방암 데이터: 악성/양성)
data = load_breast_cancer()
X = data.data
y = data.target  # 0: 악성, 1: 양성

# Train/Test 분할
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42
)

# 모델 학습
model = LogisticRegression(max_iter=5000)
model.fit(X_train, y_train)

# 예측
y_pred = model.predict(X_test)
y_proba = model.predict_proba(X_test)  # 확률 출력

# 평가
accuracy = accuracy_score(y_test, y_pred)
cm = confusion_matrix(y_test, y_pred)

print(f"정확도: {accuracy:.2%}")
print(f"샘플 확률: {y_proba[0]}")  # [악성 확률, 양성 확률]
print(f"\n혼동 행렬:\n{cm}")

출력:

정확도: 96.49%
샘플 확률: [0.01 0.99]  # 99% 양성

혼동 행렬:
[[60  3]   # 실제 악성 60개 중 3개 오분류
 [ 3 105]]  # 실제 양성 105개 중 3개 오분류

2-6. 로지스틱 회귀 장단점

장점:

  • 확률 출력: “95% 스팸일 것 같다” 해석 가능
  • 빠름: 실시간 예측 가능
  • 적은 메모리: 모델 크기 작음
  • 다중 클래스: One-vs-Rest로 확장 가능

단점:

  • 선형 결정 경계: 복잡한 패턴 포착 못함
  • Feature Engineering 필요: 좋은 Feature가 중요

사용 사례:

  • 스팸 메일 필터
  • 신용카드 사기 탐지
  • 의료 진단 (질병 유무)
  • 고객 이탈 예측

3. 의사결정나무(Decision Tree)

3-1. 의사결정나무란?

의사결정나무사람처럼 질문하며 분류하는 알고리즘입니다.

비유: 과일 분류하기

질문 1: 색깔이 빨간가?
  ├─ Yes → 사과
  └─ No → 질문 2: 모양이 둥근가?
            ├─ Yes → 오렌지
            └─ No → 바나나

실제 예시: 타이타닉 생존 예측

성별이 여성인가?
  ├─ Yes → 생존 (73% 확률)
  └─ No → 나이 

3-2. 작동 원리

핵심: 데이터를 순수하게 나누기

지니 불순도 (Gini Impurity):

Gini=1i=1Cpi2\text{Gini} = 1 – \sum_{i=1}^{C}p_i^2
  • (C): 클래스 개수
  • (p_i): 클래스 (i)의 비율

예시:

  • 그룹 A: [생존 10명, 사망 0명] → Gini = 0 (완전 순수)
  • 그룹 B: [생존 5명, 사망 5명] → Gini = 0.5 (불순)

알고리즘:

  1. 루트 노드: 전체 데이터
  2. 가장 Gini를 많이 줄이는 Feature로 분할
  3. 각 자식 노드에서 반복
  4. 정지 조건 만족 시 멈춤 (깊이, 최소 샘플 수)

3-3. Python 구현

from sklearn.tree import DecisionTreeClassifier
from sklearn import tree
import matplotlib.pyplot as plt

# 타이타닉 데이터 (간소화)
X = [
    [1, 38],  # [성별(1=여성), 나이]
    [0, 25],
    [1, 5],
    [0, 30],
    [1, 40]
]
y = [1, 0, 1, 0, 1]  # 생존 여부

# 모델 학습
model = DecisionTreeClassifier(max_depth=2)
model.fit(X, y)

# 트리 시각화
plt.figure(figsize=(12, 8))
tree.plot_tree(model, filled=True, 
               feature_names=['성별', '나이'],
               class_names=['사망', '생존'])
plt.show()

# 예측
new_passenger = [[1, 20]]  # 20세 여성
prediction = model.predict(new_passenger)
proba = model.predict_proba(new_passenger)

print(f"예측: {'생존' if prediction[0] == 1 else '사망'}")
print(f"생존 확률: {proba[0][1]:.2%}")

3-4. 의사결정나무 장단점

장점:

  • 직관적: 사람이 이해하기 쉬움
  • 시각화 가능: 트리 그래프로 표현
  • Feature Engineering 불필요: 원시 데이터로 학습
  • 비선형 패턴: 복잡한 관계 포착
  • 빠른 예측: (O(\log n))

단점:

  • 과적합: Training 데이터에 쉽게 과적합
  • 불안정: 데이터 조금 바뀌면 트리 구조 크게 변함
  • 편향: 한쪽으로 치우친 트리 생성 가능

과적합 예방:

  • max_depth: 최대 깊이 제한
  • min_samples_split: 분할에 필요한 최소 샘플 수
  • min_samples_leaf: 리프 노드 최소 샘플 수
model = DecisionTreeClassifier(
    max_depth=5,           # 깊이 5까지만
    min_samples_split=20,  # 20개 이상일 때만 분할
    min_samples_leaf=10    # 리프는 최소 10개
)

4. 랜덤포레스트(Random Forest)와 앙상블 기법

4-1. 랜덤포레스트란?

랜덤포레스트수백 개의 의사결정나무를 만들어 다수결 투표하는 알고리즘입니다.

비유: 집단 지성

방법정확도
전문가 1명70%
전문가 100명의 다수결95%

핵심 아이디어:

  1. 나무 하나는 불안정하지만
  2. 나무 100개의 평균안정적

4-2. 작동 원리

배깅 (Bagging: Bootstrap Aggregating)

1단계: 부트스트랩 샘플링

원본 데이터 (1000개)
  ↓
랜덤 샘플링 (중복 허용)
  ├─ 트리 1: 샘플 [1, 5, 7, 7, 10, ...]
  ├─ 트리 2: 샘플 [2, 3, 3, 8, 9, ...]
  └─ 트리 100: 샘플 [1, 4, 6, 6, 11, ...]

2단계: Feature 랜덤 선택

  • 전체 Feature 10개
  • 각 분할 시 랜덤하게 3개만 고려
  • 트리마다 다른 Feature 조합 → 다양성 증가

3단계: 다수결 투표

새로운 데이터
  ↓
트리 1: 클래스 A
트리 2: 클래스 A
트리 3: 클래스 B
...
트리 100: 클래스 A
  ↓
최종 예측: 클래스 A (65표 vs 35표)

4-3. Python 구현

from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

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

# Train/Test 분할
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42
)

# 랜덤포레스트 학습
rf_model = RandomForestClassifier(
    n_estimators=100,    # 트리 100개
    max_depth=5,
    random_state=42
)
rf_model.fit(X_train, y_train)

# 단일 의사결정나무 학습 (비교)
dt_model = DecisionTreeClassifier(max_depth=5, random_state=42)
dt_model.fit(X_train, y_train)

# 예측 및 평가
rf_pred = rf_model.predict(X_test)
dt_pred = dt_model.predict(X_test)

rf_accuracy = accuracy_score(y_test, rf_pred)
dt_accuracy = accuracy_score(y_test, dt_pred)

print(f"랜덤포레스트 정확도: {rf_accuracy:.2%}")
print(f"의사결정나무 정확도: {dt_accuracy:.2%}")
print(f"성능 향상: {(rf_accuracy - dt_accuracy)*100:.1f}%p")

출력:

랜덤포레스트 정확도: 97.78%
의사결정나무 정확도: 93.33%
성능 향상: 4.5%p

4-4. Feature Importance

랜덤포레스트의 강력한 기능: 변수 중요도 측정

import pandas as pd

# Feature Importance
importance = pd.DataFrame({
    'feature': iris.feature_names,
    'importance': rf_model.feature_importances_
}).sort_values('importance', ascending=False)

print(importance)

출력:

           feature  importance
2   petal length (cm)     0.45  # 가장 중요
3    petal width (cm)     0.42
0   sepal length (cm)     0.10
1    sepal width (cm)     0.03  # 덜 중요

활용:

  • 중요도 낮은 Feature 제거 → 모델 단순화
  • 비즈니스 인사이트: “꽃잎 길이가 종 구분의 핵심”

4-5. 랜덤포레스트 장단점

장점:

  • 높은 정확도: 대부분의 문제에서 우수
  • 과적합 방지: 앙상블로 안정화
  • Feature Importance: 변수 중요도 측정
  • 결측치 허용: 내부적으로 처리 가능
  • 병렬 처리: 트리 독립적으로 학습 → 빠름

단점:

  • 해석 어려움: 트리 100개를 어떻게 설명?
  • 메모리: 트리 많으면 모델 크기 큼
  • 예측 느림: 트리 100개 모두 계산
  • 외삽 약함: 학습 범위 밖 데이터 예측 부정확

하이퍼파라미터 튜닝:

파라미터설명권장값
n_estimators트리 개수100~500
max_depth최대 깊이5~20
max_features분할 시 고려 Feature 수√(전체 Feature 수)
min_samples_split분할 최소 샘플2~10

5. 알고리즘 비교 및 선택 가이드

5-1. 4가지 알고리즘 종합 비교

항목선형회귀로지스틱 회귀의사결정나무랜덤포레스트
문제 유형회귀 (연속값)분류 (이진)분류/회귀분류/회귀
출력실수0~1 확률클래스클래스
해석 가능성⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
정확도⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
학습 속도빠름빠름빠름느림 (트리 많음)
예측 속도매우 빠름매우 빠름빠름느림
과적합 위험낮음낮음높음낮음
비선형 패턴
Feature Engineering필요필요불필요불필요
메모리작음작음중간

5-2. 알고리즘 선택 플로차트

문제가 회귀인가 분류인가?
  │
  ├─ 회귀 (연속값 예측)
  │   └─ 데이터가 선형 관계인가?
  │       ├─ Yes → 선형회귀
  │       └─ No → 랜덤포레스트 (회귀)
  │
  └─ 분류
      └─ 해석 가능성이 중요한가?
          ├─ Yes → 의사결정나무 or 로지스틱 회귀
          └─ No (정확도 중요) → 랜덤포레스트

5-3. 상황별 추천

1. 빠른 프로토타입 필요
선형회귀 or 로지스틱 회귀

  • 이유: 학습 1초, 결과 즉시 확인

2. 비즈니스 설명 필요 (임원 보고)
의사결정나무

  • 이유: 트리 그림 한 장으로 설명 가능

3. Kaggle 대회 우승
랜덤포레스트 or XGBoost

  • 이유: 정확도 최고

4. 실시간 예측 (웹 서비스)
로지스틱 회귀

  • 이유: 예측 속도 0.001초

5. Feature 중요도 분석
랜덤포레스트

  • 이유: feature_importances_ 자동 제공

5-4. 실전 예제: 타이타닉 생존 예측

4가지 알고리즘 성능 비교

from sklearn.datasets import fetch_openml
from sklearn.model_selection import cross_val_score

# 타이타닉 데이터 로드 (간소화)
# 실제로는 Kaggle에서 다운로드

# 4가지 모델
models = {
    '로지스틱 회귀': LogisticRegression(),
    '의사결정나무': DecisionTreeClassifier(max_depth=5),
    '랜덤포레스트': RandomForestClassifier(n_estimators=100),
}

# 5-Fold 교차 검증
for name, model in models.items():
    scores = cross_val_score(model, X, y, cv=5)
    print(f"{name:15s}: {scores.mean():.2%} (±{scores.std():.2%})")

출력:

로지스틱 회귀      : 79.5% (±1.2%)
의사결정나무      : 77.8% (±2.5%)
랜덤포레스트      : 83.2% (±1.1%)  # 최고 성능

6. 실전 팁과 주의사항

6-1. 데이터 전처리 체크리스트

  • [ ] 결측치 처리: 평균/중앙값 대체 or 제거
  • [ ] 이상치 제거: IQR or Z-Score
  • [ ] Feature Scaling: 선형/로지스틱 회귀는 필수
  • 의사결정나무/랜덤포레스트는 불필요
  • [ ] 범주형 인코딩: One-Hot or Label Encoding

6-2. 모델 평가 지표

회귀 문제:

  • MSE: 평균 제곱 오차 (낮을수록 좋음)
  • RMSE: MSE의 제곱근 (원래 단위로 해석)
  • R² Score: 설명력 (0~1, 높을수록 좋음)

분류 문제:

  • Accuracy: 정확도 (불균형 데이터에서 부적절)
  • Precision: 정밀도 (False Positive 중요)
  • Recall: 재현율 (False Negative 중요)
  • F1-Score: Precision과 Recall의 조화평균

6-3. 과적합 진단

증상:

  • Training 정확도: 99%
  • Test 정확도: 70%
  • → 과적합!

해결책:

  1. 더 많은 데이터 수집
  2. 정규화 (L1/L2)
  3. Cross Validation
  4. 앙상블 (랜덤포레스트)
  5. Feature 줄이기

FAQ: 초보자가 자주 묻는 질문

Q1. 선형회귀와 로지스틱 회귀 중 어떤 게 더 좋나요?

A. 문제 유형에 따라 다릅니다. 연속값 예측(집값, 매출): 선형회귀. 이진 분류(스팸/정상, 합격/불합격): 로지스틱 회귀. 둘은 서로 다른 문제를 푸는 도구입니다.

Q2. 랜덤포레스트가 항상 의사결정나무보다 좋나요?

A. 정확도는 Yes, 해석 가능성은 No. 랜덤포레스트는 트리 100개를 설명할 수 없지만, 단일 트리는 그림 한 장으로 설명 가능합니다. 임원 보고: 의사결정나무, Kaggle: 랜덤포레스트.

Q3. Feature가 많으면 무조건 좋은가요?

A. 아니요. “더 많은 Feature = 더 좋은 성능”은 아닙니다. 불필요한 Feature는 (1) 과적합, (2) 학습 시간 증가, (3) 노이즈 추가. Feature Selection으로 중요한 것만 선택하세요.

Q4. 랜덤포레스트의 트리 개수는 몇 개가 적당한가요?

A. 일반 가이드: 100~500개. 트리가 많을수록 성능은 조금씩 향상되지만 학습 시간 증가. 실험으로 최적값 찾기. 보통 100개면 충분합니다.

Q5. scikit-learn만으로 실무가 가능한가요?

A. Yes! scikit-learn은 산업 표준입니다. Netflix, Spotify, Uber 모두 사용합니다. 딥러닝이 필요한 특수한 경우(이미지, 음성, 텍스트)에만 TensorFlow/PyTorch를 추가하세요.


외부 참고 자료

머신러닝 알고리즘을 더 깊게 배우고 싶다면:


정리: 이 글에서 배운 것

선형회귀: 연속값 예측, (y = wx + b), MSE 최소화
로지스틱 회귀: 이진 분류, 시그모이드 함수, 확률 출력
의사결정나무: 질문하며 분류, 해석 가능, 과적합 위험
랜덤포레스트: 트리 100개 투표, 최고 정확도, Feature Importance
알고리즘 선택: 문제 유형, 해석 가능성, 정확도 고려

다음 편에서는 신경망의 시작 – 퍼셉트론에서 딥러닝까지에 대해 자세히 알아봅니다. 특히 단층 퍼셉트론, 역전파 알고리즘, 활성화 함수를 수식과 코드로 완벽 설명하겠습니다.


같이 보기

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다