본문 바로가기
AI_basic/ML

[ML] SVM

by hits_gold 2022. 8. 1.
반응형

SVM (support vector machine)

 -> 매우 강력하고 선형이나 비선형 분류, 회귀, 이상치 탐색에도 사용할 수 있는 다목적 머신러닝 모델

 -> 특히 복잡한 분류 문제에 잘 들어맞으며 작거나 중간 크기의 데이터셋에 적합함

 

1. 선형 SVM 분류

직선에 의해 선형적인 분류를 하는 SVM

  •   왼쪽 그래프의 실선같은 경우 학습 데이터에 대해 잘 분류하고 있으나, 경계가 너무 가까워 새로운 샘플에 대해 잘 작동하지 못할 수 있음
  • 오른쪽 그래프의 실선은 제일 가까운 훈련샘플로부터 가장 멀리 떨어져 있음 -> large margin classification
  • 도로 경계에 위치한 샘플(오른쪽 그래프의 동그라미로 표시된 샘플)에 의해  결정됨  -> 이러한 샘플을 support vector라고 부름

** SVM은 특징(feature)들에 스케일에 민감하다. 위 그림을 보면 같은 스케일로 특징(feature)들을 변환했을 때 샘플이 더 멀리 떨어져서 decision boundary를 형성한 것을 볼 수 있다. 이러한 특징 때문에, SVM을 사용하려면 특징점(feature)들을 스케일링(e.g. Scikit-Learn의 StandardScaler)해야 한다.

 

1.1 Soft Margin Classification

 

 위에서 처럼 다른 클래스들을 나눌 때 샘플들로부터 가능하면 멀리 decision boundary를 형성하는 것을 hard margin classification이라고 부른다. 이 분류는 2가지 이슈가 있다. 하나는, 데이터가 직선으로 나눌 수 있을 때만 제대로 작동한다는 것이고, 다른 하나는, outlier들에 민감하다는 것이다.

 

 도로의 폭을 가능한 넓게 유지하려는 것 과  마진 오류 사이에 적절한 균형 유지 -> Soft Margin Classification

 

 Scikit-Learn의 SVM 클래스에서는 C 하이퍼파라미터를 조절할 수 있다. 값이 작으면 도로의 폭는 더 넓어지지만 마진 오류는 증가한다. 밑에 왼쪽 그림 같은 경우는 C 값이 낮기 때문에 도로의 폭은 넓고 마진 오류는 더 크다. 반면에  오른쪽 그림은 C의 값이 크기 때문에 도로의 폭이 좁지만 마진 오류도 매우 적다.

import numpy as np
from sklearn import datasets
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC

iris = datasets.load_iris()
X = iris["data"][:, (2,3)] # petal의 길이, petal의 넓이
y = (iris["target"] == 2).astype(np.float64) # Iris-Virginica

svm_clf = Pipeline([
    ("scaler", StandardScaler()),
    ("linear_svc", LinearSVC(C=1, loss="hinge")),
])

svm_clf.fit(X,y)

