본문으로 건너뛰기

036 회귀 문제란?

키워드: 회귀, regression, 연속값 예측

개요

회귀(Regression)는 연속적인 수치 값을 예측하는 머신러닝 문제입니다. 분류가 "어떤 클래스인가?"를 예측한다면, 회귀는 "얼마인가?"를 예측합니다. 이 글에서는 회귀 문제의 기본 개념과 FLAML에서의 활용법을 알아봅니다.

실습 환경

  • Python 버전: 3.11 권장
  • 필요 패키지: flaml[automl], scikit-learn, pandas
pip install flaml[automl] scikit-learn pandas matplotlib

분류 vs 회귀

핵심 차이

import numpy as np
import pandas as pd

# 036 분류: 이산적인 클래스 예측
classification_examples = {
'문제': ['스팸 여부', '질병 진단', '고객 이탈'],
'출력': ['스팸/정상', '양성/음성', '이탈/유지'],
'타입': ['이산값', '이산값', '이산값']
}

# 036 회귀: 연속적인 값 예측
regression_examples = {
'문제': ['주택 가격', '매출 예측', '온도 예측'],
'출력': ['350,000,000원', '1,234,567원', '25.3°C'],
'타입': ['연속값', '연속값', '연속값']
}

print("분류 문제:")
print(pd.DataFrame(classification_examples))
print("\n회귀 문제:")
print(pd.DataFrame(regression_examples))

출력 비교

import matplotlib.pyplot as plt

# 036 분류: 확률 분포
fig, axes = plt.subplots(1, 2, figsize=(12, 4))

# 036 분류 출력
classes = ['Class 0', 'Class 1']
probs = [0.3, 0.7]
axes[0].bar(classes, probs, color=['blue', 'orange'])
axes[0].set_ylabel('Probability')
axes[0].set_title('Classification Output (Discrete)')
axes[0].set_ylim(0, 1)

# 036 회귀 출력
x = np.linspace(100000, 500000, 100)
y = np.exp(-((x - 300000) ** 2) / (2 * 50000 ** 2))
axes[1].plot(x, y, 'g-', linewidth=2)
axes[1].axvline(x=300000, color='r', linestyle='--', label='Prediction')
axes[1].set_xlabel('House Price')
axes[1].set_ylabel('Density')
axes[1].set_title('Regression Output (Continuous)')
axes[1].legend()

plt.tight_layout()
plt.show()

회귀의 종류

1. 단순 선형 회귀

from sklearn.linear_model import LinearRegression
import numpy as np
import matplotlib.pyplot as plt

# 036 데이터 생성
np.random.seed(42)
X = np.random.rand(100, 1) * 10
y = 2.5 * X.flatten() + 10 + np.random.randn(100) * 2

# 036 선형 회귀
model = LinearRegression()
model.fit(X, y)

print("단순 선형 회귀:")
print(f" y = {model.coef_[0]:.2f} * x + {model.intercept_:.2f}")

# 036 시각화
plt.figure(figsize=(8, 6))
plt.scatter(X, y, alpha=0.5, label='Data')
plt.plot(X, model.predict(X), 'r-', linewidth=2, label='Prediction')
plt.xlabel('X')
plt.ylabel('y')
plt.title('Simple Linear Regression')
plt.legend()
plt.show()

2. 다중 회귀

# 036 여러 특성으로 예측
from sklearn.datasets import make_regression

X_multi, y_multi = make_regression(
n_samples=100,
n_features=5,
n_informative=3,
noise=10,
random_state=42
)

model_multi = LinearRegression()
model_multi.fit(X_multi, y_multi)

print("다중 회귀:")
print(f" 특성 수: {X_multi.shape[1]}")
print(f" 계수: {model_multi.coef_.round(2)}")
print(f" 절편: {model_multi.intercept_:.2f}")

3. 비선형 회귀

# 036 트리 기반 모델은 비선형 관계도 학습
from sklearn.ensemble import RandomForestRegressor

