Chciałbym użyć analizy głównych składowych (PCA) do redukcji wymiarowości. Czy Numpy lub Scipy już to ma, czy muszę używać własnego numpy.linalg.eigh
?
Nie chcę tylko używać rozkładu według wartości osobliwych (SVD), ponieważ moje dane wejściowe są dość wielowymiarowe (~ 460 wymiarów), więc myślę, że SVD będzie wolniejsze niż obliczanie wektorów własnych macierzy kowariancji.
Miałem nadzieję, że uda mi się znaleźć gotową, zdebugowaną implementację, która już podejmuje właściwe decyzje dotyczące tego, kiedy użyć której metody i która może zapewniać inne optymalizacje, o których nie wiem.
Note that from this release MDP is in maintenance mode. 13 years after its first public release, MDP has reached full maturity and no new features are planned in the future.
Kilka miesięcy później, oto mały PCA klasy i zdjęcie:
źródło
Korzystanie z PCA
numpy.linalg.svd
jest bardzo łatwe. Oto proste demo:źródło
svd
już zwracas
posortowane w porządku malejącym, o ile dokumentacja idzie. (Być może tak nie było w 2012 r., Ale dziś jest)Możesz użyć sklearn:
źródło
matplotlib.mlab ma implementację PCA .
źródło
SVD powinno działać dobrze z 460 wymiarami. Na moim netbooku Atom zajmuje to około 7 sekund. Metoda eig () przyjmuje więcej czasu (tak jak powinna, wykorzystuje więcej operacji zmiennoprzecinkowych) i prawie zawsze będzie mniej dokładna.
Jeśli masz mniej niż 460 przykładów, to co chcesz zrobić, to przekątna macierz rozproszenia (x - datamean) ^ T (x - średnia), zakładając, że twoje punkty danych są kolumnami, a następnie mnożąc w lewo przez (x - datamean). Że może być szybciej w przypadku, gdy masz więcej niż wymiary danych.
źródło
Możesz dość łatwo „przetoczyć” własne, używając
scipy.linalg
(zakładając wstępnie wyśrodkowany zbiór danychdata
):Następnie
evs
są twoje wartości własne ievmat
jest twoją macierzą projekcji.Jeśli chcesz zachować
d
wymiary, użyj pierwszychd
wartości własnych i pierwszejd
wektorów własnych.Biorąc pod uwagę, że
scipy.linalg
ma rozkład i zdrętwienie mnożenia macierzy, czego jeszcze potrzebujesz?źródło
eig()
na macierzy kowariancji.Właśnie kończę czytać książkę Machine Learning: An Algorithmic Perspective . Wszystkie przykłady kodu w książce zostały napisane przez Pythona (i prawie z Numpy). Warto przeczytać fragment kodu programu chatper10.2 Analiza głównych komponentów . Używa numpy.linalg.eig.
Nawiasem mówiąc, myślę, że SVD bardzo dobrze radzi sobie z wymiarami 460 * 460. Obliczyłem 6500 * 6500 SVD z numpy / scipy.linalg.svd na bardzo starym komputerze: Pentium III 733 MHz. Szczerze mówiąc, skrypt potrzebuje dużo pamięci (około 1.xG) i dużo czasu (około 30 minut), aby uzyskać wynik SVD. Ale myślę, że 460 * 460 na nowoczesnym komputerze nie będzie dużym problemem, chyba że będziesz potrzebować SVD wiele razy.
źródło
Nie potrzebujesz pełnej dekompozycji na wartości osobliwe (SVD), ponieważ oblicza ona wszystkie wartości własne i wektory własne i może być przeszkodą w przypadku dużych macierzy. scipy i jego rzadki moduł zapewniają ogólne liniowe funkcje algrebry działające zarówno na rzadkich, jak i gęstych macierzach, wśród których znajduje się rodzina funkcji eig *:
http://docs.scipy.org/doc/scipy/reference/sparse.linalg.html#matrix-factorizations
Scikit-learn zapewnia implementację Python PCA, która na razie obsługuje tylko gęste macierze.
Czasy:
źródło
eigsh
jest faktycznie ~ 4x wolniejszy niżeigh
dla nierzadkich macierzy. To samo dotyczyscipy.sparse.linalg.svds
versusnumpy.linalg.svd
. Zawsze brałbym SVD zamiast rozkładu wartości własnych z powodów, o których wspomniał @dwf, i być może użyłbym rzadkiej wersji SVD, jeśli macierze stają się naprawdę duże.eigsh
isvds
są szybsze niżeigh
isvd
o współczynnik ~ 3, ale jeśli A jest mniejsze, powiedzmy 100 * 100, toeigh
isvd
są szybsze odpowiednio o współczynniki ~ 4 i ~ 1,5 . Jednak T nadal używałby rzadkiego SVD zamiast rzadkiego rozkładu wartości własnej.Oto kolejna implementacja modułu PCA dla Pythona przy użyciu rozszerzeń numpy, scipy i C. Moduł przeprowadza PCA przy użyciu algorytmu SVD lub NIPALS (Nonlinear Iterative Partial Least Squares), który jest zaimplementowany w C.
źródło
Jeśli pracujesz z wektorami 3D, możesz zwięźle zastosować SVD za pomocą paska narzędzi vg . To lekka warstwa na wierzchu numpy.
Istnieje również wygodny alias, jeśli chcesz tylko pierwszy główny składnik:
Bibliotekę stworzyłem podczas mojego ostatniego uruchomienia, gdzie była motywowana takimi zastosowaniami: prostymi pomysłami, które są pełne lub nieprzejrzyste w NumPy.
źródło