Bu yazı temel bileşenler analizinin Python ile kodlanması üzerinedir. Temel bileşenler analizi hakkında detaylı teorik bilgi için tıklayınız.

Uzun süre önce MATLAB ile PCA kodunu paylaşmıştım. Python kullanarak biraz daha geliştirdim. PCA bilgisi için önceki yazıya bakabilirsiniz. Farklı olarak özvektör sayısı yerine varyansın toplam varyansa oranını parametre olarak alıyorum. 1.0 demek tüm varyansın dahil olması demek oluyor. Literatürde, genelde 0.98 veya 0.95 değerleri seçiliyor.

import numpy as np

def pca(samples, percentage=None):
    """
    Perform Principal Component Analysis

    Calculate the eigenvectors V (each as a column) and eigenvalues D of the
    given samples which is a matrix involving a sample point in each row.
    If #samples is less than #dimensions, it uses the faster PCA calculation.
    Refer to the corresponding part in the thesis (Ari2008) for details."""

    nSamples, nDim = samples.shape
    meanSample = samples.mean(0)

    # Subtract the mean from all samples to align them to origin
    samples = samples - meanSample

    # For faster calculation, use the transposed matrix of samples
    if nDim > nSamples:
        samples = samples.T

    # Find the covariance of the distribution
    C = np.dot(samples.T, samples) / (nSamples * 1.0)

    # Find the eigenvectors (V) and eigenvalues (D) of the samples
    # Recall that C*V = V*D and each column of V is an eigenvector
    D,V = np.linalg.eigh(C)

    # We need the eigenvalues sorted from higher to lower
    indices = list(index for index, item in \
            sorted(enumerate(D), key=lambda item: item[1]))
    indices = np.flipud(indices)
    D = D[indices]
    V = V[:,indices]

    # If faster calculation is done, we need to create the eigenvectors from the
    # found ones and normalize them. The eigenvalues remain the same.
    if nDim > nSamples:
        V = np.dot(samples,V)
        for i in range(nSamples):
            normV = np.linalg.norm(V[:,i])
            V[:,i] = V[:,i] / normV
        V = V.T

    # Compute the required # of dimensions acquiring the given
    # variance percentage
    if percentage is not None:
        totalVariances = [sum(D[0:i]) for i in range(len(D))]
        totalVariances = totalVariances / totalVariances[-1]
        nEnoughComponents = len(totalVariances)
        for i,val in enumerate(totalVariances):
            if val > percentage: 
                nEnoughComponents = i+1
                break

        V = V[0:nEnoughComponents,:]
        D = D[0:nEnoughComponents]

    return V,D

Kullanırsanız ve/veya geliştirirseniz lütfen benimle de paylaşın.