---
title: "선형회귀와 분류 완전 정복: 로지스틱 회귀·의사결정나무·랜덤포레스트"
id: "1684"
type: "post"
slug: "ml-algorithms-linear-logistic-regression-decision-tree-random-forest2"
published_at: "2026-07-20T02:26:06+00:00"
modified_at: "2026-07-20T02:46:15+00:00"
url: "https://doyouknow.kr/ml-algorithms-linear-logistic-regression-decision-tree-random-forest2/"
markdown_url: "https://doyouknow.kr/ml-algorithms-linear-logistic-regression-decision-tree-random-forest2.md"
excerpt: "연속값을 예측하는 선형회귀부터 확률 기반 분류인 로지스틱 회귀, 규칙을 학습하는 의사결정나무, 여러 나무를 결합하는 랜덤포레스트까지 고전 머신러닝의 핵심을 실전 관점에서 정리합니다."
taxonomy_category:
  - "AI"
  - "AI 101"
taxonomy_post_tag:
  - "scikit-learn"
  - "랜덤포레스트"
  - "로지스틱 회귀"
  - "머신러닝"
  - "분류"
  - "선형회귀"
  - "의사결정나무"
  - "지도학습"
  - "회귀"
---

머신러닝을 처음 배울 때 가장 먼저 구분해야 하는 것은 **회귀(Regression)**와 **분류(Classification)**입니다.

- **회귀**는 집값, 매출, 온도처럼 연속적인 숫자를 예측합니다.
- **분류**는 정상/불량, 스팸/정상, 이탈/유지처럼 정해진 범주를 예측합니다.

이 글에서는 고전 머신러닝의 핵심 모델인 **선형회귀**, **로지스틱 회귀**, **의사결정나무**, **랜덤포레스트**를 하나의 흐름으로 설명합니다. 단순히 사용법만 나열하지 않고 다음 질문에 답하는 것을 목표로 합니다.

> 모델은 무엇을 학습하는가?
> 어떤 손실 함수를 최소화하는가?
> 예측값은 어떻게 해석해야 하는가?
> 어떤 상황에서 모델 선택이 달라지는가?
> 높은 정확도가 실제로 믿을 만한 결과인가?

## 핵심 요약

| 모델 | 주된 문제 | 모델이 학습하는 것 | 강점 | 대표적인 약점 |
| --- | --- | --- | --- | --- |
| 선형회귀 | 회귀 | 입력과 출력의 선형 관계 | 빠르고 해석이 쉬움 | 비선형 관계와 이상치에 약함 |
| 로지스틱 회귀 | 분류 | 클래스에 속할 로그 오즈 | 확률 출력, 계수 해석 가능 | 기본 결정 경계가 선형 |
| 의사결정나무 | 회귀·분류 | 조건문 형태의 분할 규칙 | 비선형 관계, 시각화 | 과적합과 불안정성 |
| 랜덤포레스트 | 회귀·분류 | 서로 다른 여러 나무의 집계 | 안정적이고 강한 기준 모델 | 크고 느리며 외삽에 약함 |

가장 중요한 결론은 다음과 같습니다.

1. 복잡한 모델이 항상 더 좋은 모델은 아닙니다.
2. 회귀와 분류는 출력 형태뿐 아니라 손실 함수와 평가 방법도 다릅니다.
3. 분류 확률과 최종 클래스 결정은 별개의 단계입니다.
4. 모델 성능은 한 번의 학습/검증 분할보다 교차검증으로 비교하는 편이 안전합니다.
5. 랜덤포레스트의 기본 변수 중요도는 편향될 수 있으므로 순열 중요도도 함께 확인해야 합니다.
6. 실제 프로젝트에서는 전처리와 모델을 `Pipeline`으로 묶어 데이터 누수를 막아야 합니다.

## 1. 회귀와 분류는 무엇이 다른가?

### 1.1 회귀: 연속적인 숫자를 예측한다

회귀의 목표값은 숫자 축 위에서 연속적으로 변합니다.

| 입력 예시 | 예측 대상 |
| --- | --- |
| 면적, 방 개수, 지역 | 아파트 가격 |
| 광고비, 방문자 수 | 다음 달 매출 |
| 온도, 습도, 풍속 | 전력 사용량 |
| 충전 이력, 온도, 내부 저항 | 배터리 잔여 수명 |

예측 결과는 `3.7억 원`, `125.4kWh`, `42.8일`처럼 실수로 표현됩니다.

### 1.2 분류: 정해진 범주를 예측한다

분류의 목표값은 클래스입니다.

| 입력 예시 | 예측 대상 |
| --- | --- |
| 이메일 본문, 발신자 | 스팸 / 정상 |
| 센서값, 영상 특성 | 정상 / 불량 |
| 거래 금액, 장소, 시간 | 사기 / 정상 |
| 고객 행동 이력 | 이탈 / 유지 |

이진 분류는 두 클래스를 구분하고, 다중 분류는 세 개 이상의 클래스를 구분합니다.

### 1.3 숫자로 저장했다고 회귀가 되는 것은 아니다

클래스를 다음과 같이 숫자로 표현할 수 있습니다.

```
정상 = 0
불량 = 1
보류 = 2
```

하지만 `2`가 `1`보다 두 배 크다는 뜻은 아닙니다. 이 숫자는 클래스 이름을 컴퓨터가 처리할 수 있도록 바꾼 **라벨**일 뿐입니다.

반대로 만족도를 `1~5점`으로 수집했다면 문제 목적에 따라 다음처럼 다르게 접근할 수 있습니다.

- 점수 자체를 예측: 회귀 또는 순서형 회귀
- 만족/불만족으로 재정의: 이진 분류
- 1~5단계를 각각 예측: 다중 분류 또는 순서형 분류

따라서 알고리즘보다 먼저 **예측 결과를 어떤 의사결정에 사용할지** 정의해야 합니다.

## 2. 선형회귀: 데이터에 가장 잘 맞는 선을 찾는다

### 2.1 기본 아이디어

공부 시간으로 시험 점수를 예측한다고 해보겠습니다.

```
공부 시간 x:  1,  2,  3,  4,  5
시험 점수 y: 48, 58, 71, 79, 92
```

선형회귀는 이 점들을 완벽하게 통과하는 선을 찾는 것이 아니라, **전체 오차가 가장 작아지는 선**을 찾습니다.

단순 선형회귀는 다음처럼 표현합니다.

```
ŷ = w₁x + b
```

- `x`: 입력 특성
- `w₁`: 기울기 또는 회귀계수
- `b`: 절편
- `ŷ`: 모델의 예측값

특성이 여러 개라면 다중 선형회귀가 됩니다.

```
ŷ = w₁x₁ + w₂x₂ + ... + wₚxₚ + b
```

집값 예측이라면 다음과 같이 해석할 수 있습니다.

```
예측 집값 = 면적 계수 × 면적
          + 방 개수 계수 × 방 개수
          + 역 거리 계수 × 역과의 거리
          + 절편
```

