Suppor Vector Machine
- 매우 강력한 다목적 머신러닝 모델 (선형/비선형 분류, 회귀, 이상치 탐색 등)
- 머신러닝에서 가장 인기 있는 모델
- 복잡한 분류 문제에 적합
- 소규모, 중간 규모의 데이터셋에 적합
# 선형 SVM 분류
예를 들어 두 가지 클래스를 구분하는 선형 SVM 분류기가 있다고 할 때, SVM 분류기의 결정 경계는 두 개의 클래스를 나누면서 제일 가까운 훈련 샘플로부터 가능한 한 멀리 떨어져 있으려 한다. 이러한 특성을 라지 마진 분류(large margin classification) 라고 함.
라지 마진 분류의 결정 경계는 결정 경계과 가장 가깝게 위치한 샘플에 의해 전적으로 결정된다( 즉 결정 경계와 비교적 먼 샘플은 아무런 영향을 미치지 못함). 이렇게 결정 경계와 가장 가깝게 위치한 샘플을 서포트 벡터(suppor vector)라고 한다.
* SVM 은 특성의 스케일에 민감함. 특성의 스케일을 조정하면 결정 경계가 훨씬 좋아진다.
# 소프트 마진 분류
만약 모든 샘플이 결정 경계 범위(도로)의 바깥쪽에 올바르게 분류되어 있다면 이를 하드 마진 분류 라고 한다.
하드 마진의 문제점
- 데이터가 선형적으로 구분될 수 있어야 제대로 작동
- 이상치에 민감함
--> 결정 경계 찾는것이 불가능하거나, 훈련 데이터셋에 과대적합되어 일반화가 잘 안될 수 있음
좀 더 유연한 모델을 위해 결정 경계 범위의 폭을 가능한 넓게 유지하는것과 마진 오류(margin violation, 샘플이 도로 중간이나 심지어 반대쪽에 있는 경우) 사이에 적절한 균형을 잡아야 함 --> 소프트 마진 분류
사이킷런의 SVM 모델에서는 C 하이퍼파라미터를 사용해 균형 조절이 가능하다.
C 값을 줄일 경우: 도로의 폭이 넓어지지만 마진 오류도 커짐
C 값을 늘릴 경우: 도로의 폭이 좁아지면서 마진 오류도 적어짐
다음은 사이킷런 LinearSVC 클래스를 사용한 붓꽃 데이터셋 Iris-Virginia 품종 감지 분류기를 훈련시킨 코드이다.
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')),
])
svm_clf.fit(X,y)
* linearSVC 는 클래스에 대한 확률을 나타내는 predict_proba() 메서드를 제공하지 않음. SVC 모델은 probablilty = True 로 지정하면 predict_proba() 메서드를 제공.
* linearSVC 는 규제에 편향을 포함시키므로 훈련 세트에서 평균을 빼 중앙에 맞춰야 함. 또한 loss 매개변수를 'hinge'로 지정해야 함. 훈련 샘플보다 특성이 많지 않다면 성능 향상을 목적으로 dual 매개변수를 False 로 지정.
# 비선형 SVM 분류
선형적으로 분류할 수 없는 데이터셋을 다루는 방법 중 한가지는 앞에서도 설명한 다항 특성과 같은 특성을 더 추가하는 것이다. 사이킷런을 사용하여 이를 구현하려면 PolynomialFeatures, StandardScaler, LinearSVC 를 연결하여 Pipeline 을 만들면 좋다. 다음은 이를 moons 데이터셋에 적용한 코드이다.
from sklearn.datasets import make_moons
from sklearn.preprocessing import PolynomialFeatures
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', max_iter=2000))
])
polynomial_svm_clf.fit(X,y)

# 다항식 커널
다항식 특성을 추가하는 것은 간단하고 잘 작동하지만 단점이 있다.
낮은 차수의 다항식: 매우 복잡한 데이터셋을 잘 표현하지 못함
높은 차수의 다항식: 굉장히 많은 특성을 추가하므로 모델을 느리게 만듦.
SVM 을 사용할 땐 커널 트릭(kernel trick) 이라는 수학적 기교를 적용할 수 있다. 이는 어떠한 특성도 추가하지 않으면서 다항식 특성을 많이 추가한 것과 같은 결과를 얻을 수 있는 엄청난 기법이다.
다음은 커널 트릭을 활용해 moons 데이터셋에서 테스트 해본 코드이다.
from sklearn.svm import SVC
poly_kernel_svm_clf = Pipeline([
('scaler', StandardScaler()),
('svm_clf',SVC(kernel='poly', degree=3, coef0=1, C=5)),
# coef0 parameter = 높은 차수와 낮은 차수에 얼마나 영향을 받을지 결정
])
poly_kernel_svm_clf.fit(X,y)

