파이썬 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 답변

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)