본문 바로가기

파이썬

[python] 머신러닝 MNIST 필기체 숫자 이미지 분류

반응형

이번 시간에는 머신러닝 분야에서 가장 유명한 데이터셋 중 하나인

 

MNIST(Mixed National Institute of Standards and Technology)에 대해 알아보고

 

sklearn을 사용하여 필기체 숫자 이미지를 분류해 봅시다.

 

Mnist 데이터셋 예시                                                                                             (출처:https://sdc-james.gitbook.io/onebook/4.-and/5.1./5.1.3.-mnist-dataset)

 

MNIST 데이터셋에 대해 간략히 알아보겠습니다. MNIST 데이터셋은 0부터 9까지의 숫자로 이루어진 28x28 픽셀 크기의 흑백 이미지로 구성되어 있습니다. 훈련 데이터셋에는 60,000개의 이미지가 있고, 테스트 데이터셋에는 10,000개의 이미지가 있습니다. 각 이미지는 해당하는 숫자의 레이블(0부터 9까지의 정수)이 주어져 있어 이미지 분류 작업을 수행할 수 있습니다.

 

 

1. 데이터 세트 읽기

import matplotlib.pyplot as plt
from sklearn import datasets, metrics
from sklearn.model_selection import train_test_split
digits = datasets.load_digits()
plt.imshow(digits.images[0], cmap=plt.cm.gray_r, interpolation='nearest')

 

datasets.load_digits()를 호출하여 Mnist의 데이터 세트의 일부를 가져와서

images[0]의 이미지를 출력해본다

 

cmap은 color map을 지정하는 변수로 이미지를 그릴 때 각 픽셀의 색상을 결정한다.

plt.cm.gray_r은 회색조 컬러 맵을 나타냅니다.

 

interpolation은 이미지의 픽셀 사이의 값을 추정하는 방법을 지정하는 변수로 

이미지를 확대 또는 축소할 때 픽셀 사이의 값을 보간(interpolation)하여 부드럽게 표현할 수 있다.

nearest는 가장 가까운 픽셀의 값을 사용하여 보간하는 방법을 의미한다.

따라서 이미지를 보여줄 때 픽셀 사이의 값을 보간하지 않고 가장 가까운 픽셀의 값을 사용하여 표시

 

images[0] 실행화면

2. 로드한 데이터 1차원으로 평탄화(flatten)

로드한 데이터들은 2차원 배열로 되어 있는데, 이를 1차원으로 변경해주어야 머신러닝 알고리즘에 사용할 수 있다. 이를 보통 평탄화(flatten)시킨다고 한다.

숫자 2 Flatten 예시

8*8의 배열을 64로 변경하여야 한다.

n_samples = len(digits.images)
data = digits.images.reshape((n_samples, -1))

전체 데이터 세트 (n_samples, 8, 8) 에서 (n_samples, 64)로 변경하여야 한다.

n_samples는 이미지의 총 개수이고 64는 한 이미지가 가지고 있는 픽셀의 총 개수이다.

 

3. 훈련 데이터와 테스트 데이터 분할

X_train, X_test, y_train, y_test = train_test_split(data, digits.target, test_size=0.2)

평탄화(Flatten)된 데이터를 훈련데이터(X_train, y_train)와 테스트데이터(X_test, y_test)로 분할한다.

test_size는 분할 비율인데 보통 20%로 한다. 

 

4. k-최근접 이웃(KNN, K-Nearest Neighbors) 분류기 생성 모델

 

from sklearn.neighbors import KNeighborsClassifier

knn=KNeighborsClassifier(n_neighbors=6)

k-최근접 이웃 분류기는 훈련 데이터셋 내에서 입력 데이터 포인트와 가장 가까운 k개의 이웃을 찾아서 다수결(majority voting) 방식으로 분류합니다. 이웃들의 레이블 중 가장 많은 레이블을 예측값으로 사용하는 방법입니다.

 

예를 들어, k=6일 때 주변 6개의 이웃 중 4개가 "3"이라는 레이블을 가지고 있다면, 입력 데이터 포인트의 예측값은 "3"이 됩니다.

 

4. KNN 학습

knn.fit(X_train, y_train)

X_train: 훈련 데이터셋의 입력 특징(features)을 나타내는 배열입니다. 이는 모델이 학습할 때 사용되는 입력 데이터입니다. 각 행은 개별 데이터 포인트를 나타내며, 각 열은 해당 데이터 포인트의 특징 값을 나타냅니다.

y_train: 훈련 데이터셋의 목표 변수(target variable) 또는 레이블을 나타내는 배열입니다. 이는 모델이 학습할 때 사용되는 정답 데이터입니다. X_train에 대응하는 각 데이터 포인트의 실제 클래스 레이블을 나타냅니다.

 

 

5. 예측 및 평가

 

y_pred= knn.predict(X_test)
scores = metrics.accuracy_score(y_test, y_pred)
print(scores)

accuracy_score() 실제 레이블(y_test)과 예측된 레이블(y_pred)을 비교하여 분류 모델의 정확도를 계산합니다.

 

테스트 데이터셋(y_test)에 대한 예측 결과(y_pred)와 실제 레이블을 비교하여 모델의 정확도를 계산하고 출력

 

<실행결과>

0.9777777777777777

 

 

테스트 데이터셋에서 11번째 이미지 X_test[10]을 출력해보고 예측 결과를 확인해 보자.

plt.imshow(X_test[10].reshape(8,8), cmap=plt.cm.gray_r, interpolation='nearest')
y_pred=knn.predict([X_test[10]])
print(y_pred)

먼저 reshape(8,8)를 통해 해당 이미지를 8x8 크기로 변형하고

 

y_pred = knn.predict([X_test[10]]): knn 분류기를 사용하여 해당 이미지(X_test[10])의 예측을 수행합니다.

 

반응형