머신 러닝 - PCA 활용(1)

이상해씨·2021년 12월 5일
0

머신 러닝

목록 보기
25/27

◾PCA eigenface

  • olivetti 데이터
    • AT&T와 캠브리지 대학의 공동 연구 데이터
    • 얼굴 인식용으로 사용 가능
    • 특정 인물의 데이터(10장)만 이용하여 PCA 실습으로 사용
from sklearn.datasets import fetch_olivetti_faces

faces_all = fetch_olivetti_faces()

- 데이터 선택

K = 20
faces = faces_all.images[faces_all.target == K]

faces

import matplotlib.pyplot as plt

N = 2
M = 5
fig = plt.figure(figsize=(10, 5))
plt.subplots_adjust(top = 1, bottom=0, hspace=0, wspace=0.05)
for n in range(N*M):
    ax = fig.add_subplot(N, M, n+1)
    ax.imshow(faces[n], cmap=plt.cm.bone)
    ax.grid(False)
    ax.xaxis.set_ticks([])
    ax.yaxis.set_ticks([])
plt.suptitle("Olivetti")
plt.tight_layout()
plt.show()

- PCA 분석(2개의 주성분 선택)

from sklearn.decomposition import PCA

pca = PCA(n_components=2)

X = faces_all.data[faces_all.target==K]
W = pca.fit_transform(X)

X_inv = pca.inverse_transform(W)
  • 결과 그리기
import matplotlib.pyplot as plt
def draw_faces(faces, N, M, title='', inv = False):
    fig = plt.figure(figsize=(10, 5))
    plt.subplots_adjust(top = 1, bottom=0, hspace=0, wspace=0.05)
    for n in range(N*M):
        ax = fig.add_subplot(N, M, n+1)
        if inv == False:
            ax.imshow(faces[n], cmap=plt.cm.bone)
        else:
            ax.imshow(faces[n].reshape(64, 64), cmap=plt.cm.bone)
        ax.grid(False)
        ax.xaxis.set_ticks([])
        ax.yaxis.set_ticks([])
    plt.suptitle(title)
    plt.tight_layout()
    plt.show()
draw_faces(X_inv, 2, 5, 'PCA result', True)

- 원점과 두 개의 eigen face

  • 10장의 사진은 아래 3장으로 모두 표현할 수 있다.
face_mean = pca.mean_.reshape(64, 64)
face_p1 = pca.components_[0].reshape(64, 64)
face_p2 = pca.components_[1].reshape(64, 64)

plt.figure(figsize=(12, 7))
plt.subplot(131)
plt.imshow(face_mean, cmap=plt.cm.bone)
plt.grid(False); plt.xticks([]); plt.yticks([]); plt.title('mean')
plt.subplot(132)
plt.imshow(face_p1, cmap=plt.cm.bone)
plt.grid(False); plt.xticks([]); plt.yticks([]); plt.title('face_p1')
plt.subplot(133)
plt.imshow(face_p2, cmap=plt.cm.bone)
plt.grid(False); plt.xticks([]); plt.yticks([]); plt.title('face_p2')
plt.show()

- 가중치 선정

import numpy as np

N = 2
M = 5
w = np.linspace(-5, 10, N*M)
w

- 첫 번째 성분 변화

fig = plt.figure(figsize=(10, 5))
plt.subplots_adjust(top=1, bottom=0, hspace=0, wspace=0.05)

for n in range(N*M):
    ax = fig.add_subplot(N, M, n+1)
    ax.imshow(face_mean + w[n] * face_p1, cmap=plt.cm.bone)
    plt.grid(False); plt.xticks([]); plt.yticks([]); 
    plt.title('Weight :' + str(round(w[n])))

plt.tight_layout()
plt.show()

- 두 번째 성분 변화

fig = plt.figure(figsize=(10, 5))
plt.subplots_adjust(top=1, bottom=0, hspace=0, wspace=0.05)

for n in range(N*M):
    ax = fig.add_subplot(N, M, n+1)
    ax.imshow(face_mean + w[n] * face_p2, cmap=plt.cm.bone)
    plt.grid(False); plt.xticks([]); plt.yticks([]); 
    plt.title('Weight :' + str(round(w[n])))

plt.tight_layout()
plt.show()

- 두 개의 성분 표현

nx, ny = (5, 5)

x = np.linspace(-5, 8, nx)
y = np.linspace(-5, 8, ny)
w1, w2 = np.meshgrid(x, y)
w1, w2

  • shape 조정
w1.shape

w1 = w1.reshape(-1, )
w2 = w2.reshape(-1, )
w1.shape

  • 재합성
fig = plt.figure(figsize=(12, 10))
plt.subplots_adjust(top=1, bottom=0, hspace=0, wspace=0.05)

N = 5
M = 5

for n in range(N*M):
    ax = fig.add_subplot(N, M, n+1)
    ax.imshow(face_mean + w1[n] * face_p1 + w2[n] * face_p2, cmap=plt.cm.bone)
    plt.grid(False); plt.xticks([]); plt.yticks([]); 
    plt.title('Weight :' + str(round(w1[n], 1)) + ', ' + str(round(w2[n], 1)))

plt.show()


profile
후라이드 치킨

0개의 댓글