머신러닝 기초 | 군집 알고리즘(1) | 픽셀 평균값(mean 함수)과 절댓값 오차(abs 함수)로 과일 분류하기 | 넘파이 배열 1차원으로 만드는 법(reshape 함수) | np.argsort() 함수로 인덱스 정렬

    728x90

     

    1. 과일 데이터 불러오기

     

    ▶ 과일 사진 데이터 준비

    !wget https://bit.ly/fruits_300 -O fruits_300.npy
    import numpy as np
    import matplotlib.pyplot as plt

     

    ▶ 넘파이에서 npy 파일 로드

    : load() 메서드에 파일 이름을 전달

    fruits = np.load('fruits_300.npy')

    : fruits는 fruits_300.npy 파일에 들어있는 모든 데이터를 담고 있음

    : 이 데이터에는 사과, 바나나, 파인애플이 각각 100개씩 들어있음

    print(fruits.shape)

    >> 배열의 첫 번째 차원(300)은 샘플의 개수

    >> 배열의 두 번째 차원(100)은 이미지 높이

    >> 배열의 세 번째 차원(100)은 이미지 너비

     

    ▶ 첫 번째 행을 출력

    print(fruits[0, 0, :])

     

    ▶ matplotlib으로 [0]번째 이미지 그려보기(1)

    plt.imshow(fruits[0], cmap='gray')
    plt.show()

     

    ▶ matplotlib으로 [0]번째 이미지 그려보기(2)_색 반전

    plt.imshow(fruits[0], cmap='gray_r')
    plt.show()

     

    ▶ 바나나와 파인애플 이미지도 출력

    fig, axs = plt.subplots(1, 2)
    axs[0].imshow(fruits[100], cmap='gray_r')
    axs[1].imshow(fruits[200], cmap='gray_r')
    plt.show()

    >> subplot() 함수로 여러 개의 그래프를 배열처럼 쌓을 수 있음

    >> subplot(1,2)는 1개의 행, 2개의 열

    >> 100x100 사이즈의 이미지

     

     


    2. 픽셀 값 분석하기

     

    ▶ 넘파이 배열을 1차원 배열로 만들기

    : 넘파이 배열을 나눌 때 100x100 이미지를 펼쳐서 길이가 10,000인 1차원 배열로 만듦

    → fruits 배열에서 순서대로 100개씩 선택하기 위해 슬라이싱 연산자를 이용

    reshape() 메서드로 두 번째 차원(100)과 세 번째 차원(100)을 10,000으로 합침

    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)
    print(pineapple.shape)
    print(banana.shape)

    >> apple, pineapple, banana 배열의 크기는 (100, 10000)

     

    ▶ 샘플의 픽셀 평균값 계산

     

    * apple 배열, 각 샘플의 픽셀 평균값 구하기

    print(apple.mean(axis=1))

    : 넘파이 mean() 메서드 사용

    : 샘플마다 픽셀의 평균값을 계산해야 하므로 mean() 메서드가 평균을 계산할 축을 지정

    → axis = 0으로 하면 첫 번째 축이 행을 따라 계산

     

    * 히스토그램으로 픽셀 평균값 분포 살펴보기(평균값 비교)

    : 맷플롯립의 hist() 함수 사용

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

    : legend() 함수로 어떤 과일의 히스토그램인지 범례 만들기

    >> 바나나 사진의 평균값은 40 아래에 집중되어 있음

    >> 사과와 파인애플의 평균값은 90-100 사이에 집중되어 있음

    (사과나 파인애플은 대체로 형태가 동그랗고, 사진에서 차지하는 크기도 비슷하기 때문)

    >> 바나나는 픽셀 평균값만으로 사과나 파인애플과 확실히 구분 가능

     

    * 막대그래프로 픽셀 평균값 분포 살펴보기(평균값 비교)

    : 맷플롯립의 bar() 함수 사용

    → 픽셀 10,000개에 대한 평균값을 그려봄

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

    : axis = 0으로 픽셀의 평균 계산

    >> 과일마다 값이 높은 구간이 다름

    >> 사과는 사진 아래쪽으로 갈수록 값이 높아지고, 파인애플은 비교적 고르면서 높고, 바나나는 중앙의 픽셀값이 높음

     

    ▶ 픽셀 평균값을 이미지로 출력

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

    : 픽셀 평균값을 100x100 크기로 바꿔서 이미지처럼 출력

    >> 픽셀을 평균 낸 모든 사진을 합쳐놓은 이미지

     

     


    3. 평균값과 가까운 사진 고르기

     

    ▶ 절댓값 오차 사용하기

    : abs() 함수로 절댓값 계산

    : 절댓값 오차를 사용해 apple_mean()과 가장 가까운 사진을 골라옴

    : fruits 배열에 있는 모든 샘플에서 apple.mean을 뺀 절댓값의 평균을 계산

    abs_diff = np.abs(fruits - apple_mean)
    abs_mean = np.mean(abs_diff, axis=(1,2))
    print(abs_mean.shape)

     

    ▶ 오차가 가장 작은 샘플 100개 고르기

    : np.argsort() 함수는 작은 것부터 큰 것 순서대로 나열한 abs_mean 배열의 인덱스를 반환

    → apple_mean과 오차가 가장 작은 샘플 100개를 고르는 셈

    : 인덱스 중에서 처음 100개를 선택해 10x10 격자로 이루어진 그래프 그리기

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

     

     


    4. 확인문제

     

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

    728x90

    댓글