파이썬 KNN을 이용한 알고리즘 학습입니다. 손글씨를 분류하기 입니다.
조회수 568회
파이썬 KNN을 이용한 알고리즘 학습입니다. 손글씨를 분류하기 입니다.
대학교 재학 중인데, 너무 과제가 어렵고 아는 사람도 없어서 급하게 여쭤봅니다. 갑자기 이러한 글을 올려서 죄송합니다. 샵 표시가 되어있는 부분이 코드를 작성해서 내야하는데 잘 모르겠습니다. 최대한 아는 부분에서 했는데 정답이 없어 답답하여 질문드립니다. 혹시 설명도 같이 적어주시면 정말 감사하겠습니다.
손글씨 숫자 1자리의 이미지 데이터를 7만장의 28x28 크기의 흑백 이미지로 저장해 놓은 MNIST 데이터셋을 KNN 알고리즘을 활용하여, 어떤 숫자인지 분류 해보는 실습 비어있는 코드셀을 완성하여 실행, 결과가 표시되도록 하세요.
행렬 처리에 필요한 Numpy, 그래프나 그림을 그리기 위한 pyplot, 랜덤 숫자를 생성하기 위한 random, mnist 숫자 손글씨 데이터셋을 가져오기 위한 mnist, KNN 분류기를 사용하기 위한 KNeighborsClassifier, 성능을 평가하기 위한 metrics, 행렬 데이터를 쉽게 다루기 위한 pandas 패키지를 import 한다.
import numpy as np # advanced math library
import matplotlib.pyplot as plt # MATLAB like plotting routines
import random # for generating random numbers
from keras.datasets import mnist # MNIST dataset is included in Keras
from sklearn.neighbors import KNeighborsClassifier
from sklearn import metrics
import pandas as pd
(X_train, y_train), (X_test, y_test) = mnist.load_data()
print("X_train shape", X_train.shape)
print("y_train shape", y_train.shape)
print("X_test shape", X_test.shape)
print("y_test shape", y_test.shape)
y_train_df = pd.DataFrame(y_train)
print(y_train_df.value_counts())
y_test_df = pd.DataFrame(y_test)
print(y_test_df.value_counts())
plt.rcParams['figure.figsize'] = (9,9) # Make the figures a bit bigger
for i in range(9):
plt.subplot(3,3,i+1)
num = random.randint(0, len(X_train))
plt.imshow(X_train[num], cmap='gray', interpolation='none')
plt.title("Class {}".format(y_train[num]))
plt.tight_layout()
# just a little function for pretty printing a matrix
def matprint(mat, fmt="g"):
col_maxes = [max([len(("{:"+fmt+"}").format(x)) for x in col]) for col in mat.T]
for x in mat:
for i, y in enumerate(x):
print(("{:"+str(col_maxes[i])+fmt+"}").format(y), end=" ")
print("")
# now print!
matprint(X_train[num])
X_train = X_train.reshape(1,-1) ###<= 이부분도 맞는 코드인지 모르겠습니다.
X_test = X_test.reshape(1,-1) ###<= 이부분도 맞는 코드인지 모르겠습니다.
# 손글씨 이미지 1장은 28행 28열의 2차원 행렬로 이루어져 있다. 이를 KNN 분류기에
# 입력 하기 위해, 1차원 벡터로 바꾸어 준다. 28개의 행을 가로로 이어붙여서 길게 784
# 개(28x28=784)의 원소를 갖는 1차원 벡터로 바꾸어 준다. 이를 총 7만장 의 이미지에
# 대해 모두 적용하여, 6만행 784열의 훈련용 입력 데이터 행렬과, 1만행 784열의
# 테스트용 입력 데이터 행렬을 만든다. (힌트 : reshape 메소드를 사용하라)
print("훈련용 데이터 행렬의 크기 (행 크기,열 크기)", X_train.shape)
print("테스트 데이터 행렬의 크기 (행 크기,열 크기)", X_test.shape)
mnist
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(X_train,X_test)
# KNN 분류기를 만들고, 훈련용 입력 데이터와, 훈련용 정답 데이터를 입력으로 하여
# KNN 분류기를 훈련 시킨다. 이 부분도 맞는지 모르겠습니다.
# 훈련이 완료된 KNN 분류기에 테스트 입력 데이터를 넣어서 1만장의 손글씨가
# 어떤 숫자를 나타내는지 예측하여, 예측값을 저장한다.
# 테스트 정답 데이터와 예측값을 비교하여, 정확도, 정밀도, 재현율, f1 점수를 구하여
# 성능을 평가 해 본다.
plt.rcParams['figure.figsize'] = (9,9) # Make the figures a bit bigger
incorrect_index = []
for i in range(10000):
if y_test[i] != y_pred[i]:
incorrect_index.append(i)
print('10000개의 테스트 데이터 중 틀리게 예측한 데이터의 인덱스 : {}'.format(incorrect_index))
for i in range(9):
plt.subplot(3,3,i+1)
num = random.randint(0, len(incorrect_index))
plt.imshow(X_test[incorrect_index[num]].reshape(28,28), cmap='gray', interpolation='none')
plt.title("Class {}".format(y_pred[incorrect_index[num]]))
plt.tight_layout()
# 10000개의 테스트 데이터 중 틀리게 예측한 데이터에서 9개를 랜덤하게 골라 손글씨
# 그림과 예측값을 함께 출력해 준다.
1 답변
-
직접적이 답변 대신에 도움이 될 것 같은 링크를 몇개 검색하여 알려드립니다.
- https://www.youtube.com/watch?v=jzuz-FCL3i8 : 일반적인 사이킷런에 대해 쉽게 설명해 주는 오늘코딩의 동영상튜토리얼. 문서만 봐서는 어려울 때에는 이런 동영상 강의가 도움이 됩니다. 직접적으로 knn 알고리즘을 사용하는 예는 없지만, scikit-learn 의 여러 모델들은 모델클래스가 바뀌는데 fit, predict 등의 사용법은 비슷합니다. svm 을 사용하는 부분을 우선 열심히 보세요.
- https://teddylee777.github.io/scikit-learn/scikit-learn-knn : knn 알고리즘을 사용하는 예를 설명해 놓은 블로그포스트.
- https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html : scikit-learn 공식문서, 아래쪽에 예제 부분을 보세요. scikit-learn 의 어떤 모델의 개념이나 사용법을 찾아볼 때에는 구글에서 scikit-learn 과 모델명으로 검색하여 이 문서를 찾아서 쭉 읽어보는 것이 좋습니다.
댓글 입력