컴공생 누르지 마세요! 컴공생 울어요.

[ML] HA2 part2 PCA & K-NN 본문

STUDY/기계학습

[ML] HA2 part2 PCA & K-NN

당도최고치악산멜론 2023. 2. 8. 20:35

📢 학교 수업에서 수행한 과제입니다.

 

이번 게시글에서는 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

Comments