print(svm_clf.predict([[5.5, 1.7]])
# array([1.])

  -> Logistic Regression 분류기와는 달리 SVM 분류기는 각 클래스에 대해 확률을 제공하지 않는다.

 -> SGDClassifier(loss="hinge", alpha=1/(m*C))를 사용하면 LinearSVC보다 수렴은 느리게 하지만 메모리에 다 들어가지 않는 큰 데이터셋을 다룰 때는 유용하게 사용할 수 있다.

 

2. 비선형 SVM 분류

 많은 데이터셋들은 직선으로 분류가 되지 않는 경우가 많다. 이러한 경우에는 feature들을 추가해서 직선으로 분류가 가능하게 만들면 된다. 밑에 그림 같은 경우에 feature가 하나일 때는 직선 하나로 분류할 수가 없었는데 feature를 하나 추가한 이후에 분류가 가능해졌다,

이 아이디어를 구현하려면 PolynomialFeatures transformer, StandardScaler, LinearSVC를 포함한 Pipeline을 만들어야 한다.

from sklearn.datasets import make_moons
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures

poly_svm_clf = Pipeline([
    ("poly_features", PolynomialFeatures(degree=3)),
    ("scaler", StandardScaler()),
    ("svm_clf", LinearSVC(C=10, loss="hinge"))
])

poly_svm_clf.fit(X,y)

Polynomial Kernel

 -> Polynomial degree를 추가하면 복잡한 dataset에 더 잘 fit하게 만들 수 있지만, 모델이 너무 느려진다.

 -> SVM은 높은 polynomial degree를 추가하면서도 모델이 느려지지 않도록 kernel trick 이라는 것을 제공함

 

Polynomial degree를 추가하면 복잡한 dataset에 더 잘 fit하게 만들 수 있지만, 모델이 너무 느려진다. SVM은 높은 polynomial degree를 추가하면서도 모델이 느려지지 않도록 kernel trick 이라는 것을 제공한다. 실제로 polynomical feature(특징점)들을 추가하지는 않지만 추가하는 것과 같은 결과가 나오게 한다.

밑에 코드에서 SVM 분류기가 3 degree를 가진 polynomial kernel을 사용해서 학습을 한다. Polynomial degree가 높아지면 overfitting(오버피팅)이 발생한다.

from sklearn.svm import SVC
poly_kernel_svm_clf = Pipeline([
    ("scaler", StandardScaler()),
    ("svm_clf", SVC(kernel="poly", degree=3, coef0=1, C=5))
])

poly_kernel_svm_clf.fit(X,y)

  -> Polynomial degree가 높아지면 overfitting(오버피팅)이 발생함

 

Adding Similarity Features

Gaussian RBF
r=0.3 Gaussian RBF사용한 Simillarity Faetures

  1) 랜드마크 추가 (왼쪽 그림 x(-2, 0), x(1, 0))

  2) Similarity Features(여기선 Gausian Radial Basis Function (RBF)) 추가

  3) 데이터셋을 transform (오른쪽 그림)

 

  -> 가장 간단한 방법은 데이터셋의 각 인스턴스 위치에 landmark를 만드는 것

  -> 차원을 많이 만들 수 있고 transform된 training set이 직선으로 분류가 될 가능성이 높아짐

  -> 단점은 training set이 매우 크면, feature(특징점)들의 수도 매우 많아짐

 

Gaussian RBF Kernel

rbf_kernel_svm_clf = Pipeline([
    ("scaler", StandardScaler()),
    ("svm_clf", SVC(kernel="rbf", gamma=5, C=0.001))
])

rbf_kernel_svm_clf.fit(X,y)

-> 모델이 오버피팅을 하면 gamma값을 줄여야 하고, 언더피팅을 하면 증가시켜야 한다(C 하이퍼파라미터와 비슷함)

 

5.3 SVM Regression

SVM 회귀

-> SVM Regression은 위에서 언급되었던 linear & nonlinear classification과는 달리 margin violation들을 제한하면서 가능하면 많은 인스턴스들을 street에 담으려고 한다. 도로 폭의 너비는 ϵ 하이퍼파라미터로 조절이 가능하다.

from sklearn.svm import LinearSVR, SVR

svm_reg = LinearSVR(epsilon=1.5)
svm_reg.fit(X,y)

svm_poly_reg = SVR(kernel="poly", degree=2, C=100, epsilon=0.1)
svm_poly_reg.fit(X,y)

 -> LinearSVR 모듈을 사용해 구현

 -> ϵ에 민감하지 않다

 

 

SVM 비선형 회귀

  -> 비선형 회귀 작업을 처리해주려면, 커널 SVM 모델을 사용해야 한다.

  -> 왼쪽 그래프는 규제가 거의 없고(C=100) 오른쪽 그래프는 규제가 큼(C=1)

  -> SVR은 필요한 시간이 훈련 세트의 크기에 비례해 선형적으로 늘어남

 

5.4  SVM 이론

 SVM이 실제로 어떻게 예측을 할까?

 

5.4.1 결정 함수와 예측

w : featuer 가중치, b : 편향

 SVM은 새로운 샘플을 결정함수에 넣어 예측을 진행한다.

 

SVM을 학습한다는 것은 마진 오류를 피하면서 margin을 가능한 넓게 만드는 w와 b의 값을 찾는 것을 의미한다.

 

 5.4.2 목적함수

  -> 결정함수의 기울기는 w의 절대값과 같고, 이 기울기를 2로 나누면 값의 절대값이 1이 되는 점들이 결정 경계로부터 2배 멀어짐.

  -> 기울기를 2로 나누는 것은 마진에 2를 곱하는 것과 같은 것이다!

 

     즉 마진을 크게 하기 위해 w절대값을 최소화하면 됨. 양성은 1보다 크고 음성은 -1보다 작아야한다.

 

soft margin의 경우 목적함수의 최적화 문제로 표현

  

반응형