콘텐츠로 이동

Support Vector Regression (SVR)

논문 정보

항목 내용
제목 Support Vector Regression Machines
저자 Harris Drucker, Christopher J.C. Burges, Linda Kaufman, Alex Smola, Vladimir Vapnik
학회/저널 Advances in Neural Information Processing Systems (NIPS)
연도 1996
링크 https://proceedings.neurips.cc/paper/1996/hash/d38901788c533e8286cb6400b40b386d-Abstract.html

개요

문제 정의

회귀 문제에 Support Vector Machine의 개념을 적용:

  • 일반 회귀: 예측값과 실제값 차이를 최소화
  • SVR: epsilon-tube 내의 오차는 무시하고, 밖의 오차만 최소화
  • 목표: 모든 학습 데이터가 epsilon 범위 내에 있으면서 가장 평평한(flat) 함수 찾기

핵심 아이디어

epsilon-insensitive loss function:

L_epsilon(y, f(x)) = max(0, |y - f(x)| - epsilon)
  • epsilon 이내의 오차: 손실 0 (무시)
  • epsilon 초과 오차: 선형적으로 페널티
  • 이 손실 함수로 희소한(sparse) 해를 얻음

Structural Risk Minimization: - 경험적 위험 + 모델 복잡도 동시 최소화 - 과적합 방지 및 일반화 성능 향상

알고리즘/방법론

수식

Primal Formulation:

minimize:    (1/2)||w||^2 + C * sum_i (xi_i + xi_i*)

subject to:  y_i - (w . x_i + b) <= epsilon + xi_i
             (w . x_i + b) - y_i <= epsilon + xi_i*
             xi_i, xi_i* >= 0

여기서: - w: 가중치 벡터 - b: 편향 - C: 정규화 파라미터 (오차 허용도) - epsilon: 튜브 폭 - xi, xi*: slack 변수 (epsilon 초과 오차)

Dual Formulation:

maximize:    -1/2 * sum_{i,j} (alpha_i - alpha_i*)(alpha_j - alpha_j*) K(x_i, x_j)
             - epsilon * sum_i (alpha_i + alpha_i*)
             + sum_i y_i (alpha_i - alpha_i*)

subject to:  sum_i (alpha_i - alpha_i*) = 0
             0 <= alpha_i, alpha_i* <= C

예측 함수:

f(x) = sum_i (alpha_i - alpha_i*) K(x_i, x) + b

커널 함수

