비선형 SVM의 분류 방법
선형 SVM 분류기가 효율적이고 많은 경우에 아주 잘 작동하지만, 선형적으로 분류할 수 없는 데이터셋이 더 많습니다.
비선형 데이터셋을 다루는 한 가지 방법은 다항 특성과 같은 특성을 더 추가하는 것입니다. 이렇게 하면 선형적으로 구분되는 데이터셋이 만들어질 수 있습니다.
< Fig. 1. 특성을 추가하여 선형적으로 구분되는 데이터셋 만들기 예제 >
Fig. 1의 왼쪽 그래프는 하나의 특성 𝑥₁만을 가진 가장 간단한 데이터셋을 나타냅니다. 그림에서 볼 수 있듯이 이 데이터셋은 선형적인 구분이 불가능합니다.
하지만 두 번째 특성 𝑥₂ = (𝑥₁)²을 추가하여 만들어진 2차원 데이터셋은 완벽하게 선형적으로 구분할 수 있습니다.
사이킷런을 사용하여 이를 구현하려면 PolynomialFeatures 변환기와 StandardScaler, LinearSVC를 연결하여 Pipeline을 만들면 좋습니다.
아래의 예제는 moons 데이터셋에 위 3가지를 적용한 것입니다.
Code
from sklearn.datasets import make_moons
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC
X, y = make_moons(n_samples=100, noise=0.15, random_state=42)
polynomial_svm_clf = Pipeline([
("poly_features", PolynomialFeatures(degree=3)),
("scaler", StandardScaler()),
("svm_clf", LinearSVC(C=10, loss="hinge"))
])
polynomial_svm_clf.fit(X, y)
1. 다항식 커널 (Polynomial Kernel)
다항식 특성을 추가하는 것은 간단하고 모든 머신러닝 알고리즘에서 잘 작동합니다. 하지만, 낮은 차수의 다항식은 매우 복잡한 데이터셋을 잘 표현하지 못하고 높은 차수의 다항식은 굉장히 많은 특성을 추가하므로 모델을 느리게 만듭니다.
다행히도 SVM을 사용할 땐 커널 트릭(Kernel Trick)이라는 거의 기적에 가까운 수학적 기교를 적용할 수 있습니다. 실제로는 특성을 추가하지 않으면서 다항식 특성을 많이 추가한 것과 같은 결과를 얻을 수 있습니다. 사실 어떤 특성도 추가하지 않기 때문에 엄청난 수의 특성 조합이 생기지 않습니다. 이 기법은 SVC 파이썬 클래스에 구현되어 있습니다.
Code
from sklearn.svm import SVC
import matplotlib.pyplot as plt
import mglearn
X, y = make_moons(n_samples=100, noise=0.15, random_state=42)
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)
poly_kernel_svm_clf2 = Pipeline([
("scaler", StandardScaler()),
("svm_clf", SVC(kernel="poly", degree=10, coef0=100, C=5))
])
poly_kernel_svm_clf2.fit(X, y)
mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
mglearn.plots.plot_2d_separator(poly_kernel_svm_clf, X)
plt.show()
mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
mglearn.plots.plot_2d_separator(poly_kernel_svm_clf2, X)
plt.show()
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)
poly_kernel_svm_clf2 = Pipeline([
("scaler", StandardScaler()),
("svm_clf", SVC(kernel="poly", degree=10, coef0=100, C=5))
])
poly_kernel_svm_clf2.fit(X, y)
mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
mglearn.plots.plot_2d_separator(poly_kernel_svm_clf, X)
plt.show()
mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
mglearn.plots.plot_2d_separator(poly_kernel_svm_clf2, X)
plt.show()
Output
|
|
2. 유사도 특성 추가
< Exp. 1. 가우시안 RBF >
이 함수의 값은 0부터 1까지 변화하며 종 모양으로 나타납니다. 이제 새로운 특성을 만들 준비가 되었습니다. 예를 들어 𝑥₁ = -1 샘플을 살펴봅시다. 이 샘플은 첫 번째 랜드마크에서 1만큼 떨어져 있고 두 번째 랜드마크에서 2만큼 떨어져 있습니다. 그러므로 새로 만든 특성은 𝑥₂ = exp(-0.3 × 1²) ≈ 0.74와 𝑥₃ = exp(-0.3 × 2²) ≈ 0.30입니다. Fig. 1.의 오른쪽 그래프는 변환된 데이터셋을 보여줍니다.
< Fig. 1. 가우시안 RBF를 사용한 유사도 측정 >
위와 같이 변환하면 이제 선형적으로 구분이 가능합니다. 랜드마크는 어떻게 선택할까요? 간단한 방법은 데이터셋에 있는 모든 샘플 위치에 랜드마크를 설정하는 것입니다. 이렇게 하면 차원이 매우 커지고 따라서 변환된 훈련 세트가 선형적으로 구분될 가능성이 매우 높습니다. 단점은 훈련 세트에 있는 n개의 특성을 가진 m개의 샘플이 m개의 특성을 가진 m개의 샘플로 변환된다는 것입니다. 훈련 세트가 매우 클 경우 동일한 크기의 아주 많은 특성이 만들어집니다.
3. 가우시안 RBF 커널 (Gaussian RBF Kernel)
Code
gamma_lst = [0.1, 0.1, 5, 5]
C_lst = [0.001, 1000, 0.001, 1000]
for g, c in zip(gamma_lst, C_lst):
rbf_kernel_svm_clf = Pipeline([
("scaler", StandardScaler()),
("svm_clf", SVC(kernel="rbf", gamma=g, C=c))
])
rbf_kernel_svm_clf.fit(X, y)
mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
mglearn.plots.plot_2d_separator(rbf_kernel_svm_clf, X)
plt.show()
Output
|
|
|
|
각각의 그래프를 살펴보면 𝛾를 증가시키면 종 모양 그래프가 좁아져서 각 샘플의 영향 범위가 작아집니다. 결정 경계가 조금 더 불규칙해지고 각 샘플을 따라 구불구불하게 휘어집니다. 반대로 작은 𝛾의 값은 넓은 종 모양 그래프를 만들며 샘플이 넓은 범위에 걸쳐 영향을 주므로 결정 경계가 더 부드러워집니다. 결국 하이퍼파라미터 𝛾가 규제의 역할을 합니다. 모델이 과대적합일 경우엔 감소시켜야하고 과소적합인 경우엔 증가시켜야 합니다.
References
- https://tensorflow.blog/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D/2-3-7-%EC%BB%A4%EB%84%90-%EC%84%9C%ED%8F%AC%ED%8A%B8-%EB%B2%A1%ED%84%B0-%EB%A8%B8%EC%8B%A0/
- 오렐리앙 제롱, '핸즈온 머신러닝', 한빛미디어, 2018
'Machine Learning > Algorithms' 카테고리의 다른 글
[ML/SVM] 선형 SVM(Linear Support Vector Machine) (0) | 2018.08.31 |
---|---|
[ML/SVM] SVM(Support Vector Machine) 기초 (0) | 2018.08.30 |