### 2.2 회귀계수는 어떻게 해석할까?

다른 조건이 같다는 가정 아래 면적 계수가 `0.035`이고 가격 단위가 억 원이라면 다음처럼 해석합니다.

> 면적이 1㎡ 증가할 때 예측 가격은 평균적으로 0.035억 원 증가한다.

하지만 계수 해석에는 주의가 필요합니다.

- 특성끼리 강하게 상관되어 있으면 계수가 불안정해질 수 있습니다.
- 관측되지 않은 변수가 빠져 있으면 계수에 다른 효과가 섞일 수 있습니다.
- 상관관계를 학습했다고 해서 인과관계를 증명한 것은 아닙니다.
- 범주형 변수를 원-핫 인코딩했다면 기준 범주와 비교해 해석해야 합니다.
- 상호작용항이나 로그 변환을 사용하면 계수 의미도 달라집니다.

### 2.3 손실 함수: 평균제곱오차

각 샘플의 잔차는 다음과 같습니다.

```
잔차 eᵢ = 실제값 yᵢ - 예측값 ŷᵢ
```

일반적인 선형회귀는 잔차 제곱의 평균인 MSE를 최소화합니다.

```
MSE = (1 / n) × Σ(yᵢ - ŷᵢ)²
```

오차를 제곱하는 이유는 다음과 같습니다.

- 양수와 음수 오차가 서로 상쇄되지 않습니다.
- 큰 오차에 더 큰 벌점을 줍니다.
- 미분 가능한 형태라 최적화하기 쉽습니다.

반대로 큰 이상치 하나가 손실을 크게 키울 수 있다는 뜻이기도 합니다. 이상치가 많다면 MAE, Huber Loss, RANSAC 같은 대안도 검토할 수 있습니다.