커널 수식 특징
Linear K(x, x') = x . x' 선형 관계
RBF (Gaussian) K(x, x') = exp(-gamma ||x-x'||^2) 비선형, 범용
Polynomial K(x, x') = (gamma * x . x' + r)^d 다항 관계
Sigmoid K(x, x') = tanh(gamma * x . x' + r) 신경망 유사

단계별 설명

Algorithm: SVR Training

Input: 학습 데이터 {(x_i, y_i)}, 파라미터 C, epsilon, kernel
Output: 예측 함수 f(x)

1. Construct kernel matrix
   K_ij = K(x_i, x_j) for all i, j

2. Solve dual QP problem
   - Quadratic programming으로 alpha, alpha* 최적화
   - SMO (Sequential Minimal Optimization) 알고리즘 사용

3. Identify support vectors
   - alpha_i > 0 또는 alpha_i* > 0인 샘플
   - epsilon-tube 경계 또는 바깥에 위치

4. Compute bias term b
   - KKT 조건 활용
   - 0 < alpha_i < C인 서포트 벡터로 계산

5. Prediction
   f(x) = sum_{SV} (alpha_i - alpha_i*) K(x_i, x) + b

시간 복잡도

단계 복잡도
커널 행렬 계산 O(n^2 * d)
QP 최적화 (SMO) O(n^2) ~ O(n^3)
예측 (단일 샘플) O(n_sv * d)

주요 결과

논문의 실험 결과

Boston Housing 데이터셋:

방법 Mean Squared Error
Ridge Regression 24.3
Bagging Trees 12.1
SVR (RBF) 8.4

Sinc 함수 근사:

방법 Support Vectors MSE
SVR epsilon=0.1 45 0.0012
SVR epsilon=0.01 112 0.0003

이론적 특성

  1. Sparsity: 학습 데이터 중 일부만 support vector로 사용
  2. Generalization: VC 차원 기반 일반화 한계 존재
  3. Global Optimum: Convex 최적화로 전역 최적해 보장

실전 적용 가이드

언제 사용하나

  1. 중소규모 데이터셋: n < 10,000에서 효과적
  2. 비선형 관계: RBF 커널로 복잡한 패턴 학습
  3. 이상치 존재: epsilon-insensitive loss로 로버스트
  4. 고차원 데이터: 커널 트릭으로 효율적 처리

하이퍼파라미터

파라미터 설명 권장 범위 튜닝 방법
C 정규화 강도 (높을수록 오차에 민감) 0.1 ~ 1000 Grid search, log scale
epsilon 튜브 폭 (높을수록 관대) 0.01 ~ 1.0 타겟 노이즈 수준 참고
gamma (RBF) 커널 폭 (높을수록 복잡) 1/n_features ~ 10 Grid search
degree (Poly) 다항식 차수 2 ~ 5 도메인 지식

파라미터 선택 가이드라인

C 튜닝:
- C 낮음: 과소적합, 단순한 모델
- C 높음: 과적합, 모든 점 맞추려 함

epsilon 튜닝:
- epsilon 낮음: 정밀한 예측, support vector 많음
- epsilon 높음: 관대한 예측, support vector 적음

gamma (RBF) 튜닝:
- gamma 낮음: 부드러운 결정 경계
- gamma 높음: 복잡한 결정 경계, 과적합 위험

주의사항

  1. 스케일링 필수: 특성 스케일에 민감. StandardScaler 또는 MinMaxScaler 적용 필수.

  2. 대규모 데이터: n > 10,000이면 계산 비용 급증. LinearSVR 또는 다른 알고리즘 고려.

  3. 커널 선택:

  4. 먼저 RBF 시도
  5. 선형 관계 의심시 Linear 커널
  6. 도메인 지식 있으면 Polynomial

  7. 메모리: 커널 행렬이 O(n^2) 메모리 사용.

Python 코드 예시

import numpy as np
from sklearn.svm import SVR
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
from sklearn.datasets import fetch_california_housing
import matplotlib.pyplot as plt

# 데이터 로드
data = fetch_california_housing()
X, y = data.data[:2000], data.target[:2000]  # 계산 시간을 위해 서브샘플

# Train/test split
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# 스케일링 (필수)
scaler_X = StandardScaler()
scaler_y = StandardScaler()

X_train_scaled = scaler_X.fit_transform(X_train)
X_test_scaled = scaler_X.transform(X_test)
y_train_scaled = scaler_y.fit_transform(y_train.reshape(-1, 1)).ravel()

# SVR 모델 학습
svr = SVR(
    kernel='rbf',
    C=100,
    epsilon=0.1,
    gamma='scale'
)
svr.fit(X_train_scaled, y_train_scaled)

# 예측
y_pred_scaled = svr.predict(X_test_scaled)
y_pred = scaler_y.inverse_transform(y_pred_scaled.reshape(-1, 1)).ravel()

# 평가
print("=== SVR Performance ===")
print(f"R2 Score: {r2_score(y_test, y_pred):.4f}")
print(f"MSE: {mean_squared_error(y_test, y_pred):.4f}")
print(f"RMSE: {np.sqrt(mean_squared_error(y_test, y_pred)):.4f}")
print(f"MAE: {mean_absolute_error(y_test, y_pred):.4f}")
print(f"Number of support vectors: {svr.n_support_.sum()}")
print(f"Support vector ratio: {svr.n_support_.sum() / len(X_train):.2%}")

# 시각화
plt.figure(figsize=(10, 4))

plt.subplot(1, 2, 1)
plt.scatter(y_test, y_pred, alpha=0.5)
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--')
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.title('SVR: Actual vs Predicted')

plt.subplot(1, 2, 2)
residuals = y_test - y_pred
plt.hist(residuals, bins=30, edgecolor='black')
plt.xlabel('Residual')
plt.ylabel('Frequency')
plt.title('Residual Distribution')

plt.tight_layout()
plt.savefig('svr_result.png', dpi=150)
plt.show()

하이퍼파라미터 튜닝

from sklearn.model_selection import GridSearchCV

# 파라미터 그리드
param_grid = {
    'C': [0.1, 1, 10, 100],
    'epsilon': [0.01, 0.1, 0.5],
    'gamma': ['scale', 'auto', 0.01, 0.1]
}

# Grid Search
svr = SVR(kernel='rbf')
grid_search = GridSearchCV(
    svr,
    param_grid,
    cv=5,
    scoring='neg_mean_squared_error',
    n_jobs=-1,
    verbose=1
)

grid_search.fit(X_train_scaled, y_train_scaled)

print("\n=== Grid Search Results ===")
print(f"Best parameters: {grid_search.best_params_}")
print(f"Best CV score (neg MSE): {grid_search.best_score_:.4f}")

# 최적 모델로 예측
best_svr = grid_search.best_estimator_
y_pred_best = scaler_y.inverse_transform(
    best_svr.predict(X_test_scaled).reshape(-1, 1)
).ravel()

print(f"\nTest R2 with best model: {r2_score(y_test, y_pred_best):.4f}")

커널 비교

# 여러 커널 비교
kernels = ['linear', 'rbf', 'poly']
results = {}

for kernel in kernels:
    svr = SVR(kernel=kernel, C=10, epsilon=0.1)
    svr.fit(X_train_scaled, y_train_scaled)

    y_pred = scaler_y.inverse_transform(
        svr.predict(X_test_scaled).reshape(-1, 1)
    ).ravel()

    results[kernel] = {
        'r2': r2_score(y_test, y_pred),
        'rmse': np.sqrt(mean_squared_error(y_test, y_pred)),
        'n_sv': svr.n_support_.sum()
    }

print("\n=== Kernel Comparison ===")
print(f"{'Kernel':<10} {'R2':>8} {'RMSE':>8} {'#SV':>8}")
print("-" * 36)
for kernel, metrics in results.items():
    print(f"{kernel:<10} {metrics['r2']:>8.4f} {metrics['rmse']:>8.4f} {metrics['n_sv']:>8}")

대규모 데이터용 LinearSVR

from sklearn.svm import LinearSVR

# 대규모 데이터에서 빠른 학습
linear_svr = LinearSVR(
    epsilon=0.1,
    C=1.0,
    max_iter=10000,
    dual=True
)
linear_svr.fit(X_train_scaled, y_train_scaled)

y_pred_linear = scaler_y.inverse_transform(
    linear_svr.predict(X_test_scaled).reshape(-1, 1)
).ravel()

print(f"\nLinearSVR R2: {r2_score(y_test, y_pred_linear):.4f}")

관련 기법

비교

기법 장점 단점 적합 상황
SVR 비선형, 로버스트 느림, 파라미터 민감 중소규모, 비선형
Linear Regression 빠름, 해석 가능 선형만 선형 관계
Random Forest 빠름, 로버스트 외삽 불가 범용
Gradient Boosting 높은 성능 과적합 위험 대회, 복잡한 패턴
Neural Network 매우 유연 데이터/계산 필요 대규모 데이터

대안 기법

  1. Kernel Ridge Regression
  2. SVR과 유사하나 모든 데이터 사용
  3. Closed-form solution 존재
  4. Sparsity 없음

  5. Gaussian Process Regression

  6. 불확실성 추정 가능
  7. 자동 하이퍼파라미터 최적화 (MLE)
  8. 계산 비용 O(n^3)

  9. nu-SVR

  10. epsilon 대신 nu 파라미터 사용
  11. nu: support vector 비율의 하한
  12. epsilon 자동 결정

  13. Relevance Vector Machine (RVM)

  14. Bayesian SVR 변형
  15. 더 희소한 해
  16. 불확실성 추정 가능

참고 문헌

  • Smola, A.J., & Scholkopf, B. (2004). "A tutorial on support vector regression". Statistics and Computing.
  • Vapnik, V. (1995). "The Nature of Statistical Learning Theory". Springer.
  • Chang, C.C., & Lin, C.J. (2011). "LIBSVM: A library for support vector machines". ACM TIST.