2016-04-12 11 views
5

Mogę wykonać PCA w scikicie według kodu poniżej: X_train ma 279180 wierszy i 104 kolumny.Projekcja i rekonstrukcja PCA w Scikit

from sklearn.decomposition import PCA 
pca = PCA(n_components=30) 
X_train_pca = pca.fit_transform(X_train) 

Teraz, kiedy chcę do projektu wektorów własnych na przestrzeni cech, muszę zrobić co następuje:

""" Projection """ 
comp = pca.components_ #30x104 
com_tr = np.transpose(pca.components_) #104x30 
proj = np.dot(X_train,com_tr) #279180x104 * 104x30 = 297180x30 

Ale jestem wahając się z tego kroku, ponieważ Scikit documentation mówi:

components_: array, [n_components, n_features]

Główne osie wf eature space, reprezentujące kierunki maksymalnej wariancji danych.

Wydaje mi się, że jest już wyświetlany, ale kiedy sprawdziłem kod źródłowy, zwraca tylko wektory własne.

Jaki jest właściwy sposób jego wyświetlania?

Docelowo zamierzam obliczyć MSE odbudowy.

""" Reconstruct """ 
recon = np.dot(proj,comp) #297180x30 * 30x104 = 279180x104 

""" MSE Error """ 
print "MSE = %.6G" %(np.mean((X_train - recon)**2)) 

Odpowiedz

13

Można zrobić

proj = pca.inverse_transform(X_train_pca) 

ten sposób nie trzeba się martwić jak wykonać mnożenia.

Co można uzyskać po pca.fit_transform lub pca.transform to, co nazywa się zwykle „obciążeń” dla każdej próbki, co oznacza, ile każdego składnika trzeba go opisać najlepiej stosując liniową kombinację components_ (głównych osiach w przestrzeni cech).

Projekcja, na którą celujesz, powraca w oryginalnym obszarze sygnału. Oznacza to, że musisz powrócić do przestrzeni sygnału za pomocą komponentów i obciążeń.

Istnieją trzy kroki, aby ujednoznacznić się tutaj.Tutaj masz, krok po kroku, co można zrobić przy użyciu obiektu PCA i jak to jest rzeczywiście obliczana:

  1. pca.fit szacunki składniki (przy użyciu SVD na środku xTrain):

    from sklearn.decomposition import PCA 
    import numpy as np 
    from numpy.testing import assert_array_almost_equal 
    
    Xtrain = np.random.randn(100, 50) 
    
    pca = PCA(n_components=30) 
    pca.fit(Xtrain) 
    
    U, S, VT = np.linalg.svd(Xtrain - Xtrain.mean(0)) 
    
    assert_array_almost_equal(VT[:30], pca.components_) 
    
  2. pca.transform oblicza obciążenia jak opisać

    X_train_pca = pca.transform(Xtrain) 
    
    X_train_pca2 = (Xtrain - pca.mean_).dot(pca.components_.T) 
    
    assert_array_almost_equal(X_train_pca, X_train_pca2) 
    
  3. pca.inverse_transform uzyskuje ONT projekcji O komponenty w przestrzeni sygnału jesteś zainteresowany

    X_projected = pca.inverse_transform(X_train_pca) 
    X_projected2 = X_train_pca.dot(pca.components_) + pca.mean_ 
    
    assert_array_almost_equal(X_projected, X_projected2) 
    

Teraz można ocenić utraty projekcja

loss = ((X_train - X_projected) ** 2).mean() 
+0

Ok, więc mogę zadzwonić 'pca.fit' obliczyć składniki, a następnie projekcję można obliczyć za pomocą 'pca.fit_transform' (to znaczy, gdy chcę dalej pracować z danymi - pobrać je do jakiegoś modelu, ponieważ wymiarowość jest zredukowana). I do rekonstrukcji, nazywam 'pca.invert_transform', aby obliczyć MSE. Czy to jest poprawne? – HonzaB

+1

To zależy od tego, co rozumiesz przez projekcję. Po pierwsze, zauważ, że 'pca.fit_transform (X)' daje taki sam wynik jak 'pca.fit (X) .transform (X)' (jest to zoptymalizowany skrót). Po drugie, projekcja jest generalnie czymś, co przechodzi z jednej przestrzeni w tę samą przestrzeń, a więc tutaj z przestrzeni sygnałowej do przestrzeni sygnałowej, z tą właściwością, że dwukrotne jej zastosowanie jest jak nakładanie jej raz. Tutaj będzie to 'f = lambda X: pca.inverse_transform (pca.transform (X))'. Możesz sprawdzić, że 'f (f (X)) == f (X).' Tak nazwałbym to projekcją. 'pca.transform' uzyskuje ładunki. W końcu to tylko terminologia – eickenberg

+0

Przez rzutowanie rozumiem transformację wektorów na przestrzeń cech. To właśnie zrobiłem w moim pytaniu (drugi krok) i to samo robi 'pca.transform (X)' - wynikiem jest macierz _Mxk_, gdzie _M_ to liczba wierszy i _k_ liczba wybranych składników. Wykorzystam to jako dane wejściowe do modeli (i powinienem oczekiwać lepszych wyników niż przy użyciu oryginalnego zestawu danych). – HonzaB