손실 함수에 대한 자세한 내용은 [손실함수 완전 정복](https://doyouknow.kr/loss-function-complete-guide2/)
에서 이어서 볼 수 있습니다.

### 2.4 선형회귀의 가정

선형회귀를 단순 예측기가 아니라 통계적 추론 도구로 사용할 때는 다음 가정이 중요합니다.

#### 선형성

특성과 목표값 사이의 기대 관계가 선형이어야 합니다. 비선형 관계라면 다항 특성, 로그 변환, 스플라인 또는 트리 기반 모델이 더 적합할 수 있습니다.

#### 오차의 독립성

한 관측값의 오차가 다른 관측값의 오차와 강하게 연결되지 않아야 합니다. 시계열 데이터에서는 시간 순서에 따른 자기상관을 특히 확인해야 합니다.

#### 등분산성

예측값의 크기에 따라 잔차 분산이 크게 달라지지 않아야 합니다. 가격이 커질수록 오차 폭도 커지는 데이터에서는 로그 변환이 도움이 될 수 있습니다.

#### 다중공선성 관리

두 특성이 거의 같은 정보를 담으면 각각의 계수를 안정적으로 추정하기 어렵습니다. 예를 들어 `면적(㎡)`과 `면적(평)`을 동시에 넣으면 사실상 같은 정보를 두 번 제공하는 셈입니다.

#### 잔차의 정규성

예측 자체보다 계수의 신뢰구간이나 유의성 검정에 더 중요한 가정입니다. 머신러닝 예측만을 목표로 한다면 정규성 위반이 곧 모델 사용 불가를 뜻하지는 않습니다.

### 2.5 선형회귀 실전 코드

아래 예제는 캘리포니아 주택 데이터로 선형회귀를 평가합니다. 전처리가 포함될 가능성을 고려해 처음부터 `Pipeline` 형태를 사용합니다.

```
from sklearn.datasets import fetch_california_housing
from sklearn.linear_model import LinearRegression
from sklearn.metrics import (
    mean_absolute_error,
    mean_squared_error,
    r2_score,
)
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler

# 데이터
data = fetch_california_housing(as_frame=True)
X = data.data
y = data.target

# 평가용 데이터는 학습에 사용하지 않는다.
X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.2,
    random_state=42,
)

# 선형회귀 자체는 스케일링 없이도 학습할 수 있지만,
# 계수 비교와 정규화 모델 확장을 위해 Pipeline으로 구성한다.
model = make_pipeline(
    StandardScaler(),
    LinearRegression(),
)

model.fit(X_train, y_train)
y_pred = model.predict(X_test)

mae = mean_absolute_error(y_test, y_pred)
rmse = mean_squared_error(y_test, y_pred) ** 0.5
r2 = r2_score(y_test, y_pred)

print(f"MAE : {mae:.4f}")
print(f"RMSE: {rmse:.4f}")
print(f"R²  : {r2:.4f}")
```

실행 환경과 라이브러리 버전에 따라 결과는 달라질 수 있습니다. 따라서 블로그 예제에서 특정 점수를 보편적인 성능처럼 단정하기보다, **코드를 실행해 자신의 결과를 확인하도록 안내하는 편이 정확합니다.**

### 2.6 R²를 0~1로만 이해하면 안 되는 이유

결정계수 R²는 다음 관점으로 해석합니다.

```
R² = 1 - (모델의 제곱오차 합 / 평균 예측의 제곱오차 합)
```

- `R² = 1`: 평가 데이터에서 완벽한 예측
- `R² = 0`: 목표값 평균만 예측하는 기준선과 비슷함
- `R² < 0`: 평균만 예측하는 것보다 나쁨

따라서 R²는 항상 0과 1 사이에 있는 지표가 아닙니다. 테스트 데이터에서는 음수가 나올 수 있습니다.

### 2.7 선형회귀가 잘 맞는 경우

- 관계가 대체로 선형일 때
- 빠르고 설명 가능한 기준 모델이 필요할 때
- 각 특성의 방향과 크기를 분석하고 싶을 때
- 샘플 수보다 특성 수가 지나치게 많지 않을 때
- 학습 범위 밖의 값을 어느 정도 외삽해야 할 때

### 2.8 선형회귀가 잘 맞지 않는 경우

- 강한 비선형 관계가 있을 때
- 극단적인 이상치가 많을 때
- 특성 간 복잡한 상호작용이 많을 때
- 시간·공간적 의존성을 단순 독립 샘플로 볼 수 없을 때
- 목표값 분포가 심하게 치우쳐 있고 오차 구조도 일정하지 않을 때

## 3. 로지스틱 회귀: 선형 점수를 확률로 바꾸는 분류 모델

### 3.1 이름은 회귀지만 용도는 분류다

로지스틱 회귀는 입력 특성의 가중합을 먼저 계산합니다.

```
z = w₁x₁ + w₂x₂ + ... + wₚxₚ + b
```

이 점수 `z`는 음의 무한대부터 양의 무한대까지 가능합니다. 이를 시그모이드 함수에 통과시키면 0과 1 사이의 값이 됩니다.

```
p(y=1 | x) = 1 / (1 + exp(-z))
```

출력값은 주어진 입력이 양성 클래스에 속할 모델 확률로 해석합니다.

예를 들어:

```
p(y=1 | x) = 0.82
```

라면 모델은 해당 샘플이 클래스 1에 속할 확률을 0.82로 추정한 것입니다.

다만 이 값이 실제 빈도와 잘 일치하는지는 **확률 보정(calibration)**을 별도로 확인해야 합니다.

### 3.2 확률과 클래스 예측은 다른 단계다

로지스틱 회귀가 `0.63`을 출력했다고 해서 자동으로 반드시 클래스 1이 되어야 하는 것은 아닙니다. 일반적인 기본 임계값은 0.5이지만, 업무 비용에 따라 바꿀 수 있습니다.

```
확률 0.63
임계값 0.50 → 클래스 1
임계값 0.70 → 클래스 0
```

의료 선별검사처럼 놓치면 큰 피해가 생기는 문제에서는 임계값을 낮춰 재현율을 높일 수 있습니다. 반대로 정상 거래를 사기로 잘못 막는 비용이 크다면 임계값을 높여 정밀도를 우선할 수 있습니다.

즉, **모델 학습**과 **의사결정 임계값 선택**은 분리해서 생각해야 합니다.

### 3.3 로그 오즈를 선형으로 모델링한다

로지스틱 회귀가 실제로 선형 관계를 가정하는 대상은 확률 자체가 아니라 로그 오즈입니다.

```
오즈 = p / (1 - p)

log(p / (1 - p)) = w₁x₁ + ... + wₚxₚ + b
```

특성 `xⱼ`가 1 증가할 때 다른 특성이 같다면 오즈는 `exp(wⱼ)`배가 됩니다.

예를 들어 계수가 `0.69`라면:

```
exp(0.69) ≈ 1.99
```

즉 해당 특성이 1 증가할 때 양성 클래스의 오즈가 약 2배가 된다고 해석할 수 있습니다. 여기서 오즈와 확률은 서로 다른 개념이므로 “확률이 2배”라고 표현해서는 안 됩니다.

### 3.4 손실 함수: 로그 손실과 교차 엔트로피

이진 분류의 대표 손실 함수는 다음과 같습니다.

```
Binary Cross-Entropy
= -(1 / n) × Σ[yᵢ log(pᵢ) + (1-yᵢ) log(1-pᵢ)]
```

모델이 틀린 클래스를 높은 확률로 확신할수록 큰 벌점을 받습니다.

- 실제 `y=1`, 예측 확률 `p=0.99`: 손실이 작음
- 실제 `y=1`, 예측 확률 `p=0.01`: 손실이 매우 큼

정확도는 0.51과 0.99를 모두 같은 정답으로 처리하지만, 로그 손실은 확신의 정도까지 평가합니다.

### 3.5 정규화: 복잡도를 제어하는 핵심 장치

실제 `scikit-learn`의 `LogisticRegression`은 기본적으로 정규화를 사용합니다.

#### L2 정규화

큰 계수를 제곱 형태로 벌점화합니다. 여러 특성을 조금씩 사용하는 안정적인 모델이 되기 쉽습니다.

```
손실 + λ × Σwⱼ²
```

#### L1 정규화

계수의 절댓값에 벌점을 줍니다. 일부 계수를 정확히 0으로 만들 수 있어 특성 선택 효과가 있습니다.

```
손실 + λ × Σ|wⱼ|
```

`scikit-learn`에서는 정규화 강도를 `C`로 조절하며 `C`가 작을수록 정규화가 강해집니다.

### 3.6 로지스틱 회귀 실전 코드

수치형 특성의 결측치를 대체하고 표준화한 뒤 로지스틱 회귀를 학습합니다. 모든 전처리는 학습 폴드 안에서만 계산되도록 `Pipeline`에 포함합니다.

```
from sklearn.datasets import load_breast_cancer
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import (
    classification_report,
    confusion_matrix,
    roc_auc_score,
)
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler

data = load_breast_cancer(as_frame=True)
X = data.data
y = data.target

X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.2,
    stratify=y,
    random_state=42,
)

model = make_pipeline(
    SimpleImputer(strategy="median"),
    StandardScaler(),
    LogisticRegression(
        C=1.0,
        max_iter=5000,
        random_state=42,
    ),
)

model.fit(X_train, y_train)

y_pred = model.predict(X_test)
y_proba = model.predict_proba(X_test)[:, 1]

print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred, digits=3))
print(f"ROC-AUC: {roc_auc_score(y_test, y_proba):.3f}")
```

`stratify=y`는 학습 데이터와 테스트 데이터의 클래스 비율을 비슷하게 유지합니다.

### 3.7 임계값을 직접 적용하는 방법

```
threshold = 0.35
y_pred_custom = (y_proba >= threshold).astype(int)
```

하지만 테스트 세트를 보면서 가장 좋은 임계값을 고르면 테스트 정보가 모델 선택에 사용됩니다. 임계값은 별도의 검증 세트나 교차검증으로 선택하고, 마지막 테스트 세트는 최종 평가에만 사용해야 합니다.

최신 `scikit-learn`에서는 내부 교차검증을 이용해 특정 평가 지표에 맞는 임계값을 찾는 `TunedThresholdClassifierCV`도 제공합니다.

### 3.8 다중 분류로 확장하기

로지스틱 회귀는 다중 클래스에도 사용할 수 있습니다.

- **One-vs-Rest**: 각 클래스를 나머지 전체와 구분하는 이진 분류기를 여러 개 학습
- **Multinomial**: 소프트맥스를 이용해 모든 클래스를 한 번에 모델링

클래스가 셋 이상이면 단순히 “시그모이드 하나”만으로 설명하면 부족합니다. 사용한 솔버와 설정에 따라 실제 최적화 방식이 달라집니다.

### 3.9 로지스틱 회귀가 잘 맞는 경우

- 빠른 기준 분류 모델이 필요할 때
- 확률과 계수를 해석해야 할 때
- 희소한 고차원 데이터가 있을 때
- 선형 결정 경계가 충분하거나 특성 공학으로 선형화할 수 있을 때
- 추론 지연과 모델 크기를 작게 유지해야 할 때

### 3.10 로지스틱 회귀가 잘 맞지 않는 경우

- 복잡한 비선형 경계가 있을 때
- 상호작용을 직접 만들기 어려울 때
- 클래스별 군집이 여러 개로 흩어져 있을 때
- 입력 특성의 스케일 차이가 큰데 전처리를 하지 않았을 때

## 4. 의사결정나무: 질문을 반복해 공간을 나눈다

### 4.1 기본 아이디어

의사결정나무는 다음과 같은 규칙을 데이터에서 학습합니다.

```
센서 온도 ≤ 62.5°C인가?
├─ 예
│  └─ 진동 RMS ≤ 1.8인가?
│     ├─ 예: 정상
│     └─ 아니오: 점검
└─ 아니오
   └─ 불량
```

각 내부 노드는 하나의 질문을, 가지는 질문의 결과를, 리프 노드는 최종 예측을 나타냅니다.

### 4.2 나무는 어떻게 가장 좋은 질문을 찾을까?

분류 트리는 분할 전보다 분할 후의 클래스가 더 순수해지는 기준을 찾습니다.

#### 지니 불순도

```
Gini = 1 - Σpₖ²
```

- 한 클래스만 존재: `Gini = 0`
- 이진 클래스가 절반씩 존재: `Gini = 0.5`

#### 엔트로피

```
Entropy = -Σpₖ log₂(pₖ)
```

지니 불순도와 엔트로피는 수치가 다르지만, 실전에서 비슷한 분할을 만드는 경우가 많습니다. 어느 기준이 항상 우월하다고 보기보다는 교차검증으로 확인하는 편이 낫습니다.

### 4.3 회귀나무는 무엇을 최소화할까?

회귀나무는 리프 안의 목표값이 서로 비슷해지도록 나눕니다. 일반적으로 제곱오차를 줄이는 분할을 찾고, 리프에 도달한 샘플들의 평균을 예측값으로 사용합니다.

이 구조 때문에 회귀나무는 학습 범위 밖으로 자연스럽게 증가하거나 감소하는 값을 외삽하기 어렵습니다. 마지막 리프의 평균값 근처에서 계단식으로 예측하기 쉽습니다.

### 4.4 트리가 비선형 관계를 학습하는 방식

선형 모델은 하나의 직선 또는 초평면으로 경계를 만듭니다. 반면 결정 트리는 축에 평행한 조건을 여러 번 결합해 복잡한 영역을 만듭니다.

예를 들어 다음 상호작용을 별도 수식 없이 학습할 수 있습니다.

```
나이가 30세 미만이면서
최근 7일 접속 횟수가 2회 이하이고
요금제가 무료이면
이탈 위험이 높다
```

따라서 트리는 변수 간 조건부 상호작용을 자동으로 포착하는 장점이 있습니다.

### 4.5 의사결정나무 실전 코드

```
from sklearn.datasets import load_breast_cancer
from sklearn.metrics import classification_report
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, export_text

data = load_breast_cancer(as_frame=True)
X = data.data
y = data.target

X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.2,
    stratify=y,
    random_state=42,
)

model = DecisionTreeClassifier(
    criterion="gini",
    max_depth=4,
    min_samples_leaf=8,
    class_weight="balanced",
    random_state=42,
)

model.fit(X_train, y_train)
y_pred = model.predict(X_test)

print(classification_report(y_test, y_pred, digits=3))

rules = export_text(
    model,
    feature_names=list(X.columns),
    max_depth=3,
)
print(rules)
```

### 4.6 과적합을 제어하는 핵심 파라미터

| 파라미터 | 역할 | 커질 때 또는 작아질 때 |
| --- | --- | --- |
| max_depth | 최대 트리 깊이 | 작을수록 단순해짐 |
| min_samples_split | 노드를 나누는 최소 샘플 수 | 클수록 분할이 줄어듦 |
| min_samples_leaf | 리프 최소 샘플 수 | 클수록 예측이 부드러워짐 |
| max_leaf_nodes | 리프 개수 제한 | 작을수록 단순해짐 |
| ccp_alpha | 비용 복잡도 가지치기 | 클수록 더 많이 가지치기 |
| class_weight | 클래스별 손실 가중치 | 불균형 데이터에서 활용 |

깊이를 무조건 `5`로 고정하거나 모든 문제에 동일한 권장 범위를 적용하는 것은 적절하지 않습니다. 데이터 크기, 노이즈, 클래스 불균형, 평가 지표에 맞춰 교차검증으로 선택해야 합니다.

### 4.7 트리의 장점

- 수치형 특성의 표준화가 필수적이지 않습니다.
- 비선형 관계와 특성 간 상호작용을 학습합니다.
- 규칙 형태로 시각화할 수 있습니다.
- 단조 변환에 비교적 둔감합니다.
- 분류와 회귀 모두 지원합니다.

### 4.8 트리의 한계

- 깊은 트리는 훈련 데이터에 쉽게 과적합됩니다.
- 데이터가 조금만 바뀌어도 분할 구조가 크게 달라질 수 있습니다.
- 축에 평행한 분할 때문에 부드러운 경계를 비효율적으로 근사할 수 있습니다.
- 회귀 문제에서 외삽에 약합니다.
- 단일 트리의 클래스 확률은 리프의 표본 비율이므로 작은 리프에서는 거칠고 과신될 수 있습니다.

### 4.9 “트리는 특성 공학이 필요 없다”는 오해

트리는 표준화가 거의 필요하지 않지만, 이것이 특성 공학이 불필요하다는 뜻은 아닙니다.

여전히 다음 작업이 중요합니다.

- 잘못된 단위와 결측값 처리
- 날짜에서 요일·시간대·경과 시간 추출
- 누적값을 변화량으로 변환
- 범주형 데이터 인코딩
- 데이터 누수 특성 제거
- 미래 정보를 포함하는 특성 제거
- 식별자와 실제 설명 변수를 구분
- 도메인 기반 비율, 차이, 집계 특성 생성

자세한 내용은 [특성 공학 완전 가이드](https://doyouknow.kr/feature-engineering-selection-extraction-pca-normalization/)
에서 확인할 수 있습니다.

## 5. 랜덤포레스트: 서로 다른 나무를 모아 분산을 줄인다

### 5.1 단일 나무의 약점을 여러 나무로 줄인다

의사결정나무는 데이터 변화에 민감합니다. 랜덤포레스트는 서로 조금씩 다른 나무를 많이 만들고 결과를 집계해 이 불안정성을 줄입니다.

분류에서는 보통 여러 나무의 예측 확률 또는 투표를 집계하고, 회귀에서는 여러 나무의 예측값을 평균냅니다.

핵심은 나무의 개수만 늘리는 것이 아니라 **나무들이 서로 다르게 학습하도록 만드는 것**입니다.

### 5.2 두 가지 무작위성

#### 부트스트랩 샘플링

원본 학습 데이터에서 중복을 허용해 각 나무용 샘플을 뽑습니다.

```
원본: A B C D E
트리 1: A A C D E
트리 2: B C C E E
트리 3: A B D D E
```

#### 무작위 특성 선택

각 분할에서 전체 특성을 모두 검토하지 않고 일부만 후보로 사용합니다. 강한 특성 하나가 모든 나무를 지배하는 것을 줄이고 나무 간 다양성을 높입니다.

### 5.3 배깅이 분산을 줄이는 이유

서로 상관이 낮은 여러 추정기의 평균은 단일 추정기보다 변동성이 작습니다. 랜덤포레스트는 다음 두 가지를 동시에 추구합니다.

- 각 나무가 어느 정도 유용할 것
- 나무끼리 완전히 같은 실수를 하지 않을 것

나무가 너무 비슷하면 개수를 늘려도 얻는 이득이 제한적입니다. 무작위 특성 선택은 나무 간 상관을 낮추는 역할을 합니다.

### 5.4 OOB 평가

부트스트랩 샘플에는 중복이 생기므로 각 나무가 학습하지 않은 샘플이 남습니다. 이를 **Out-of-Bag 샘플**이라고 합니다.

`oob_score=True`를 사용하면 별도의 검증 세트 없이 학습 중 남은 샘플을 활용해 내부적인 일반화 성능 추정치를 얻을 수 있습니다.

```
from sklearn.ensemble import RandomForestClassifier

model = RandomForestClassifier(
    n_estimators=500,
    max_features="sqrt",
    min_samples_leaf=3,
    oob_score=True,
    n_jobs=-1,
    random_state=42,
)

model.fit(X_train, y_train)
print(f"OOB score: {model.oob_score_:.3f}")
```

OOB 점수는 유용한 진단 도구지만, 최종 테스트 세트와 교차검증을 완전히 대체한다고 보기는 어렵습니다.

### 5.5 랜덤포레스트 실전 코드

```
from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, roc_auc_score
from sklearn.model_selection import train_test_split

data = load_breast_cancer(as_frame=True)
X = data.data
y = data.target

X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.2,
    stratify=y,
    random_state=42,
)

model = RandomForestClassifier(
    n_estimators=500,
    max_features="sqrt",
    min_samples_leaf=3,
    class_weight="balanced",
    oob_score=True,
    n_jobs=-1,
    random_state=42,
)

model.fit(X_train, y_train)

y_pred = model.predict(X_test)
y_proba = model.predict_proba(X_test)[:, 1]

print(classification_report(y_test, y_pred, digits=3))
print(f"ROC-AUC : {roc_auc_score(y_test, y_proba):.3f}")
print(f"OOB score: {model.oob_score_:.3f}")
```

### 5.6 주요 하이퍼파라미터

| 파라미터 | 의미 | 실전 해석 |
| --- | --- | --- |
| n_estimators | 나무 개수 | 늘리면 대체로 안정화되지만 시간·메모리 증가 |
| max_depth | 각 나무 최대 깊이 | 작게 제한하면 과적합 감소 |
| max_features | 분할마다 검토할 특성 수 | 작을수록 나무 다양성 증가, 개별 나무 성능은 감소 가능 |
| min_samples_leaf | 리프 최소 표본 수 | 노이즈에 덜 민감하고 확률이 부드러워짐 |
| max_samples | 각 나무가 사용할 샘플 크기 | 학습 속도와 다양성 조절 |
| class_weight | 클래스 가중치 | 불균형 분류에서 비용 반영 |
| n_jobs | 병렬 작업 수 | -1이면 사용 가능한 CPU 코어 활용 |
| oob_score | OOB 평가 사용 | 부트스트랩 사용 시 내부 검증 가능 |

“트리는 무조건 100개면 충분하다”거나 “500개가 최적이다” 같은 고정 답은 없습니다. 나무 수에 따른 교차검증 성능과 학습 비용이 안정되는 지점을 확인해야 합니다.

### 5.7 변수 중요도는 그대로 믿어도 될까?

랜덤포레스트의 `feature_importances_`는 각 특성이 불순도를 얼마나 줄였는지 누적한 값입니다. 계산이 빠르지만 다음 문제가 있습니다.

- 가능한 분할 지점이 많은 연속형 또는 고카디널리티 특성이 유리할 수 있습니다.
- 학습 데이터에 과적합된 특성이 중요하게 보일 수 있습니다.
- 강하게 상관된 특성들은 중요도를 서로 나눠 가질 수 있습니다.
- 중요도는 인과효과를 뜻하지 않습니다.

따라서 모델의 예측력이 충분한지 먼저 확인한 뒤, 가능하면 검증 데이터에서 **순열 중요도**를 함께 계산합니다.

```
import pandas as pd
from sklearn.inspection import permutation_importance

result = permutation_importance(
    model,
    X_test,
    y_test,
    scoring="roc_auc",
    n_repeats=20,
    random_state=42,
    n_jobs=-1,
)

importance = pd.DataFrame({
    "feature": X_test.columns,
    "importance_mean": result.importances_mean,
    "importance_std": result.importances_std,
}).sort_values("importance_mean", ascending=False)

print(importance.head(10))
```

순열 중요도는 한 특성의 값을 섞었을 때 평가 성능이 얼마나 떨어지는지 측정합니다. 특정 모델과 특정 평가 데이터에서의 의존도를 뜻하며, 특성 자체의 보편적 가치나 인과성을 증명하지는 않습니다.

### 5.8 랜덤포레스트가 잘 맞는 경우

- 표 형태의 데이터에서 강한 기준 모델이 필요할 때
- 비선형 관계와 상호작용이 예상될 때
- 전처리 시간을 줄이고 빠르게 성능을 확인하고 싶을 때
- 단일 트리보다 안정적인 예측이 필요할 때
- 변수 중요도를 탐색적으로 확인하고 싶을 때

### 5.9 랜덤포레스트가 잘 맞지 않는 경우

- 매우 높은 차원의 희소 텍스트 데이터
- 학습 범위 밖 값을 외삽해야 하는 회귀
- 극도로 낮은 추론 지연이 필요한 환경
- 모델 용량을 매우 작게 유지해야 하는 환경
- 개별 예측을 간단한 수식 하나로 설명해야 하는 환경
- 매끄러운 확률 보정이 중요한 의사결정 문제

## 6. 네 모델을 공정하게 비교하는 방법

### 6.1 한 번의 Train/Test 분할만으로 결론 내리지 않는다

데이터를 한 번만 나누면 우연히 쉬운 테스트 세트 또는 어려운 테스트 세트가 만들어질 수 있습니다. 모델 비교에는 교차검증이 더 적합합니다.

분류에서는 클래스 비율을 유지하는 `StratifiedKFold`, 회귀에서는 `KFold`를 주로 사용합니다. 시간 순서가 있는 데이터에서는 무작위 교차검증 대신 `TimeSeriesSplit`이나 과거로 학습하고 미래를 검증하는 방식을 사용해야 합니다.

### 6.2 전처리까지 교차검증 안에 넣는다

다음 방식은 데이터 누수를 만듭니다.

```
# 잘못된 예: 전체 데이터로 평균과 표준편차를 미리 계산
X_scaled = scaler.fit_transform(X)
scores = cross_val_score(model, X_scaled, y, cv=5)
```

스케일러가 검증 폴드의 정보까지 미리 보게 됩니다. 올바른 방법은 `Pipeline`입니다.

```
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import StratifiedKFold, cross_validate
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler

pipeline = make_pipeline(
    StandardScaler(),
    LogisticRegression(max_iter=5000),
)

cv = StratifiedKFold(
    n_splits=5,
    shuffle=True,
    random_state=42,
)

scores = cross_validate(
    pipeline,
    X,
    y,
    cv=cv,
    scoring={
        "accuracy": "accuracy",
        "f1": "f1",
        "roc_auc": "roc_auc",
    },
    return_train_score=True,
)

for metric in ["test_accuracy", "test_f1", "test_roc_auc"]:
    values = scores[metric]
    print(f"{metric}: {values.mean():.3f} ± {values.std():.3f}")
```

### 6.3 로지스틱 회귀·트리·랜덤포레스트 비교 예제

```
from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import StratifiedKFold, cross_validate
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.tree import DecisionTreeClassifier

data = load_breast_cancer(as_frame=True)
X = data.data
y = data.target

models = {
    "logistic_regression": make_pipeline(
        SimpleImputer(strategy="median"),
        StandardScaler(),
        LogisticRegression(max_iter=5000, random_state=42),
    ),
    "decision_tree": make_pipeline(
        SimpleImputer(strategy="median"),
        DecisionTreeClassifier(
            max_depth=5,
            min_samples_leaf=5,
            random_state=42,
        ),
    ),
    "random_forest": make_pipeline(
        SimpleImputer(strategy="median"),
        RandomForestClassifier(
            n_estimators=500,
            min_samples_leaf=3,
            n_jobs=-1,
            random_state=42,
        ),
    ),
}

cv = StratifiedKFold(
    n_splits=5,
    shuffle=True,
    random_state=42,
)

for name, model in models.items():
    result = cross_validate(
        model,
        X,
        y,
        cv=cv,
        scoring={
            "accuracy": "accuracy",
            "f1": "f1",
            "roc_auc": "roc_auc",
        },
    )

    print(f"\n[{name}]")
    print(f"Accuracy: {result['test_accuracy'].mean():.3f}")
    print(f"F1      : {result['test_f1'].mean():.3f}")
    print(f"ROC-AUC : {result['test_roc_auc'].mean():.3f}")
```

출력값을 글에 고정해 두기보다는 실행 환경에서 재현된 결과를 기록해야 합니다. 모델 비교에서는 평균뿐 아니라 표준편차도 함께 봐야 합니다.

### 6.4 통계적 차이와 실무적 차이는 다르다

ROC-AUC가 `0.941`에서 `0.944`로 올랐다고 해도 다음을 함께 확인해야 합니다.

- 교차검증 폴드에 따라 차이가 뒤집히는가?
- 추론 속도와 메모리 비용은 얼마나 늘었는가?
- 실제 업무 비용이 줄었는가?
- 확률 보정은 좋아졌는가?
- 특정 사용자 또는 하위 집단에서 성능이 나빠지지 않았는가?
- 데이터 분포가 바뀌어도 유지되는가?

모델 선택은 점수 하나의 순위표가 아니라 **성능·비용·해석·안정성의 다목적 문제**입니다.

## 7. 평가 지표: 정확도 하나로는 부족하다

### 7.1 회귀 지표

#### MAE

```
MAE = 평균 |실제값 - 예측값|
```

원래 목표값 단위로 해석하기 쉽고 큰 이상치의 영향이 MSE보다 작습니다.

#### MSE

```
MSE = 평균 (실제값 - 예측값)²
```

큰 오차에 강한 벌점을 주지만 단위가 제곱됩니다.

#### RMSE

```
RMSE = sqrt(MSE)
```

원래 단위로 돌아오면서 큰 오차를 강조합니다.

#### R²

평균 예측 기준선보다 오차를 얼마나 줄였는지 나타냅니다. 테스트 세트에서는 음수가 될 수 있습니다.

#### MAPE 주의점

실제값이 0에 가깝거나 음수가 있으면 MAPE가 불안정하거나 해석 불가능해질 수 있습니다. 모든 회귀 문제의 기본 지표로 무조건 사용하면 안 됩니다.

### 7.2 분류 혼동행렬

| 실제 \ 예측 | 양성 | 음성 |
| --- | --- | --- |
| 양성 | TP | FN |
| 음성 | FP | TN |

- **TP**: 실제 양성을 양성으로 예측
- **FN**: 실제 양성을 놓침
- **FP**: 실제 음성을 양성으로 잘못 예측
- **TN**: 실제 음성을 음성으로 예측

### 7.3 분류 지표

#### 정확도

```
Accuracy = (TP + TN) / 전체
```

클래스가 균형적이고 오분류 비용이 비슷할 때 유용합니다.

#### 정밀도

```
Precision = TP / (TP + FP)
```

양성이라고 경고한 것 중 실제 양성의 비율입니다. 오탐 비용이 클 때 중요합니다.

#### 재현율

```
Recall = TP / (TP + FN)
```

실제 양성 중 찾아낸 비율입니다. 미탐 비용이 클 때 중요합니다.

#### F1 점수

```
F1 = 2 × Precision × Recall / (Precision + Recall)
```

정밀도와 재현율의 조화평균입니다. 하지만 TN을 직접 반영하지 않으므로 문제 맥락에 따라 한계가 있습니다.

#### ROC-AUC

모든 임계값에서 재현율과 위양성률의 관계를 요약합니다. 클래스가 매우 불균형할 때는 ROC-AUC가 낙관적으로 보일 수 있습니다.

#### PR-AUC 또는 Average Precision

양성 클래스가 희귀하고 양성 탐지가 핵심일 때 정밀도-재현율 곡선이 더 직접적인 정보를 줄 수 있습니다.

#### 로그 손실

정답 클래스에 부여한 확률을 평가합니다. 클래스만 맞히는 것보다 확률의 품질까지 중요할 때 사용합니다.

#### Brier Score

예측 확률과 실제 결과의 제곱오차를 측정합니다. 확률 보정 평가에 활용할 수 있습니다.

평가 지표를 더 깊게 보려면 [AI 모델 성능 평가 지표 완전 정복](https://doyouknow.kr/ai-model-evaluation-metrics-complete-guide2/)
을 참고하세요.

## 8. 모델 선택 가이드

### 8.1 빠른 선택표

| 상황 | 우선 검토할 모델 | 이유 |
| --- | --- | --- |
| 연속값 예측과 설명이 중요 | 선형회귀 | 계수 해석과 빠른 기준선 |
| 이진 분류와 확률 해석이 중요 | 로지스틱 회귀 | 로그 오즈·확률·빠른 추론 |
| 단순 규칙을 시각화해야 함 | 얕은 의사결정나무 | 조건문으로 설명 가능 |
| 표 데이터에서 강한 비선형 기준선 필요 | 랜덤포레스트 | 상호작용과 비선형 관계 |
| 희소한 고차원 텍스트 분류 | 로지스틱 회귀 | 선형 모델이 효율적 |
| 회귀에서 학습 범위 밖 외삽 필요 | 선형계열 우선 검토 | 트리 평균은 외삽에 약함 |
| 극도로 작은 모델 필요 | 선형·로지스틱 회귀 | 계수 벡터만 저장 |
| 클래스 불균형이 심함 | 모델보다 지표·임계값·가중치 설계 우선 | 정확도만으로 판단 불가 |

### 8.2 알고리즘 선택 순서

```
1. 목표값은 연속값인가, 클래스인가?
   ├─ 연속값: 회귀
   └─ 클래스: 분류

2. 단순하고 설명 가능한 기준 모델이 필요한가?
   ├─ 회귀: 선형회귀
   └─ 분류: 로지스틱 회귀

3. 비선형 관계나 상호작용이 강한가?
   ├─ 설명 우선: 제한된 깊이의 의사결정나무
   └─ 안정적 성능 우선: 랜덤포레스트

4. 시간 순서, 그룹, 공간 구조가 있는가?
   └─ 모델보다 먼저 올바른 데이터 분할 전략 설계

5. 오분류 비용이 비대칭인가?
   └─ 임계값, 클래스 가중치, 평가 지표 조정

6. 마지막으로 교차검증·테스트·운영 비용을 함께 비교
```

### 8.3 반드시 기준 모델부터 시작한다

처음부터 복잡한 앙상블이나 딥러닝으로 시작하면 다음을 놓치기 쉽습니다.

- 데이터 누수 여부
- 목표값 정의 오류
- 평가 지표 선택 오류
- 단순 규칙만으로 해결되는 문제
- 복잡한 모델이 실제로 만든 추가 가치

권장 순서는 다음과 같습니다.

```
단순 기준선
→ 선형 또는 로지스틱 모델
→ 단일 트리
→ 랜덤포레스트
→ 그래디언트 부스팅 또는 다른 고급 모델
```

## 9. 실전에서 자주 발생하는 오류

### 9.1 테스트 데이터로 전처리 기준까지 학습

전체 데이터 평균으로 결측치를 대체하거나 전체 데이터 평균·표준편차로 스케일링한 뒤 교차검증하면 정보 누수가 생깁니다.

**해결:** 모든 전처리를 `Pipeline` 안에 둡니다.

### 9.2 시간 데이터에 무작위 분할 사용

미래 데이터를 학습에 넣고 과거를 테스트하면 실제 배포보다 지나치게 좋은 성능이 나옵니다.

**해결:** 시간 순서를 보존하고 과거로 학습해 미래를 검증합니다.

### 9.3 같은 사람이나 장비의 데이터가 양쪽에 섞임

한 환자, 한 고객, 한 설비에서 나온 여러 행이 학습과 검증에 동시에 들어가면 모델이 개체 특성을 외울 수 있습니다.

**해결:** `GroupKFold`, `GroupShuffleSplit` 등 그룹 단위 분할을 사용합니다.

### 9.4 불균형 데이터에서 정확도만 확인

불량률이 1%라면 모든 샘플을 정상으로 예측해도 정확도는 99%입니다.

**해결:** 재현율, 정밀도, PR-AUC, 비용 기반 지표를 함께 봅니다.

### 9.5 확률 0.5를 절대적 기준으로 사용

0.5는 수학적 기본값일 뿐 업무 최적값이 아닙니다.

**해결:** 검증 데이터에서 비용과 목표 지표에 맞춰 임계값을 선택합니다.

### 9.6 변수 중요도를 인과관계로 해석

중요도는 모델이 예측에 의존한 정도이지, 변수를 바꾸면 결과가 변한다는 인과효과가 아닙니다.

**해결:** 중요도, 부분의존, SHAP, 도메인 지식, 인과 설계를 구분합니다.

### 9.7 단일 트리의 높은 훈련 점수를 신뢰

제약 없는 트리는 훈련 데이터를 거의 외울 수 있습니다.

**해결:** 교차검증과 `max_depth`, `min_samples_leaf`, 가지치기를 사용합니다.

### 9.8 스케일링의 필요성을 모델별로 혼동

- 선형회귀의 예측값 자체는 스케일링 없이도 구할 수 있습니다.
- 그러나 정규화 모델, 수치 안정성, 계수 비교에는 스케일링이 중요합니다.
- 로지스틱 회귀는 최적화와 정규화 때문에 스케일링의 이점이 큽니다.
- 트리와 랜덤포레스트는 분할 순서 기반이라 표준화가 일반적으로 필요하지 않습니다.

### 9.9 랜덤포레스트가 항상 더 좋다고 가정

랜덤포레스트는 강력한 기준 모델이지만 다음 경우 로지스틱 회귀가 더 나을 수 있습니다.

- 관계가 실제로 선형에 가까움
- 데이터가 희소하고 차원이 높음
- 학습 데이터가 적음
- 해석과 확률 보정이 중요함
- 모델 크기와 지연 시간이 중요함

## 10. 편향-분산 관점으로 네 모델 이해하기

머신러닝 모델의 오차는 직관적으로 다음 요소로 나눠 생각할 수 있습니다.

```
일반화 오차 ≈ 편향² + 분산 + 줄일 수 없는 잡음
```

### 선형회귀와 로지스틱 회귀

모델 형태가 제한되어 있어 복잡한 관계에서는 편향이 커질 수 있습니다. 반면 데이터가 조금 바뀌어도 모델이 크게 흔들리지 않아 분산은 비교적 낮은 편입니다.

### 깊은 의사결정나무

복잡한 패턴까지 맞출 수 있어 훈련 편향은 낮지만, 데이터 변화에 민감해 분산이 큽니다.

### 랜덤포레스트

여러 나무를 평균내 단일 나무의 높은 분산을 줄입니다. 다만 각 나무가 가진 계단식 예측과 외삽 한계까지 사라지는 것은 아닙니다.

이 관점은 [과적합과 과소적합](https://doyouknow.kr/overfitting-underfitting-regularization-dropout-early-stopping/)
과 연결됩니다.

## 11. 자주 묻는 질문

### Q1. 선형회귀와 로지스틱 회귀 중 어느 것이 더 좋은가요?

서로 다른 문제를 해결하므로 직접적인 우열 관계가 아닙니다.

- 연속값 예측: 선형회귀
- 클래스 또는 클래스 확률 예측: 로지스틱 회귀

### Q2. 로지스틱 회귀는 왜 회귀라는 이름을 쓰나요?

클래스 자체를 직접 회귀하는 것이 아니라 입력 특성으로 로그 오즈를 선형 모델링하기 때문입니다. 최종 용도는 분류입니다.

### Q3. 선형 모델도 비선형 관계를 학습할 수 있나요?

원래 특성에 다항항, 상호작용항, 로그 변환, 스플라인 등을 추가하면 변환된 특성 공간에서는 선형 모델을 유지하면서 원래 입력에 대한 비선형 관계를 표현할 수 있습니다.

### Q4. 트리 모델에는 표준화가 정말 필요 없나요?

대부분의 일반적인 결정 트리와 랜덤포레스트는 값의 대소 순서로 분할하므로 표준화의 영향이 거의 없습니다. 하지만 전처리 파이프라인 전체에서 결측치, 인코딩, 데이터 타입 정리는 여전히 필요합니다.

### Q5. 랜덤포레스트는 과적합하지 않나요?

단일 깊은 나무보다 과적합 위험을 줄이는 경우가 많지만 과적합이 불가능한 것은 아닙니다. 노이즈 특성이 많거나 리프가 지나치게 작고 데이터가 적으면 학습 패턴을 과도하게 따라갈 수 있습니다.

### Q6. 랜덤포레스트의 나무는 몇 개가 적당한가요?

고정된 정답은 없습니다. 나무 수를 늘리며 검증 성능, 분산, 학습 시간, 메모리가 안정되는 구간을 확인해야 합니다. 나무를 늘리는 것은 대개 과적합을 급격히 키우기보다 계산 비용을 늘리는 방향으로 작용하지만, 다른 복잡도 파라미터도 함께 조정해야 합니다.

### Q7. 정확도와 ROC-AUC 중 무엇을 사용해야 하나요?

정확도는 하나의 임계값에서 최종 클래스 결과를 평가합니다. ROC-AUC는 여러 임계값에서 순위 구분 능력을 요약합니다. 실제 운영 임계값의 비용이 중요하다면 정밀도, 재현율, 혼동행렬, 비용 함수도 반드시 함께 봐야 합니다.

### Q8. 모델이 출력한 80% 확률은 정말 80%인가요?

반드시 그렇지는 않습니다. 비슷한 샘플 100개 중 실제로 약 80개가 양성이 되는지 확인하는 확률 보정 평가가 필요합니다. 랜덤포레스트와 깊은 트리의 확률은 특히 보정이 필요할 수 있습니다.

### Q9. 변수 중요도가 낮으면 특성을 바로 삭제해도 되나요?

바로 삭제하면 안 됩니다. 상관된 특성끼리 중요도를 나눠 갖거나 모델이 좋지 않아 모든 중요도가 낮게 보일 수 있습니다. 교차검증 성능과 순열 중요도, 도메인 지식을 함께 확인해야 합니다.

### Q10. 네 모델만으로 실무를 할 수 있나요?

많은 표 데이터 문제의 기준선과 초기 제품에는 충분히 유용합니다. 다만 최고 성능이 필요하다면 그래디언트 부스팅, 범주형 특화 모델, 시계열 모델, 신경망 등도 비교해야 합니다. 중요한 것은 더 복잡한 모델을 쓰는 것이 아니라 검증된 추가 가치를 확인하는 것입니다.

## 12. 마무리

선형회귀와 로지스틱 회귀는 단순하지만 빠르고 해석 가능한 강력한 기준 모델입니다. 의사결정나무는 사람이 이해하기 쉬운 규칙으로 비선형 관계를 학습하지만, 깊어질수록 불안정하고 과적합되기 쉽습니다. 랜덤포레스트는 여러 나무를 결합해 이러한 분산을 줄이며 표 데이터에서 안정적인 기준 모델로 자주 사용됩니다.

네 알고리즘을 한 문장씩 정리하면 다음과 같습니다.

- **선형회귀:** 연속값을 입력 특성의 가중합으로 예측한다.
- **로지스틱 회귀:** 선형 점수를 확률로 바꾸고 임계값으로 클래스를 결정한다.
- **의사결정나무:** 조건을 반복해 데이터 공간을 나누고 리프에서 예측한다.
- **랜덤포레스트:** 서로 다른 여러 나무의 결과를 평균 또는 투표해 안정성을 높인다.

실무에서는 어떤 모델을 선택했는지보다 다음이 더 중요합니다.

```
올바른 목표 정의
→ 누수 없는 데이터 분할
→ 적절한 전처리
→ 업무 비용에 맞는 평가 지표
→ 교차검증
→ 최종 테스트
→ 배포 후 분포 변화 감시
```

## 같이 보면 좋은 글

- [AI 모델 성능 평가 지표 완전 정복: Accuracy·F1부터 LLM·RAG 평가까지](https://doyouknow.kr/ai-model-evaluation-metrics-complete-guide2/)
- [특성 공학 완전 정복: 선택·추출·PCA·정규화](https://doyouknow.kr/feature-engineering-selection-extraction-pca-normalization/)
- [손실함수 완전 정복: MSE·Cross-Entropy부터 Focal·Huber Loss까지](https://doyouknow.kr/loss-function-complete-guide2/)
- [과적합과 과소적합: 편향·분산과 정규화](https://doyouknow.kr/overfitting-underfitting-regularization-dropout-early-stopping/)
- [모델 학습과 최적화: 경사하강법·역전파·학습률](https://doyouknow.kr/ai-model-training-optimization-loss-gradient-descent-backpropagation2/)
- [데이터셋 구성의 모든 것: 수집·분할·불균형·데이터 누수](https://doyouknow.kr/ai-dataset-preparation-train-validation-test-labeling2/)
- [AI 가이드 인덱스](https://doyouknow.kr/ai-guide-index/)

## 외부 참고 자료

- [scikit-learn: Linear Models](https://scikit-learn.org/stable/modules/linear_model.html)
- [scikit-learn: Decision Trees](https://scikit-learn.org/stable/modules/tree.html)
- [scikit-learn: RandomForestClassifier](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html)
- [scikit-learn: Metrics and scoring](https://scikit-learn.org/stable/modules/model_evaluation.html)
- [scikit-learn: Tuning the decision threshold](https://scikit-learn.org/stable/modules/classification_threshold.html)
- [scikit-learn: Probability calibration](https://scikit-learn.org/stable/modules/calibration.html)
- [scikit-learn: Permutation feature importance](https://scikit-learn.org/stable/modules/permutation_importance.html)
- [Breiman, Random Forests, Machine Learning 45, 2001](https://doi.org/10.1023/A:1010933404324)

### 이 글 공유하기:

- [Facebook으로 공유하기 (새 창에서 열림)Facebook](https://doyouknow.kr/ml-algorithms-linear-logistic-regression-decision-tree-random-forest2/?share=facebook)
- [X에 공유 (새 창에서 열림)X](https://doyouknow.kr/ml-algorithms-linear-logistic-regression-decision-tree-random-forest2/?share=x)
-

### 이것이 좋아요:

좋아하기로드 중...

### *관련*

### 관련된 글:

1. [[AI 101] 선형회귀와 분류 – 모든 머신러닝 알고리즘의 시작점](https://doyouknow.kr/ml-algorithms-linear-logistic-regression-decision-tree-random-forest/)
2. [[AI 101] AI는 어떻게 학습할까? 머신러닝의 3가지 학습 방법 완벽 가이드](https://doyouknow.kr/machine-learning-three-types-supervised-unsupervised-reinforcement/)
3. [AI 학습의 숨은 심판관, 손실함수 완전 정복: MSE·Cross-Entropy부터 Focal·Dice·LLM 손실까지](https://doyouknow.kr/loss-function-complete-guide2/)
4. [[AI 101] AI 개발의 첫걸음 – Python이 AI의 표준 언어가 된 이유](https://doyouknow.kr/python-ai-development-tensorflow-pytorch-colab/)

### 댓글 남기기[응답 취소](/ml-algorithms-linear-logistic-regression-decision-tree-random-forest2/?t=1785800579#respond)
