Python/Sklearn

[Sklearn] 파이썬 서포트 벡터 머신 분류기(SVM) - SVC 함수 사용법

jimmy_AI 2021. 11. 22. 11:19
반응형

이번 글에서는 대표적인 머신러닝을 이용한 분류기 중 하나인 서포트 벡터 머신(SVM)을

파이썬 사이킷런에서 구현하고 결과를 확인하는 과정을 간단히 살펴보도록 하겠습니다.

 

이 글에서는 사이킷런에서 제공하는 기본 데이터셋인 아이리스 꽃 분류 데이터셋을 활용하였습니다.

 

파이썬 사이킷런 서포트 벡터 머신 분류기 SVM 사전 작업

우선, 모듈을 임포트하고, 아이리스 꽃 분류 데이터셋을 가져오도록 하겠습니다.

from sklearn.datasets import load_iris
import pandas as pd
import numpy as np

# 데이터셋 로드
iris = load_iris()
df = pd.DataFrame(data= np.c_[iris.data, iris.target] , 
                  columns= ['sepal length', 'sepal width', 'petal length', 'petal width', 'target'])

 

분류 작업에 데이터셋을 활용하기 위하여 train, test 데이터 셋 분류를 이어서 진행하도록 하겠습니다.

from sklearn.model_selection import train_test_split

# train, test 데이터셋 분리
X = df[df.columns[:-1]]
y = df['target']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 123)

 

SVM 활용에서 커널 함수를 활용하기 위해서는 반드시 정규화가 필요합니다. 따라서, 사이킷런의 정규화 함수를 가져와 학습 데이터셋을 기준으로 정규화 모듈을 학습시키겠습니다. 이후, Sklearn SVM 모듈의 SVC 함수를 선언하여 서포트 벡터 머신 분류기를 학습시키도록 하겠습니다.

from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler

# 정규화 작업
scaler = StandardScaler()
scaler.fit(X_train)
X_train = scaler.transform(X_train)

# SVM 모델 생성
model = SVC(kernel='poly', C = 3, degree = 3)
model.fit(X_train, y_train)

파이썬 사이킷런 SVM 하이퍼파라미터

SVM 분류기는 하이퍼파라미터로 커널 함수 종류, 정규화 조건 등을 변경할 수 있는데, 조건에 따라 학습되는 방식이 매우 크게 차이가 납니다. 따라서, 여러 하이퍼파라미터를 테스트해보는 것이 중요합니다. 다만, SVM은 시간 복잡도가 최대 \(O(n^3)\)으로, 비교적 복잡한 분류 알고리즘이니, 데이터셋이 클 경우 주의하시길 바랍니다.

 

SVC함수에서 지정가능한 대표적인 인자 목록은 다음과 같습니다.

 

kernel : 커널 함수 종류를 지정합니다. 'linear', 'poly', 'rbf', 'sigmoid', 'precomputed' 중에서 지정 가능하며, 기본 값은 'rbf'로 설정되어 있습니다.

C : regularization의 정도를 지정합니다. 클수록 L2 panelty가 증가합니다. 기본 값은 1.0으로 설정되어있습니다.

degree : kernel이 'poly'일 때만 유효합니다. 커널 함수를 몇차 함수로 지정할지를 결정합니다.

gamma : 'scale'과 'auto' 중에서 지정 가능합니다.  커널 함수가 'rbf', 'poly', 'sigmoid' 인 경우에 유효하며, 커널 계수를 지정하는 하이퍼파라미터입니다.

random_state : 다른 머신러닝 모델과 마찬가지로 seed를 지정하여 실행시마다 결과를 고정하는 역할을 수행합니다.

 

SVM 성능 평가

테스트 데이터셋을 기준으로 target 라벨 예측을 진행한 뒤, 실제 라벨과 비교하여 예측 정확도를 살펴보도록 하겠습니다. 여기서, train 데이터셋을 기준으로 학습되었던 정규화 모듈을 테스트 데이터셋에도 이용해주어야 합니다.

from sklearn.metrics import accuracy_score

# test 데이터셋도 정규화(train 데이터셋 기준으로 학습시킨 정규화 모듈 사용)
X_test = scaler.transform(X_test)

y_pred = model.predict(X_test) # 예측 라벨
accuracy_score(y_test, y_pred)

여기서는 약 91% 정도의 정확도를 나타냈는데, SVC 함수의 하이퍼파라미터 조건을 바꾸면 크게 변동이 있었습니다.

SVM 결과 비교 시각화

마지막으로, test 데이터셋을 기준으로 실제 라벨과 예측 라벨의 데이터 분포를 시각화 해보도록 하겠습니다. 다만, iris 데이터셋에서는 feature가 4개이므로, 2차원으로 PCA 차원 축소 후 시각화를 진행해보도록 하겠습니다.

import matplotlib.pyplot as plt
from sklearn.decomposition import PCA

# SVM 결과로 시각화(PCA 2차원 축소 후 결과 확인)
pca = PCA(n_components=2)

# test 데이터셋 기준 시각화 진행
X_test_pca = pca.fit_transform(X_test)
y_find = y_test.reset_index(drop = True)

# target 마다 index 가져오기(꽃 종류마다 색깔을 다르게 시각화 목적) : 실제 라벨 기준
index_0 = y_find[y_find == 0].index
index_1 = y_find[y_find == 1].index
index_2 = y_find[y_find == 2].index

# target 마다 index 가져오기(꽃 종류마다 색깔을 다르게 시각화 목적) : 예측 라벨 기준
y_pred_Series = pd.Series(y_pred)
index_0_p = y_pred_Series[y_pred_Series == 0].index
index_1_p = y_pred_Series[y_pred_Series == 1].index
index_2_p = y_pred_Series[y_pred_Series == 2].index

# 시각화
plt.figure(figsize = (12, 6))
plt.subplot(121)
plt.scatter(X_test_pca[index_0, 0], X_test_pca[index_0, 1], color = 'purple', alpha = 0.6, label = 'setosa')
plt.scatter(X_test_pca[index_1, 0], X_test_pca[index_1, 1], color = 'green', alpha = 0.6, label = 'versicolor')
plt.scatter(X_test_pca[index_2, 0], X_test_pca[index_2, 1], color = 'yellow', alpha = 0.6, label = 'virginica')
plt.title('Real target', size = 13)
plt.legend()

plt.subplot(122)
plt.scatter(X_test_pca[index_0_p, 0], X_test_pca[index_0_p, 1], color = 'purple', alpha = 0.6, label = 'setosa')
plt.scatter(X_test_pca[index_1_p, 0], X_test_pca[index_1_p, 1], color = 'green', alpha = 0.6, label = 'versicolor')
plt.scatter(X_test_pca[index_2_p, 0], X_test_pca[index_2_p, 1], color = 'yellow', alpha = 0.6, label = 'virginica')
plt.title('SVM result', size = 13)
plt.legend()
plt.show()

데이터 분포를 보아하니, 실제 라벨과도 제법 결과가 잘 들어맞는 것으로 보입니다. 물론 이 부분도 커널 함수 종류 등을 변경하면 양상이 달라질 수 있습니다. 여기까지 파이썬 사이킷런에서 SVM 기법을 데이터셋에 적용하는 방법에 대해서 간단히 다루어보았습니다.