컴공생 누르지 마세요! 컴공생 울어요.
[ML] HA2 part2 PCA & K-NN 본문
📢 학교 수업에서 수행한 과제입니다.
이번 게시글에서는 K-NN과 PCA를 이용하여 MNIST dataset을 학습시켜 볼 것입니다.
구글 코랩에서 코드를 작성 및 실행하였습니다.
우선 MNIST dataset을 import하겠습니다.
import pandas as pd
df_train = pd.read_csv('https://media.githubusercontent.com/media/hmkim312/datas/main/mnist/mnist_train.csv')
df_test = pd.read_csv('https://media.githubusercontent.com/media/hmkim312/datas/main/mnist/mnist_test.csv')
df_train.shape, df_test.shape
train set과 test set으로 split을 수행합니다.
import numpy as np
X_train = np.array(df_train.iloc[:, 1:])
y_train = np.array(df_train['label'])
X_test = np.array(df_test.iloc[:,1:])
y_test = np.array(df_test['label'])
K-NN을 이용하여 MNIST dataset을 분류하고, accuracy와 분류에 걸린 시간을 확인해보도록 하겠습니다.
from sklearn.neighbors import KNeighborsClassifier
import time
k=10
start = time.time()
clf = KNeighborsClassifier(n_neighbors = k)
clf.fit(X_train, y_train)
train_accuracy = clf.score(X_train, y_train)
test_accuracy = clf.score(X_test, y_test)
end = time.time()
print("Train Accuracy: ", train_accuracy)
print("Test Accuracy: ", test_accuracy)
print("Time: ", end - start)
그 결과, 아래와 같은 accuracy와 time을 확인할 수 있었습니다.
Train Accuracy: 0.975 Test Accuracy: 0.9665 Time: 302.35762453079224 |
그럼 이제 K-NN과 PCA를 함께 사용하여 dimension을 줄이고, GridSearchCV를 이용하여 optimal number of principal components와 k를 찾도록 하겠습니다.
from sklearn.pipeline import Pipeline
from sklearn.decomposition import PCA
from sklearn.model_selection import GridSearchCV, KFold
pipe = Pipeline([
('pca', PCA()),
('clf', KNeighborsClassifier()),
])
parameters = {
'pca__n_components' : [2, 5, 10],
'clf__n_neighbors' : [5, 10, 15]
}
kf = KFold(n_splits=5)
grid = GridSearchCV(pipe, parameters, cv = kf, refit=True, scoring = 'accuracy', verbose=3)
grid.fit(X_train, y_train)
print("Best accuracy: ", round(grid.best_score_, 4))
print('Best parameters: ', grid.best_params_)
다음과 같은 best accuracy와 best parameters가 출력되었습니다.
K-NN에서 k 값이 5일 때, PAC에서 number of princial components가 10일 때 최적의 결과를 얻는 것을 확인할 수 있습니다.
Best accuracy: 0.9281 Best parameters: {'clf__n_neighbors': 5, 'pca__n_components': 10} |
이렇게 얻은 best parameter를 기반으로 best estimator를 구성하고, 이를 이용해서 다시 evaluation을 수행해보겠습니다.
from sklearn.metrics import accuracy_score
start = time.time()
acc = accuracy_score(y_test, grid.best_estimator_.predict(X_test))
end = time.time()
elapsed_time = end - start # time to elapse
print("Accuracy: ", acc)
print("Time to elapse: ", elapsed_time)
다음과 같은 accuracy와 time을 확인할 수 있습니다.
Accuracy: 0.9276 Time to elapse: 1.9445927143096924 |
PCA 적용 전과 후의 testing set에 대한 performance를 비교해보면 다음과 같습니다.
(1) 적용 전
accuracy: 0.9665
time: 302.35762453079224
(2) 적용 후
accuracy: 0.9276
time: 1.9445927143096924
적용 전에 비해 적용 후에 accuracy가 소폭 감소하였지만, 객관적으로 여전히 높은 accuracy를 가짐을 확인할 수 있으며, time이 대폭 감소한 것을 볼 수 있습니다. 즉, PCA가 efficiency를 개선한다고 할 수 있습니다.
그럼 왜 이렇게 시간적인 면에서 성능의 차이가 나타나는 것일까요?
그 이유는 K-NN에서 나타나는 Curse of dimensionality 때문입니다. dimension of the data가 증가할 수록 nearest neighbors에 대한 distance가 더욱 커지면서 '근접'이라는 의미가 옅어지는 것입니다.
이러한 문제를 해결하기 위해 PCA를 이용하여 dimension을 reduce하며, 그 결과 위와 같이 성능이 향상됨을 확인할 수 있습니다.
이렇게하여 K-NN과 PCA를 통한 MNIST dataset 학습에 대해 알아보았습니다.
전체 소스코드는 아래 구글 코랩 링크를 참고해주세요.
https://colab.research.google.com/drive/1budv_YFFNCNLqjwHgkp14vYbFCWcKHDf?usp=sharing
HA2_part2.ipynb
Colaboratory notebook
colab.research.google.com