본문으로 건너뛰기

044 회귀 평가 지표 - R², MAPE

키워드: R2, MAPE

개요

R²와 MAPE는 MAE/RMSE와 다른 관점에서 모델 성능을 평가합니다. R²는 설명력을, MAPE는 백분율 오차를 측정합니다.

실습 환경

  • Python 버전: 3.11 권장
  • 필요 패키지: pycaret[full]>=3.0

R² (R-squared, 결정 계수)

모델이 타겟 변동을 얼마나 설명하는지 측정:

R² = 1 - (SS_res / SS_tot)
= 1 - [Σ(yᵢ - ŷᵢ)² / Σ(yᵢ - ȳ)²]
  • SS_res: 잔차 제곱합 (모델 오차)
  • SS_tot: 총 제곱합 (타겟 변동)
import numpy as np
from sklearn.metrics import r2_score

y_true = np.array([100, 150, 200, 250, 300])
y_pred = np.array([110, 140, 210, 240, 295])

# 044 R² 계산
y_mean = y_true.mean()
ss_res = np.sum((y_true - y_pred) ** 2)
ss_tot = np.sum((y_true - y_mean) ** 2)
r2 = 1 - (ss_res / ss_tot)

print(f"R²: {r2:.4f}") # 0.982

# 044 sklearn으로 확인
r2_sklearn = r2_score(y_true, y_pred)
print(f"R² (sklearn): {r2_sklearn:.4f}")

R² 해석

R² 값해석
1.0완벽한 예측
0.9+매우 좋음
0.7-0.9좋음
0.5-0.7보통
0.3-0.5약함
< 0.3나쁨
음수평균보다 못함
# 044 R² 해석 예시
print("R² 해석:")
print(" R²=0.85는 모델이 타겟 변동의 85%를 설명한다는 의미")
print(" 나머지 15%는 설명되지 않는 변동 (노이즈, 누락된 특성 등)")

R²의 한계

1. 음수가 될 수 있음

y_true = np.array([10, 20, 30])
y_pred = np.array([100, 100, 100]) # 매우 나쁜 예측

r2 = r2_score(y_true, y_pred)
print(f"R² (나쁜 모델): {r2:.4f}") # 음수

# 044 평균으로 예측하는 것보다 못하면 R² < 0

2. 스케일에 독립적

# 044 동일한 R², 다른 절대 오차
y_true_small = np.array([1, 2, 3, 4, 5])
y_pred_small = np.array([1.1, 1.9, 3.1, 3.9, 5.1])

y_true_large = y_true_small * 1000
y_pred_large = y_pred_small * 1000

print(f"작은 스케일 R²: {r2_score(y_true_small, y_pred_small):.4f}")
print(f"큰 스케일 R²: {r2_score(y_true_large, y_pred_large):.4f}")
# 044 동일한 R²이지만 절대 오차는 1000배 차이

MAPE (Mean Absolute Percentage Error)

백분율 오차의 평균:

MAPE = (100/n) × Σ|(yᵢ - ŷᵢ) / yᵢ|
from sklearn.metrics import mean_absolute_percentage_error

y_true = np.array([100, 150, 200, 250, 300])
y_pred = np.array([110, 140, 210, 240, 295])

# 044 MAPE 계산
mape = np.mean(np.abs((y_true - y_pred) / y_true)) * 100
print(f"MAPE: {mape:.2f}%") # 5.07%

# 044 sklearn
mape_sklearn = mean_absolute_percentage_error(y_true, y_pred) * 100
print(f"MAPE (sklearn): {mape_sklearn:.2f}%")

MAPE 해석

MAPE해석
< 10%매우 정확
10-20%좋음
20-50%보통
> 50%부정확
# 044 비즈니스 해석
mape = 8.5
print(f"MAPE {mape}%는 평균적으로 예측이 실제값의 {mape}% 정도 벗어난다는 의미")
print(f"예: 실제 가격 $100일 때, 예측은 $91.5 ~ $108.5 범위")

MAPE의 한계

1. 0에 가까운 값에서 폭발

y_true = np.array([0.001, 10, 20])
y_pred = np.array([0.002, 11, 19])

# 0에 가까운 값이 있으면 MAPE 폭발
mape = np.mean(np.abs((y_true - y_pred) / y_true)) * 100
print(f"MAPE (0 포함): {mape:.2f}%") # 매우 큰 값

2. 비대칭성

# 044 과대 예측과 과소 예측의 비대칭
y_true = np.array([100, 100])
y_pred_over = np.array([200, 200]) # 2배 과대 예측
y_pred_under = np.array([50, 50]) # 절반 과소 예측

mape_over = mean_absolute_percentage_error(y_true, y_pred_over) * 100
mape_under = mean_absolute_percentage_error(y_true, y_pred_under) * 100

print(f"과대 예측 MAPE: {mape_over}%") # 100%
print(f"과소 예측 MAPE: {mape_under}%") # 50%
# 044 같은 비율이지만 MAPE가 다름

PyCaret에서 R², MAPE 사용

from pycaret.regression import *
from pycaret.datasets import get_data

data = get_data('boston')
reg = setup(data, target='medv', session_id=42, verbose=False)

# 044 모델 생성
model = create_model('rf', verbose=False)
results = pull()

print("평가 지표:")
print(f"R²: {results['R2'].mean():.4f}")
print(f"MAPE: {results['MAPE'].mean():.4f}")

# 044 R² 기준 최적 모델
best_r2 = compare_models(sort='R2', n_select=1)

# 044 튜닝도 R² 기준
tuned = tune_model(model, optimize='R2')

지표 비교 종합

from pycaret.regression import *
from pycaret.datasets import get_data
import pandas as pd

data = get_data('boston')
reg = setup(data, target='medv', session_id=42, verbose=False)

# 044 여러 모델 비교
models_to_compare = ['lr', 'rf', 'xgboost', 'lightgbm']

results = []
for model_name in models_to_compare:
model = create_model(model_name, verbose=False)
metrics = pull()

results.append({
'Model': model_name,
'MAE': metrics['MAE'].mean(),
'RMSE': metrics['RMSE'].mean(),
'R2': metrics['R2'].mean(),
'MAPE': metrics['MAPE'].mean()
})

df = pd.DataFrame(results)
print("\n모델별 지표 비교:")
print(df.round(4))

지표 선택 가이드

상황권장 지표
모델 설명력 평가
비즈니스 보고MAPE
이상치 있음MAE
큰 오차 중시RMSE
0 근처 값 있음MAE, RMSE (MAPE 피함)
다른 스케일 비교MAPE, R²

정리

  • : 모델의 설명력 (0~1, 음수 가능)
  • MAPE: 백분율 오차, 비즈니스 해석 용이
  • R²가 높아도 절대 오차가 클 수 있음
  • MAPE는 0에 가까운 값에서 문제
  • 단일 지표가 아닌 여러 지표 종합 평가 권장

다음 글 예고

다음 글에서는 선형 회귀 상세를 다룹니다.


PyCaret 머신러닝 마스터 시리즈 #044