033 SVM 분류 상세
키워드: SVM, svc
개요
SVM(Support Vector Machine)은 결정 경계와 가장 가까운 데이터 포인트(서포트 벡터)를 기반으로 분류하는 알고리즘입니다. 커널 트릭을 통해 비선형 분류도 가능합니다.
실습 환경
- Python 버전: 3.11 권장
- 필요 패키지:
pycaret[full]>=3.0
SVM 원리
- 마진 최대화: 클래스 간 거리(마진)를 최대화하는 초평면 찾기
- 서포트 벡터: 결정 경계에 가장 가까운 데이터 포인트
- 커널 트릭: 고차원 공간으로 매핑하여 비선형 분류
PyCaret에서 SVM
from pycaret.classification import *
from pycaret.datasets import get_data
# 033 데이터 로드
data = get_data('diabetes')
clf = setup(data, target='Class variable', session_id=42, verbose=False)
# 033 Linear SVM
svm_linear = create_model('svm')
# 033 RBF SVM
svm_rbf = create_model('rbfsvm')
주요 하이퍼파라미터
C (정규화)
# 033 C: 오분류 허용 정도 (작을수록 마진 넓음, 오분류 허용)
svm_c1 = create_model('svm', C=1.0) # 기본값
svm_c01 = create_model('svm', C=0.1) # 소프트 마진
svm_c10 = create_model('svm', C=10.0) # 하드 마진
커널
# 033 kernel: 커널 함수 종류
svm_linear = create_model('rbfsvm', kernel='linear')
svm_rbf = create_model('rbfsvm', kernel='rbf') # 기본값
svm_poly = create_model('rbfsvm', kernel='poly')
svm_sigmoid = create_model('rbfsvm', kernel='sigmoid')
gamma (RBF, Poly, Sigmoid)
# 033 gamma: 커널 계수 (높을수록 복잡한 결정 경계)
svm_gamma_auto = create_model('rbfsvm', gamma='auto')
svm_gamma_scale = create_model('rbfsvm', gamma='scale') # 기본값
svm_gamma_01 = create_model('rbfsvm', gamma=0.1)
Polynomial 커널 파라미터
# 033 degree: 다항식 차수
svm_poly = create_model('rbfsvm', kernel='poly', degree=3)
# 033 coef0: 독립항
svm_poly = create_model('rbfsvm', kernel='poly', coef0=0.0)
커널 비교
from pycaret.classification import *
from pycaret.datasets import get_data
import pandas as pd
data = get_data('iris')
clf = setup(data, target='species', session_id=42, verbose=False)
kernels = ['linear', 'rbf', 'poly', 'sigmoid']
results = []
for kernel in kernels:
svm = create_model('rbfsvm', kernel=kernel, verbose=False)
metrics = pull()
results.append({
'kernel': kernel,
'accuracy': metrics['Accuracy'].mean(),
'auc': metrics['AUC'].mean()
})
df = pd.DataFrame(results)
print(df)
스케일링의 중요성
SVM은 거리 기반이므로 스케일링 필수:
from pycaret.classification import *
from pycaret.datasets import get_data
data = get_data('diabetes')
# 033 스케일링 없이
clf1 = setup(data, target='Class variable', normalize=False, session_id=42, verbose=False)
svm1 = create_model('rbfsvm', verbose=False)
results1 = pull()
# 033 스케일링 적용
clf2 = setup(data, target='Class variable', normalize=True, normalize_method='zscore', session_id=42, verbose=False)
svm2 = create_model('rbfsvm', verbose=False)
results2 = pull()
print(f"스케일링 없이: {results1['Accuracy'].mean():.4f}")
print(f"스케일링 적용: {results2['Accuracy'].mean():.4f}")
확률 예측
from pycaret.classification import *
from pycaret.datasets import get_data
data = get_data('diabetes')
clf = setup(data, target='Class variable', session_id=42, verbose=False)
# 033 probability=True로 확률 예측 활성화
svm = create_model('rbfsvm', probability=True, verbose=False)
# 033 예측
predictions = predict_model(svm)
print(predictions[['Class variable', 'prediction_label', 'prediction_score']].head())
튜닝
from pycaret.classification import *
from pycaret.datasets import get_data
data = get_data('diabetes')
clf = setup(data, target='Class variable', normalize=True, session_id=42, verbose=False)
# 033 기본 모델
svm = create_model('rbfsvm', verbose=False)
# 033 자동 튜닝
tuned_svm = tune_model(svm, optimize='AUC')
# 033 커스텀 그리드
custom_grid = {
'C': [0.1, 1, 10, 100],
'gamma': ['scale', 'auto', 0.01, 0.1, 1],
'kernel': ['rbf', 'poly']
}
tuned_svm = tune_model(svm, custom_grid=custom_grid, optimize='AUC')
결정 경계 시각화
from pycaret.classification import *
from pycaret.datasets import get_data
data = get_data('iris')
clf = setup(
data,
target='species',
session_id=42,
verbose=False
)
svm = create_model('rbfsvm', verbose=False)
# 033 결정 경계 시각화 (2차원)
plot_model(svm, plot='boundary')
서포트 벡터 확인
from pycaret.classification import *
from pycaret.datasets import get_data
data = get_data('iris')
clf = setup(data, target='species', session_id=42, verbose=False)
svm = create_model('rbfsvm', verbose=False)
# 033 서포트 벡터 개수
print(f"서포트 벡터 개수: {svm.n_support_}")
print(f"클래스별 서포트 벡터: {list(svm.n_support_)}")
# 033 서포트 벡터 인덱스
print(f"총 서포트 벡터: {len(svm.support_)}")
장단점
장점:
- 고차원 데이터에서 효과적
- 결정 경계가 명확
- 커널 트릭으로 비선형 분류 가능
- 과적합에 강건 (마진 최대화)
단점:
- 대용량 데이터에서 느림 (O(n²) ~ O(n³))
- 스케일링 필수
- 확률 출력이 느림
- 하이퍼파라미터 튜닝 필요
- 해석이 어려움
언제 사용하나?
# 1. 고차원, 소규모 데이터
# 033 특성 수 >> 샘플 수 (텍스트, 유전자 데이터)
# 2. 명확한 마진이 필요할 때
# 033 클래스가 잘 분리되는 경우
# 3. 비선형 관계가 있을 때
# 033 RBF 커널로 복잡한 결정 경계
# 033 주의: 대용량 데이터에서는 다른 알고리즘 권장
SVM vs 다른 알고리즘
| 상황 | SVM | 대안 |
|---|---|---|
| 대용량 | 느림 | XGBoost, LightGBM |
| 고차원 | 적합 | SVM |
| 해석 필요 | 어려움 | 로지스틱, 결정 트리 |
| 비선형 | RBF | 랜덤 포레스트 |
| 빠른 프로토타이핑 | 느림 | 랜덤 포레스트 |
정리
- SVM은 마진 최대화 기반 분류기
- C로 소프트/하드 마진 조절
- RBF 커널이 가장 범용적
- 스케일링 필수
- 소규모 고차원 데이터에 적합
- 대용량 데이터에서는 비효율적
다음 글 예고
다음 글에서는 KNN 분류 상세를 다룹니다.
PyCaret 머신러닝 마스터 시리즈 #033