# 036 비선형 데이터
X_nonlinear = np.linspace(0, 10, 100).reshape(-1, 1)
y_nonlinear = np.sin(X_nonlinear).flatten() + np.random.randn(100) * 0.1

# 036 랜덤 포레스트
rf = RandomForestRegressor(n_estimators=100, random_state=42)
rf.fit(X_nonlinear, y_nonlinear)

plt.figure(figsize=(8, 6))
plt.scatter(X_nonlinear, y_nonlinear, alpha=0.5, label='Data')
plt.plot(X_nonlinear, rf.predict(X_nonlinear), 'r-', linewidth=2, label='RF Prediction')
plt.xlabel('X')
plt.ylabel('y')
plt.title('Non-linear Regression with Random Forest')
plt.legend()
plt.show()

FLAML로 회귀 문제 해결

기본 사용법

from flaml import AutoML
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split

# 036 캘리포니아 주택 데이터
data = fetch_california_housing()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = data.target

print("캘리포니아 주택 데이터:")
print(f" 샘플 수: {len(X)}")
print(f" 특성 수: {X.shape[1]}")
print(f" 타겟 범위: {y.min():.2f} ~ {y.max():.2f}")

# 036 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)

# 036 FLAML AutoML (회귀)
automl = AutoML()
automl.fit(
X_train, y_train,
task="regression", # 회귀 태스크
time_budget=60,
metric="r2", # R² 최적화
verbose=1
)

print(f"\n최적 모델: {automl.best_estimator}")
print(f"검증 R²: {1 - automl.best_loss:.4f}")

예측 및 평가

from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score

# 036 예측
y_pred = automl.predict(X_test)

# 036 평가
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

print("회귀 평가 결과:")
print(f" MSE: {mse:.4f}")
print(f" RMSE: {rmse:.4f}")
print(f" MAE: {mae:.4f}")
print(f" R²: {r2:.4f}")

회귀 vs 분류 설정 비교

# 036 분류 설정
automl_clf = AutoML()
# 036 automl_clf.fit(X, y, task="classification", metric="accuracy")

# 036 회귀 설정
automl_reg = AutoML()
# 036 automl_reg.fit(X, y, task="regression", metric="r2")

comparison = pd.DataFrame({
'항목': ['task', '주요 metric', 'predict 출력', '평가 함수'],
'분류': ['classification', 'accuracy, f1, roc_auc', '클래스 레이블', 'accuracy_score, f1_score'],
'회귀': ['regression', 'r2, mse, mae', '연속 수치', 'r2_score, mean_squared_error']
})

print("분류 vs 회귀 설정 비교:")
print(comparison.to_string(index=False))

회귀 문제 예시

# 036 실제 회귀 문제 예시
regression_problems = {
'도메인': ['부동산', '금융', '에너지', '의료', '마케팅', '제조'],
'문제': [
'주택 가격 예측',
'주가 예측',
'전력 수요 예측',
'환자 재원 기간 예측',
'고객 생애 가치 예측',
'제품 불량률 예측'
],
'타겟': ['가격(원)', '주가(원)', '전력량(kWh)', '일수', '금액(원)', '비율(%)']
}

print("회귀 문제 예시:")
print(pd.DataFrame(regression_problems).to_string(index=False))

정리

  • 회귀는 연속적인 수치 값을 예측하는 문제입니다.
  • FLAML에서 task="regression"으로 설정합니다.
  • 주요 평가 지표: MSE, RMSE, MAE, R²
  • 선형 회귀부터 트리 기반 모델까지 다양한 알고리즘을 자동 탐색합니다.
  • 분류와 달리 연속적인 수치를 출력합니다.

다음 글 예고

다음 글에서는 회귀 평가 지표 상세에 대해 알아보겠습니다. MSE, RMSE, MAE, R², MAPE 등 다양한 회귀 평가 지표의 의미와 선택 기준을 다룹니다.


FLAML AutoML 마스터 시리즈 #036