일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- SQL
- Oracle ASSM
- Python
- Spark jdbc parallel read
- git 기본명령어
- 알고리즘
- Oracle 논리적 저장 구조
- airflow 정리
- Collaborative filtering
- 데이터분석
- 앙상블
- 추천시스템
- git init
- 통계분석
- 데이터 분석
- 배깅
- 오라클 데이터 처리방식
- Decision Tree
- enq: FB - contention
- Linux
- Spark Data Read
- Spark 튜닝
- 랜덤포레스트
- 리눅스 환경변수
- CF
- 네트워크
- git stash
- 의사결정나무
- BFS
- eda
- Today
- Total
[Alex] 데이터 장인의 블로그
[Machine Learning] SVM - 서포트 벡터 머신 본문
출처
[서적] 파이썬 데이터 사이언스 핸드북
https://pierpaolo28.github.io/blog/blog6/
SVM: Feature Selection and Kernels
기반으로 한 학습내용 정리입니다.
분류 = 분리
분류 학습의 가장 기본적인 아이디어는 훈련 데이터의 공간에서 하나의 분할 초평면을 찾아 서로 다른 클래스의 데이터를 찾아내어 분리하는 것이다. 그렇다면 위의 그림에서 분류를 하기 위한 분할선을 하나 찾는다고 가정할 때, 왜 오른쪽 초록선이 기준이 되는 것일까?
그 이유는 가장 '견고'한 선이기 때문이다. 노이즈(이상값)나 어떠한 영향으로 인해 새로운 데이터가 분류 경계에 가까이 가게된다면 '오류'가 생기게 된다. 이러한 오류를 최대한 줄일 수 있도록 '분할선'을 학습하는 것이 서포트 벡터 머신 (SVM)에 가장 기본적인 이론이라고 할 수 있다.
마진
서포트 벡터 머신에서는 '마진'을 극대화하는 선이 최적의 모델이 된다. 즉, SVM은 최대 '마진' 추정기의 대표적인 예이다.
마진의 두가지 형태 - 하드 VS 소프트
SVM의 마진은 두가지 형태를 보이는데 '하드' 마진과 '소프트' 마진이다.
-
하드 마진: 오분류하는 결과를 고려하지 않고, 가장 적합한 초평면을 산출하는 방법.
-
소프트 마진: 모델에 허용 오차를 추가하여 데이터를 '일반화' 하는 방법. 어느정도의 오분류를 허용하고 더욱 '유연'하게 예측할 수 있도록 지원하는 것.
Scikit-Learn 에서 소프트 마진 SVM은 C인자를 통해 조절할 수 있다. C인자를 높게 산정할수록 오분류에 대한 패널티를 더하는 방법이다. 즉, '여유' 가지는 정도를 C인자로 정하는 것이라 할 수 있다.
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
# use seaborn plotting defaults
import seaborn as sns; sns.set()
from sklearn.datasets.samples_generator import make_blobs
X, y = make_blobs(n_samples=100, centers=2,
random_state=0, cluster_std=1.2)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn');
def plot_svc_decision_function(model, ax=None, plot_support=True):
"""Plot the decision function for a 2D SVC"""
if ax is None:
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
# create grid to evaluate model
x = np.linspace(xlim[0], xlim[1], 30)
y = np.linspace(ylim[0], ylim[1], 30)
Y, X = np.meshgrid(y, x)
xy = np.vstack([X.ravel(), Y.ravel()]).T
P = model.decision_function(xy).reshape(X.shape)
# plot decision boundary and margins
ax.contour(X, Y, P, colors='k',
levels=[-1, 0, 1], alpha=0.5,
linestyles=['--', '-', '--'])
# plot support vectors
if plot_support:
ax.scatter(model.support_vectors_[:, 0],
model.support_vectors_[:, 1],
s=300, linewidth=1, facecolors='none');
ax.set_xlim(xlim)
ax.set_ylim(ylim)
from sklearn.svm import SVC # "Support vector classifier"
X, y = make_blobs(n_samples=100, centers=2,
random_state=0, cluster_std=0.8)
fig, ax = plt.subplots(1, 2, figsize=(16, 6))
fig.subplots_adjust(left=0.0625, right=0.95, wspace=0.1)
for axi, C in zip(ax, [10.0, 0.1]):
model = SVC(kernel='linear', C=C).fit(X, y)
axi.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
plot_svc_decision_function(model, axi)
axi.scatter(model.support_vectors_[:, 0],
model.support_vectors_[:, 1],
s=300, lw=1, facecolors='none');
axi.set_title('C = {0:.1f}'.format(C), size=14)
C가 낮을수록 더욱 후하게 (Soft Margin 스럽게) 분류한다는 것을 알 수 있다. 즉 C인자(Cost)는 어느정도는 비용을 감수하면서 적절한 답을 찾는 방법의 정도를 나타내는 것이다.
커널 SVM
SVM은 기본적으로 선형 분류를 위한 경계면을 만들어낸다. 하지만 비선형 형태의 분류를 어떻게 나타낼 수 있을까?
위에서 보이는 것처럼 2차원에서 선형 분리가 되지 않을 수 있지만, 고차원(3차원)에서는 선형 분리가 가능할 수 있다. 이러한 원리를 기반으로 선형 분리가 불가능한 저차원 데이터를 고차원으로 변형하여 선형 분리를 나타낼 수 있다. 때문에 Kernel Trick이라는 Mapping 함수를 사용한다. Kernel Trick은 고차원 Mapping과 고차원에서의 내적 연산을 '한번에 할 수 있는 방법'이다. 이를 통해 여러가지 Kernel 함수를 통해 저차원에서 해결하지 못한 선형 분리를 고차원에서 해결할 수 있다.
from sklearn.datasets.samples_generator import make_circles
X, y = make_circles(100, factor=.1, noise=.1)
clf = SVC(kernel='linear').fit(X, y)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
plot_svc_decision_function(clf, plot_support=False);
여기서 '사영' 이라는 방법을 통해 저차원의 데이터를 고차원의 데이터로 변형한다.
# 방사형 기저함수의 function
r = np.exp(-(X ** 2).sum(1))
from mpl_toolkits import mplot3d
from ipywidgets import interact, fixed
ax = plt.subplot(projection='3d')
ax.scatter3D(X[:, 0], X[:, 1], r, c=y, s=50, cmap='autumn')
sklearn 에는 SVM 대표적인 Kernel 함수들이 기본적으로 내재되어 이를 사영 및 분류에 활용한다.
clf = SVC(kernel='rbf', C=1E6) # 방사형 기저함수
clf.fit(X, y)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
plot_svc_decision_function(clf)
plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1],
s=300, lw=1, facecolors='none');
대표적인 Kernel 함수
-
Linear (선형 함수)
-
Poly (다항식 함수) -> 엄청오래 걸림 비추
-
RBF (방사기저 함수) -> 가장 성능이 좋아 자주 사용됨.
-
Hyper-Tangent (쌍곡선 탄젠트 함수)
장점
-
고차원, 저차원 데이터에서 잘 동작.
-
모델 훈련 훈 예측 단계 매우 빠름.
-
비교적 적은 수의 데이터에 의존 -> 적은 메모리 사용.
단점
-
모델 복잡도가 최악인 경우 -> 연산량 너무 커짐
-
매개변수, 전처리 신경 엄청 많이 씀 <-> 랜덤포레스트, 그라디언트 부스팅 (전처리 거의 필요 없음)
-
확률적 해석이 불가능. 모델을 설명하기가 부적합
데이터 세트가 커질수록 비용이 커진다. 100,000개 이상의 데이터셋에서는 속도와 메모리 관점에서 도전적인 과제
'ML&DL > Machine Learning' 카테고리의 다른 글
[Machine Learning] Random Forest - 랜덤 포레스트 코드 구현 (feat. python) (0) | 2020.10.04 |
---|---|
[Machine Learning] Random Forest - 랜덤 포레스트 (0) | 2020.10.04 |
[Machine Learning] Decision Tree - 의사결정나무 (0) | 2020.09.20 |