본문 바로가기

여러가지/Python

섹션 19. 커널 서포트 벡터 머신 (SVM)

● URL : https://colab.research.google.com/drive/15rzEZzs-qcb8q_At26Gr-vK50_sPnlMy#scrollTo=qeTjz2vDilAC 

 

일반적인 경우, 데이터가 결정 경계에 의해 선형적으로 분리 가능하다.

하지만 데이터가 선형적으로 분리 불가능한 경우도 있는데, 이 경우 아래의 순서에 따라 데이터를 분리한다.

(1) 비선형으로 분리되는 데이터 집합을 고차원에 배열하여 선형적으로 분리 가능한 데이터 집합으로 만든다.
(2) 서포트 벡터 머신 알고리즘을 가져와 데이터 집합에 대한 결졍 경계를 만든다.
(3) 원래 차원으로 불러온다.

즉, 고차원을 탐색한다는 해결책이 있다.

 

하지만 이는 많은 계산이 필요하여 프로세싱 지연이 발생한다.

따라서 커널 기술을 활용한다.

 

(1) Gussian RBF Kernel

K : kernel, 두 벡터(x,l)에 연결
x : 포인트
l : 랜드마크

 

랜드마크에 가까워 질 수록 지수 부분이 작아진다. 즉, 0에 가까워진다.

결과적으로 K(x,l)은 1에 가까워진다. 즉, 랜드마크에 가까워진다.

 

위의 커널 함수를 사용하여 데이터 집합을 분리해 결정 경계를 만든다.

원 안의 포인트에는 0 이상의 값을 배정하고, 원 밖의 포인트에는 0을 배정하여 데이터 집합을 분리한다.

 

시그마원의 넓이를 정의한다. 따라서 랜드마크가 위치할 최적의 장소를 찾기 위해서는, 즉, 정확하게 데이터 집합을 분리하기 위해서는 적절한 시그마를 찾아야한다. 시그마 커지면 원의 넓이 커지고, 시그마 작아지면 원의 넓이 작아진다. 즉, 비례관계이다.

이는 곧 결정 경계이다.

 

결과적으로 선형적으로 분리할 수 없는 데이터의 차원 변경 없이(고차원으로 들어가지 않고) 결정 경계를 만들고 수정할 수 있다.

추가로 두 개 이상의 커널 함수를 사용하여 활용할 수 있다.

 

○ 결정 경계

(1차원) 점

(2차원) 선

(3차원) 초평면

 

여러가지 커널

 

(1) Gussian RBF Kernel

(2) Sigmoid Kernel

- 방향성 있다.

- 우측의 값은 자동으로 높은 값 나온다. (?)

- 결정 경계 선을 긋거나 특정 경계를 넘어가는 포인트들은 범주화에 들어가야 한다는 걸 강조할 경우 시그모이드 커널 사용한다.

(3) Polynomial Kernel

- 다항의 상황에서 커널이 어떻게 되는지 지시 내릴 수 있다.

 

○ 비선형 서포트 벡터 커널 SVR

서포트 벡터 머신 작동 방식과 매우 비슷

 

Step 1. Importing the libraries

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

 

Step 2. Importing the dataset

dataset = pd.read_csv('Social_Network_Ads.csv')
X = dataset.iloc[:, 1:-1].values
y = dataset.iloc[:, -1].values

 

Step 3. Splitting the dataset into the Training set and Test set

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 0)

 

Step 4. Feature Scaling

from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)

 

Step 5. Training the Kernel SVM model on the Training set

from sklearn.svm import SVC
classifier = SVC(kernel = 'rbf', random_state = 0)
classifier.fit(X_train, y_train)

 

Step 6. Predicting a new result - 단일 결과 예측

print(classifier.predict(sc.transform([[30,87000]])))

 

Step 7. Predicting the Test set results

y_pred = classifier.predict(X_test)
print(np.concatenate((y_pred.reshape(len(y_pred),1), y_test.reshape(len(y_test),1)),1))

 

Step 8. Making the Confusion Matrix

from sklearn.metrics import confusion_matrix, accuracy_score
cm = confusion_matrix(y_test, y_pred)
print(cm)
accuracy_score(y_test, y_pred)

 

Step 9. Visualising the Training set results

from matplotlib.colors import ListedColormap
X_set, y_set = sc.inverse_transform(X_train), y_train
X1, X2 = np.meshgrid(np.arange(start = X_set[:, 0].min() - 10, stop = X_set[:, 0].max() + 10, step = 1),
np.arange(start = X_set[:, 1].min() - 1000, stop = X_set[:, 1].max() + 1000, step = 1))
plt.contourf(X1, X2, classifier.predict(sc.transform(np.array([X1.ravel(), X2.ravel()]).T)).reshape(X1.shape),
alpha = 0.75, cmap = ListedColormap(('salmon', 'dodgerblue')))
plt.xlim(X1.min(), X1.max())
plt.ylim(X2.min(), X2.max())
for i, j in enumerate(np.unique(y_set)):
plt.scatter(X_set[y_set == j, 0], X_set[y_set == j, 1], c = ListedColormap(('salmon', 'dodgerblue'))(i), label = j)
plt.title('K-NN (Training set)')
plt.xlabel('Age')
plt.ylabel('Estimated Salary')
plt.legend()
plt.show()

Step 10. Visualising the Test set results

from matplotlib.colors import ListedColormap
X_set, y_set = sc.inverse_transform(X_test), y_test
X1, X2 = np.meshgrid(np.arange(start = X_set[:, 0].min() - 10, stop = X_set[:, 0].max() + 10, step = 1),
np.arange(start = X_set[:, 1].min() - 1000, stop = X_set[:, 1].max() + 1000, step = 1))
plt.contourf(X1, X2, classifier.predict(sc.transform(np.array([X1.ravel(), X2.ravel()]).T)).reshape(X1.shape),
alpha = 0.75, cmap = ListedColormap(('salmon', 'dodgerblue')))
plt.xlim(X1.min(), X1.max())
plt.ylim(X2.min(), X2.max())
for i, j in enumerate(np.unique(y_set)):
plt.scatter(X_set[y_set == j, 0], X_set[y_set == j, 1], c = ListedColormap(('salmon', 'dodgerblue'))(i), label = j)
plt.title('K-NN (Test set)')
plt.xlabel('Age')
plt.ylabel('Estimated Salary')
plt.legend()
plt.show()