본문 바로가기
Machine Learning

[혼자 공부하는 머신러닝+딥러닝] 군집 알고리즘

by 가론노미 2023. 5. 21.
[혼자 공부하는 머신러닝+딥러닝] 책의 내용을 정리한 글입니다.

개념

비지도 학습

  • 머신러닝의 한 종류로, 훈련 데이터에 타깃이 없음
  • 타깃이 없기 때문에 외부의 도움 없이 스스로 유용한 무언가를 학습해야 함
  • 대표적인 비지도 학습 - 군집, 차원 축소 등

히스토그램

  • 구간별로 값이 발생한 빈도를 그래프로 표시한 것
  • 보통 x축 - 값의 구간(계급) / y축 - 발생 빈도(도수)

군집

  • 비슷한 샘플끼리 하나의 그룹으로 모으는 대표적인 비지도 학습 작업
  • 군집 알고리즘으로 모은 샘플 그룹 → 클러스터

코드 작성

군집과 비슷하게 흑백 사진의 픽셀 평균값을 사용해 같은 과일 사진들을 모아보자.

과일 사진 데이터 준비

!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')

# 크기가 100x100인 300개의 이미지 샘플
print(fruits.shape)
# => (300, 100, 100)

# cmap을 'gray_r'로 지정하면 값을 반전하여 출력
fig, axs = plt.subplots(1, 3)
axs[0].imshow(fruits[0], cmap='gray_r')
axs[1].imshow(fruits[100], cmap='gray_r')
axs[2].imshow(fruits[200], cmap='gray_r')
plt.show()

사과 / 파인애플 / 바나나 - 샘플 이미지

각 이미지 별 픽셀 평균값 확인

apple = fruits[0:100].reshape(-1, 100*100)
pineapple = fruits[100:200].reshape(-1, 100*100)
banana = fruits[200:300].reshape(-1, 100*100)

# mean() 메서드는 axis=0인 경우 행 방향으로 계산, axis=1인 경우 열 방향으로 계산
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()

사과와 파인애플은 형태와 크기가 비슷하여 픽셀 평균값이 겹쳐 있다

샘플의 픽셀 평균값이 아닌 전체 샘플에 대해 픽셀별 평균값 확인

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()

사과 / 파인애플 / 바나나 - 픽셀별 평균값

위에서 구한 픽셀별 평균값으로 이미지 출력

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()

사과 / 파인애플 / 바나나 - 픽셀별 평균값을 통해 출력한 대표 이미지

절댓값 오차를 사용하여 평균값과 가까운 사진 모아 보기

# 샘플별로 사과의 평균값을 뺀 절댓값의 평균을 계산
abs_diff = np.abs(fruits - apple_mean)
abs_mean = np.mean(abs_diff, axis=(1,2))
print(abs_mean.shape)
# => (300,)

# 사과의 평균값과 절댓값 오차가 가장 작은 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()

# 바나나의 평균값과 절댓값 오차가 가장 작은 100개의 샘플
abs_diff = np.abs(fruits - banana_mean)
abs_mean = np.mean(abs_diff, axis=(1,2))

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()