# 유사도 특성 추가
비선형 특성을 다루는 또 다른 기법은 각 샘플이 특정 랜드마크 와 얼마나 닮았는지 추정하는 유사도 함수 로 계산한 특성을 추가하는 것이다.
데이터 중 랜드마크를 설정하여 유사도 함수를 정의하고 모든 데이터에 대한 유사도 함수를 계산하여 도출된 함숫값을 특성으로 변수변환하여 나타내면 선형적으로 구분이 가능해진다.

위 그래프는 가우시안 방사 기저 함수(Radial Basis Function, RBF) 를 유사도 함수로 정의하였다.
가우시안 RBF
ϕγ(x,ℓ)=e(−γ‖
랜드마크를 선택하는 간단한 방법은 데이터셋에 있는 모든 샘플 위치에 랜드마크를 설정하는 것이다.
이렇게 설정하면 차원이 매우 커지고 변환된 훈련 세트가 선형적으로 구분될 가능성이 높지만, 단점은 훈련 세트에 있는 n 개의 특성을 가진 m 개의 샘플이 m 개의 특성을 가진 m 개의 샘플로 변환된다는 것이다. 훈련 세트가 매우 클 경우 동일한 크기의 아주 많은 특성이 만들어진다.
# 가우시안 RBF 커널
유사도 특성 방식도 머신러닝 알고리즘에 유용하게 사용될 수 있다. 이때 역시 커널 트릭에 의해 특성을 추가하지 않고도 유사도 특성을 많이 추가한 것과 같은 비슷한 결과를 얻을 수 있다. 다음은 SVC 모델에 가우시한 RBF 커널을 적용한 코드이다.
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를 증가시키면 종 모양의 그래프가 좁아져서 각 샘플의 영향 범위가 작아진다. 따라서 결정 경계가 더 불규칙해지고 각 샘플을 따라 구불구불하게 휘는 모습을 볼 수 있다.
모델이 과대적합일 경우 하이퍼파라미터 gamma를 감소시켜야 하며 과소적합일 경우 증가시켜야 한다.
# 계산 복잡도
LinearSVC 파이썬 클래스는 선형 SVM 을 위한 최적화된 알고리즘을 구현한 liblinear 라이브러리를 기반으로 하며, 훈련 샘플 수와 특성 수에 거의 선형적으로 늘어난다.
정밀도를 높이면 알고리즘의 수행 시간이 길어지며 허용오차 하이퍼파라미터 \varepsilon 으로 조절한다. (사이킷런에서 매개변수 tol, 기본값 0.0001) 대부분의 분류 문제는 기본값에서 잘 작동한다.
SVC 는 커널 트릭 알고리즘을 구현한 libsvm 라이브러리를 기반으로 하며 훈련의 시간 복잡도는 특성 수에 샘플 수의 제곱에서 세제곱의 곱에 비례한다. 계산의 복잡성으로 인해 작거나 중간 규모의 훈련 세트에 잘 맞는다.
하지만 특성의 개수에는 선형적이며 희소 특성일 경우 잘 확장된다. 이때 알고리즘의 성능은 샘플이 가진 0이 아닌 특성의 평균 수에 비례한다.
파이썬 클래스 | 시간 복잡도 | 외부 메모리 학습 지원 | 스케일 조정 필요성 | 커널 트릭 |
LinearSVC | O(m\times n) | 아니오 | 예 | 아니오 |
SGDClassifier | O(m \times n) | 예 | 예 | 아니오 |
SVC | O(m^2 \times n) ~ O(m^3 \times n) | 아니오 | 예 | 예 |
이미지 출저 : handson-ml 옮긴이 github
'Artificial Intelligence > Machine Learning' 카테고리의 다른 글
핸즈온 머신러닝(7) - 결정 트리 (1) | 2020.01.28 |
---|---|
핸즈온 머신러닝(6) - 서포트 벡터 머신 2 (0) | 2020.01.27 |
핸즈온 머신러닝(5) - 로지스틱 회귀 2 (0) | 2020.01.24 |
핸즈온 머신러닝(5) - 로지스틱 회귀 1 (0) | 2020.01.24 |
핸즈온 머신러닝(5) - 규제가 있는 선형 모델 (0) | 2020.01.24 |
댓글