컴공생 누르지 마세요! 컴공생 울어요.
[ML] HA1 part2 Support vector machines with Iris dataset 본문
📢 학교 수업에서 수행한 과제입니다.
이번 게시글에서는 Iris dataset에 대해 SVM을 학습해볼 것이다.
구글 코랩에서 코드를 작성 및 실행하였으며, 전체 코드는 아래 링크를 참고하라.
https://colab.research.google.com/drive/1r0RvW8XH62gozq3JdvmW3hd1gwIfZuIo?usp=sharing
HA1_part2.ipynb
Colaboratory notebook
colab.research.google.com
그럼 우선 iris 데이터셋을 불러온다.
from sklearn.datasets import load_iris
iris_dataset = load_iris()
X = iris_dataset['data']
y = iris_dataset['target']
이제 데이터셋을 train set과 test set으로 나눠준다. overfitting을 방지하기 위해 training에는 train set을, testing에는 test set을 사용해준다.
# Split the dataset into training and testing sets
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)
StandardScaler function을 사용해서 모든 data points를 mean = 0, std = 1로 매핑시켜준다.
from sklearn.preprocessing import StandardScaler
def scaler_samples(train_X,test_X):
scaler = StandardScaler()
train_X = scaler.fit_transform(train_X)
test_X = scaler.transform(test_X)
return train_X, test_X
x_train, x_test = scaler_samples(x_train, x_test)
이제 SVM을 학습시켜보자. 이때, Linear kernel과 RBF kernel 두 가지를 사용해보고, hyperparameter tuning을 적용해 performance가 개선되는지 확인해 볼 것이다.
우선 Linear kernel을 이용해서 SVM을 training한다.
# Train SVM using linear kernel
from sklearn.svm import LinearSVC, SVC
classifier = LinearSVC(C=1.0, loss='hinge')
classifier.fit(x_train, y_train)
# Test SVM using linear kernel
y_pred = classifier.predict(x_test)
# Report accuracy
from sklearn.metrics import accuracy_score
print("accuracy on test dataset: {}".format(accuracy_score(y_test, y_pred)))
84% 정도의 accuracy가 나왔다.
5-fold cross validation을 적용해보자.
# 5-fold cross validation
from sklearn.model_selection import cross_val_score
scores = cross_val_score(classifier, x_test, y_test, cv=5)
# Report accuracies from each fold and the mean accuracy after taking the mean on five accuracies.
print('cross-val-score: {}'.format(scores))
print('cross-val-score.mean: {}'.format(scores.mean()))
score가 약 80% 정도다.
이제 RBF kernel을 이용해서 SVM을 학습해보자.
classifier_w_rbf = SVC(kernel = 'rbf', C=1.0, gamma=0.01, random_state=0)
classifier_w_rbf.fit(x_train, y_train)
y_pred = classifier_w_rbf.predict(x_test)
print("accuracy on test dataset: {}".format(accuracy_score(y_test, y_pred)))
accuracy가 87% 정도이다. linear kernel에 비해 소폭 상승했다.
이제 5-fold cross validation을 적용해보자.
scores = cross_val_score(classifier_w_rbf, x_test, y_test, cv=5)
print('cross-val-score: {}'.format(scores))
print('cross-val-score.mean: {}'.format(scores.mean()))
score가 76% 정도로 나왔다.
이제 Grid Search를 이용하여 Hyperparameter tuning을 해볼 것이다.
grid search를 통해 주어진 hyperparameter 그룹에 대한 모든 조합을 시도해보고, 그 중 best parameter 조합과 best accuracy를 확인할 수 있다.
코드는 다음과 같다.
from sklearn.model_selection import GridSearchCV
# define parameter search space
param_grid = {'C': [0.1, 1, 10, 100],
'gamma': [1.0, 0.1, 0.01, 0.001],
'kernel': ['rbf', 'poly', 'sigmoid']}
grid = GridSearchCV(SVC(), param_grid, refit = True, verbose = 3)
# fit the model for grid search
grid.fit(x_train, y_train)
# Report best parameters after grid search
print(grid.best_params_)
# Report accuracy
grid_pred = grid.predict(x_test)
print("accuracy on test dataset: {}".format(accuracy_score(y_test, grid_pred)))
best parameter와 best accuracy가 위와 같이 출력되었다.
rbf, poly, sigmoid 커널 중 sigmoid가 best parameter로 출력되었는데, 사실 iris dataset이 multiclass classification인만큼 예상치 못한 결과였다. 보통 sigmoid는 binary classification에서 더 좋은 성능을 보이고, multiclass classification에서는 rbf가 더 좋은 성능을 보이는 것으로 알려져 있기 때문이다.
하지만 위에서 출력된, 각 parameter별 grid search cross validation 결과값에 따르면 C가 10 이상일 때, gamma가 0.1 이하일 때 rbf보다 sigmoid가 더 우세한 성능을 보이는 순간이 있다.
이는 C가 커지면 soft margin svm에서 max(0, 1−" 𝑦_𝑖 (𝑤^𝑇 𝑥_𝑖+𝑏)") 부분이 강조되면서 decision boundary가 더욱 정교화되는데, 이때 iris dataset의 outlier들을 처리하는 데 sigmoid 커널이 rbf보다 더 좋은 성능을 보이기 때문에 결과적으로 rbf가 아닌 sigmoid 커널이 best parameter로 출력된 것이라고 생각한다.
또한, Linear kernel과 RBF kernel, Hyperparameter tuning 시 accuracy를 비교해보자.
linear kernel을 사용하였을 경우의 accuracy는 0.8421, RBF kernel을 사용하였을 경우의 accuracy는 0.8684, hyperparameter tuning 후의 accuracy는 0.973이었다.
linear kerenl이나 RBF kernel을 사용하였을 때보다 tuning 후 accuracy가 향상되었기 때문에 hyperparameter tuning이 performance improvement에 효과가 있다고 할 수 있다.