[ 핸즈온 머신러닝 2판 ] SVM이란?
어제보다 나은 사람이 되기

걱정보단 실행을, 그러나 계획적으로

Box World 자세히보기

AI/Hands-On Machine Learning 2판

[ 핸즈온 머신러닝 2판 ] SVM이란?

Box형 2021. 2. 2. 01:11
반응형

인내는 어떤 실력보다 강하다

- 벤 호건 (프로 골퍼) -


시작하며

 SVM은 Classification, Regression 등 다양한 곳에서 활용됩니다. 특히 복잡한 데이터셋을 학습하기에 용이하다는 점도 SVM의 인기를 높이는 데 한 몫 하였습니다.


5.1 선형 SVM 분류

 위 데이터셋은 서로 다른 종류의 붓꽃들을 모아놓은 데이터셋입니다. 이 둘을 직선 하나만 그어서 같은 클래스의 데이터들만 모여있도록 구역을 나눌 수 있을까요?

 당연히 가능합니다. 우리는 이것을 선형적으로 구분이 가능하다고 합니다. 그러나 왼쪽 그래프의 빨간색이나 자주색 선이 두 클래스를 잘 구분하는 듯 하지만 경계가 너무 데이터에 가깝기 때문에 좋은 성능을 보일거라곤 장담하지 못합니다.

 결론은 오른쪽처럼 두 클래스를 나눌 때 최대한 큰 마진(margin)을 갖도록 경계를 정하면 그만큼 성능이 높아진다는 것입니다. 이렇게 마치 최대한 폭이 넓은 도로를 찾는 듯 분류하는 것이 Large Margin Classfication이라고 합니다.

 도로 밖에 data를 추가하더라도 경계는 변하지 않으며, 오른쪽 그래프의 두 점선처럼 도로의 경계에 영향을 미치는 데이터를 Suppor Vector라고 합니다.

 이렇게 경계를 정하여 데이터를 분류하는데 사용하는 모델을 SVM(Support Vector Machine)이라고 합니다.


  SVM을 다룰 때 feature의 Scale(범위)을 조정하는 것이 중요합니다. 

 왼쪽 그래프는 $x_1$과 $x_0$의 Scale이 달라 Margin이 거의 없는 경계가 생성되었습니다. 반대로 이 feature들의 스케일을 조정하면 오른쪽처럼 경계가 훨씬 좋아집니다.


 Margin Classification

 Margin Classification에는 Hard와 Soft 두가지가 있습니다. Hard Margin Classification은 모든 데이터가 도로의 바깥쪽에 올바르게 분류되어야합니다.

 그러나 이는 데이터가 선형적으로 분류가 가능해야하고, 변칙적으로 튀는 이상치(Anomaly data)에 민감합니다.(이상치마저도 완벽하게 분류하려하니 경계가 좋은 성능을 지닐 수가 없겠죠)

 따라서 왼쪽 그래프처럼 이상치가 존재하는 경우 Hard하게 분류하는 것은 불가능합니다. 게다가 오른쪽처럼 분류할 수 있다하더라도 완벽하게 분류하기 위해선 margin이 거의 없는 경계를 만들어야하는 상황이 발생하게 됩니다.

 그래서 우리는 분류가 조금 틀리더라도 성능 좋은 경계를 만들기 위해 Soft Margin Classification을 생각하게 되었습니다. 이는 도로의 Margin의 크기와 잘못 분류하는 Margin violation(마진 오류)에 대한 트레이드 오프 관계에서 균형을 잘 잡아야합니다.

 sklearn의 SVM 모델의 하이퍼 파라미터중 하나인 $C$는 이러한 트레이드 오프를 정하는데 사용됩니다. 이 $C$가 높을 수록 모델은 Margin Violation을 허용하지 않으려 합니다. 반대로 $C$가 낮으면 Margin Violation은 높아지겠지만 일반화가 더 잘될 것입니다.


 다음은 앞서 본 붓꽃 데이터셋에 대해서 feature Scale을 조정한 후, 특정 품종을 감지하기 위해 선형 SVM 모델을 훈련시키는 코드입니다.

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)]  # 꽃잎 길이, 꽃잎 너비
y = (iris["target"] == 2).astype(np.float64)  # Iris virginica

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

svm_clf.fit(X, y)

//output
Pipeline(steps=[('scaler', StandardScaler()),
                ('linear_svc', LinearSVC(C=1, loss='hinge', random_state=42))])
svm_clf.predict([[5.5, 1.7]])

//output(예측 결과)
array([1.])

 sklearn의 SVM 모델을 최적화할 땐 보통 SGDClassifier같은 일반적인 Gradient Descent Algorithm을 이용합니다.


5.2 비선형 SVM 분류

 선형 SVM 분류기가 많은 경우에 잘 작동하지만, 선형적으로 분류할 수 없는 데이터셋들 또한 많습니다. 이럴 때 Polynomial Feature과 같은 feature를 추가하는 것입니다.

 왼쪽 그래프는 $x_1$이라는 하나의 feature만 가지는 데이터셋으로 선형적으로 분류가 안되지만, $x_2=(x_1)^2$라는 새로운 특성을 추가하면 오른쪽처럼 완벽하게 선형적으로 분류가 가능합니다.

 sklearn에서는 다음과 같이 적용해볼 수 있습니다 사용된 데이터는 Binary Classification의 예시를 들때 자주 사용되는 moon dataset입니다.

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

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

