본문 바로가기
딥러닝 & 머신러닝/혼자 공부하는 머신러닝 딥러닝

6-1. 군집 알고리즘

by sim0609 2023. 2. 17.

군집 알고리즘

이번에는 타깃(정답)을 모르는 사진을 종류별로 분류하려 한다.

이렇게 정답이 없을 때 사용하는 머신러닝 알고리즘을 '비지도 학습'이라 한다.

 

타깃값이 없을 때 데이터에 있는 패턴을 찾거나 데이터 구조를 파악해야하는게 핵심이다.  따라서, 흑백 과일 사진에 있는 픽셀값을 통해 비슷한 과일 샘플 그룹끼리 모아보자(군집 활용)

 

소스 코드

!wget https://bit.ly/fruits_300_data -O fruits_300.npy

import numpy as np
import matplotlib.pyplot as plt

# 과일 사진 데이터
fruits = np.load('fruits_300.npy')

# 샘플 개수: 300개
# 이미지 크기(배열의 크기): 100 * 100
print(fruits.shape)

# 첫 번째 이미지 확인
# 넘파이 배열은 흑백 사진을 담고 있기 때문에 0 ~ 255까지의 정숫값을 가짐
plt.imshow(fruits[0], cmap = 'gray')
plt.show()

# 현재 이미지는 흑백이 반전된 이미지이기 때문에 밝은 색은 짙게, 짙은 색은 밝게 나온다
# 다시 보기 좋게 이미지를 처리하자
# 여기서 밝은 부분은 0에 가깝고 짙은 부분은 255에 가깝다
plt.imshow(fruits[0], cmap = 'gray_r')
plt.show()

# 바나나와 파인애플 이미지도 출력하기
# subplots() 함수로 그래프를 쌓을 행과 열 지정
fig, axs = plt.subplots(1, 2)
axs[0].imshow(fruits[100], cmap = 'gray_r')
axs[1].imshow(fruits[200], cmap = 'gray_r')
plt.show()

# 배열 계산을 편리하게 하기 위해서 각 이미지를 길이가 10000인 1차원 배열로 만들어보자
# 지금 사용하는 데이터는 사과, 파인애플, 바나나가 각각 100개로 이루어져 있음
# 각 과일의 샘플 개수: 100개, 각 과일의 이미지 크기(배열의 크기): 1 * 10000
apple = fruits[0:100].reshape(-1, 100 * 100)
pineapple = fruits[100:200].reshape(-1, 100*100)
banana = fruits[200:300].reshape(-1, 100*100)
print(apple.shape)

# apple, pineapple, banana 배열에 들어있는 샘플의 픽셀 평균값을 계산해보자
# 히스토그램을 통해 각 샘플들(이미지들)의 평균값이 어떻게 분포되는지 확인해보자
# 각 샘플들의 픽셀 평균값으로는 파인애플과 사과를 구별할 수 없음
# 가로: 각 이미지 샘플의 평균값 / 세로: 각 이미지의 개수
plt.hist(np.mean(apple, axis = 1), alpha = 0.8)
plt.hist(np.mean(pineapple, axis = 1), alpha = 0.8)
plt.hist(np.mean(banana, axis = 1), alpha = 0.8)
plt.legend(['apple', 'pineapple', 'banana'])
plt.show()

# 각 과일별 전체 샘플에 대해 각 픽셀별 평균을 구해보자
# 사과는 아래로 갈수록 픽셀값이 높아지고, 파인애플은 픽셀값이 비교적 고르면서 높고, 바나나는 중앙의 픽셀값이 높다
# 가로: 픽셀 / 세로: 100개 샘플의 각 픽셀별 평균
fig, axs = plt.subplots(1, 3, figsize=(20, 5))
axs[0].bar(range(10000), np.mean(apple, axis = 0))
axs[1].bar(range(10000), np.mean(pineapple, axis = 0))
axs[2].bar(range(10000), np.mean(banana, axis = 0))
plt.show()

# 픽셀 평균값을 다시 100 * 100 크기로 바꿔서 이미지처럼 출력
# 픽셀을 평균낸 이미지는 모든 사진을 합쳐놓은 대표 이미지로 생각할 수 있다
apple_mean = np.mean(apple, axis = 0).reshape(100, 100)
pineapple_mean = np.mean(pineapple, axis = 0).reshape(100, 100)
banana_mean = np.mean(banana, axis = 0).reshape(100, 100)
fig, axs = plt.subplots(1, 3, figsize=(20, 5))
axs[0].imshow(apple_mean, cmap = 'gray_r')
axs[1].imshow(pineapple_mean, cmap = 'gray_r')
axs[2].imshow(banana_mean, cmap = 'gray_r')
plt.show()

# 이렇게 만들어진 대표 이미지로 과일을 구별해보자
# 사과 사진의 평균값인 apple_mean과 가장 가까운 사진 고르기 -> 절댓값 오차 이용
abs_diff = np.abs(fruits - apple_mean)
abs_mean = np.mean(abs_diff, axis=(1, 2))
print(abs_mean.shape)

# apple_mean과 오차가 가장 작은 샘플 100개 고르기
apple_index = np.argsort(abs_mean)[:100]
fig, axs = plt.subplots(10, 10, figsize = (10, 10))
for i in range(10):
  for j in range(10):
    axs[i, j].imshow(fruits[apple_index[i*10+j]], cmap = 'gray_r')
    axs[i, j].axis('off')
plt.show()  

# 파인애플 사진의 평균값인 pineapple_mean과 가장 가까운 사진 고르기 -> 절댓값 오차 이용
abs_diff = np.abs(fruits - pineapple_mean)
abs_mean = np.mean(abs_diff, axis=(1, 2))
print(abs_mean.shape)

# pineapple_mean과 오차가 가장 작은 샘플 100개 고르기
pineapple_index = np.argsort(abs_mean)[:100]
fig, axs = plt.subplots(10, 10, figsize = (10, 10))
for i in range(10):
  for j in range(10):
    axs[i, j].imshow(fruits[pineapple_index[i*10+j]], cmap = 'gray_r')
    axs[i, j].axis('off')
plt.show()     

# 바나나 사진의 평균값인 banana_mean과 가장 가까운 사진 고르기 -> 절댓값 오차 이용
abs_diff = np.abs(fruits - banana_mean)
abs_mean = np.mean(abs_diff, axis = (1, 2))
print(abs_mean)

# banana_mean과 오차가 가장 작은 샘플 100개 고르기
banana_index = np.argsort(abs_mean)[:100]
fig, axs = plt.subplots(10, 10, figsize = (10, 10))
for i in range(10):
  for j in range(10):
    axs[i, j].imshow(fruits[banana_index[i*10 + j]], cmap = 'gray_r')
    axs[i, j].axis('off')
plt.show()

'딥러닝 & 머신러닝 > 혼자 공부하는 머신러닝 딥러닝' 카테고리의 다른 글

6-2. k-평균  (0) 2023.02.18
5-2. 교차 검증과 그리드 서치  (0) 2023.02.17
5-1. 결정 트리  (0) 2023.02.15
4-2. 확률적 경사 하강법  (0) 2023.02.14
4-1. 로지스틱 회귀  (0) 2023.02.14