더북(TheBook)

새로운 샘플과 훈련 데이터셋의 샘플 간 유사도를 계산한 후 고윳값으로 고유 벡터 a를 정규화해야 합니다. 앞서 구현한 rbf_kernel_pca 함수를 커널 행렬의 고윳값도 반환하도록 수정하겠습니다.

from scipy.spatial.distance import pdist, squareform
from numpy import exp
from scipy.linalg import eigh
import numpy as np

def rbf_kernel_pca(X, gamma, n_components):
    """
    RBF 커널 PCA 구현

    매개변수
    ------------
    X: {넘파이 ndarray}, shape = [n_samples, n_features]

    gamma: float
      RBF 커널 튜닝 매개변수

    n_components: int
      반환할 주성분 개수

    반환값
    ------------
    alphas: {넘파이 ndarray}, shape = [n_samples, k_features]
      투영된 데이터셋

    lambdas: list
      고윳값

    """
    # MxN 차원의 데이터셋에서 샘플 간의 유클리디안 거리의 제곱을 계산합니다
    sq_dists = pdist(X, 'sqeuclidean')

    # 샘플 간의 거리를 정방 대칭 행렬로 변환합니다
    mat_sq_dists = squareform(sq_dists)

    # 커널 행렬을 계산합니다
    K = exp(-gamma * mat_sq_dists)

    # 커널 행렬을 중앙에 맞춥니다
    N = K.shape[0]
    one_n = np.ones((N,N)) / N
    K = K - one_n.dot(K) - K.dot(one_n) + one_n.dot(K).dot(one_n)

    # 중앙에 맞춰진 커널 행렬의 고윳값과 고유 벡터를 구합니다
    # scipy.linalg.eigh 함수는 오름차순으로 반환합니다
    eigvals, eigvecs = eigh(K)
    eigvals, eigvecs = eigvals[::-1], eigvecs[:, ::-1]

    # 최상위 k개의 고유 벡터를 선택합니다(투영 결과)
    alphas = np.column_stack([eigvecs[:, i]
                              for i in range(n_components)])

    # 고유 벡터에 상응하는 고윳값을 선택합니다
    lambdas = [eigvals[i] for i in range(n_components)]

    return alphas, lambdas
신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.