polynomial_svm_clf.fit(X, y)


5.2.1 Polynomial Kernel(다항식 커널)

  Polynomial Feature를 추가하는 건 모든 머신러닝 알고리즘에서 사용가능한 보편적입니다. 그러나 이런식으로 변형된 높은 차수의 다항식은 모델을 느리게 만듭니다.

 다행히 SVM은 Kernel Trick을 이용하여 실제로는 feature를 추가하지 않으면서 feature를 많이 추가한듯한 결과를 얻을 수 있습니다.


 커널 트릭에 대한 좀 더 자세한 부분은 아래의 이전 포스팅을 참고해주세요

[AI/Coursera ( Machine Learning )] - [머신러닝 순한맛] SVM(Supprot Vector Machine)이란? - 3) Kernal

 

[머신러닝 순한맛] SVM(Supprot Vector Machine)이란? - 3) Kernal

시작하며 저번 포스팅에서는 SVM의 Margin에 대해 다루며, 선형으로 분리되는 데이터의 Decision Boundary를 어떻게 지정할 것인가에 대해 다뤄보았습니다. 하지만 이 세상의 대부분의 데이터는 대부분

box-world.tistory.com


 다음은 Polynomial Feature를 추가하여 SVM을 사용하는 코드입니다.

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)

 왼쪽 그래프는 3차 Polynomial Kernel을, 오른쪽은 10차를 적용하였습니다. 추가하는 feature의 차수가 높아질수록 Margin Violation이 감소되게끔 경계가 변하는 것을 볼 수 있습니다.

 하이퍼파라미터 $C$는 높은 차수와 낮은 차수에 얼마나 영향을 받을지 결정합니다.


5.2.2 유사도 특성

 유사도 특성은 각 data가 특정 랜드마크와 얼마나 닮았는지를 y값으로 두는 유사도 함수를 이용하는데, y값이 바로 추가된 feature가 됩니다.

 예를 들어 왼쪽 그래프처럼 $x_1 = -2$와 $x_1 = 1$를 중심축으로 가지는 $γ = 3$인 Gaussian RBF를 유사도 함수로 정의합니다. 이때 $x_1 = -2$와 $x_1 = 1$가 바로 랜드마크입니다. 

 쉽게 설명하자면 나머지 데이터들이 정해진 랜드마크와 얼마나 닮았느냐에 대한 수치가 y축인 유사도인것입니다. 예를 들어 랜드마크 $x_1 = -2$에 대해 $x_1 = -1$과 $x_1 = 4$ 두개에 대해 -1이 -2와 더 가까우므로 유사도가 높은 것입니다.

 이렇게 추가된 feature를 이용하면 오른쪽 그래프처럼 분류가 가능해집니다. 위 예시에서는 데이터들 중 2개만을 랜드마크로 지정했지만 모든 데이터를 랜드마크로 지정하면, 차원이 커지기 때문에 선형적으로 구분될 가능성이 커집니다.

 다만 n개의 feature를 가지던 m개의 데이터가 m개의 feature를 가지는 m개의 데이터로 변환된다는 것이 리스크로 작용합니다.(기존에 존재하던 feature는 제외한다고 가정합니다.)


5.2.3 Gaussian RBF Kernel

 앞서 우리는 유사도를 이용하여 feature를 추가하는 방법을 살펴보았습니다. 그런데 이렇게 유사도를 측정하여 feature를 추가하는 방식은 큰 연산 비용을 요구합니다. 여기서 Kernel Trick이 비용을 줄이는데 아주 중요한 작용을 합니다.

 우선 다음은 Gaussian RBF Kernel을 사용한 SVM 모델을 사용하는 코드입니다.

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

//output
Pipeline(steps=[('scaler', StandardScaler()),
                ('svm_clf', SVC(C=0.001, gamma=5))])

 위 그래프에서 알 수 있듯이 $γ$가 커질수록 앞서 봤던 종 모양의 그래프가 좁아지면서 각 데이터의 영향 범위가 줄어드는 효과를 가져옵니다. 이에 따라 경계는 좀더 구불구불해지고 불규칙해집니다.

 이 밖에 다른 커널들도 많이 존재하지만 거의 쓰이지 않습니다. 대부분은 선형 커널(LinearSVC)와 Gaussian RBF Kernel에서 문제가 해결됩니다.


5.3 SVM을 이용한 Regression

 SVM은 Classification 뿐 아니라 Regression에도 이용될 수 있습니다. 원리는 간단합니다. Regression에서는 도로 경계안에 최대한 많은 데이터들을 담아 데이터를 대표하려고 하면 됩니다. 

 즉 일정한 Margin Violation 아래에서 가능한 많은 데이터가 도로안에 들어가도록 학습니다. 이때 도로의 폭인 Margin은  위와 같이 하이퍼파라미터로 조절 가능하다.

 다음은 sklearn의 LinearSVR을 이용한 선형 SVM Regression을 적용하는 코드입니다.

from sklearn.svm import LinearSVR

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

 그리고 다음은 2차 Polynomial Kernel을 사용한 SVM Regression입니다.

from sklearn.svm import SVR

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


 다음 포스팅에서는 SVM만큼이나 보편적으로 사용되는 Decision Tree에 대해서 공부해보겠습니다. 긴글 읽어주셔서 감사합니다. 오늘도 행복한 하루 보내세요 :)

 

반응형