PCA(Olivetti 데이터)

yeoni·2023년 6월 17일
0

머신러닝

목록 보기
27/40

데이터 확인

  • 특정 샘플만 선택(20번째 사람의 10개 사진)
from sklearn.datasets import fetch_olivetti_faces

faces_all = fetch_olivetti_faces()

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

import matplotlib.pyplot as plt

N = 2
M = 5
fig = plt.figure(figsize=(10, 5))
plt.subplots_adjust(top=1, bottom=0, hspace=0.5, 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()

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) #(10, 4096) -> 4096 = 64 * 64 사진크기

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

for n in range(N*M):
    ax = fig.add_subplot(N, M, n+1)
    ax.imshow(X_inv[n].reshape(64, 64), cmap=plt.cm.bone) # 사진 크기대로 다시 reshape
    ax.grid(False)
    ax.xaxis.set_ticks([])
    ax.yaxis.set_ticks([])

plt.suptitle('PCA result')
plt.tight_layout()
plt.show()

원점과 두 개의 eigen face

  • 10장의 사진을 3장으로 표현
  • face_p1만 표현
  • pca.components_ : 주성분 출력
# 벡터로 표현
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')

가중치

# 가중치 선정
import numpy as np

N = 2
M = 5

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

fig = plt.figure(figsize=(10, 5))
plt.subplots_adjust(top=1, bottom=0, hspace=0.5, 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()

두 개의 성분을 모두 표현

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 = w1.reshape(-1, )
w2 = w2.reshape(-1, )

fig = plt.figure(figsize=(10, 5))
plt.subplots_adjust(top=1, bottom=0, hspace=0.5, 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()



Reference
1) 제로베이스 데이터스쿨 강의자료

profile
데이터 사이언스 / just do it

0개의 댓글