Wcześniej zapytałem o to na StackOverflow, ale wydaje się, że może być bardziej odpowiednie tutaj, biorąc pod uwagę, że nie otrzymało żadnych odpowiedzi na SO. To trochę na styku statystyki i programowania.
Muszę napisać kod, aby wykonać PCA (Principal Component Analysis). Przejrzałem dobrze znane algorytmy i zaimplementowałem ten , który, o ile wiem, jest równoważny algorytmowi NIPALS. Działa dobrze do znajdowania pierwszych 2-3 głównych składników, ale wydaje się, że ich konwergencja staje się bardzo powolna (rzędu setek do tysięcy iteracji). Oto szczegóły tego, czego potrzebuję:
Algorytm musi być wydajny w przypadku ogromnej liczby funkcji (od 10 000 do 20 000) i wielkości próbek rzędu kilkuset.
Musi być racjonalnie możliwy do wdrożenia bez przyzwoitej biblioteki algebry liniowej / macierzy, ponieważ językiem docelowym jest D, który jeszcze go nie ma, a nawet gdyby tak było, wolałbym nie dodawać go jako zależności do danego projektu .
Na marginesie, wydaje się, że w tym samym zbiorze danych R wydaje się, że wszystkie główne składniki są bardzo szybkie, ale wykorzystuje rozkład pojedynczej wartości, co nie jest czymś, co chcę sam kodować.
Odpowiedzi:
Zaimplementowałem Randomized SVD, jak podano w „Halko, N., Martinsson, PG, Shkolnisky, Y., i Tygert, M. (2010). Algorytm analizy głównej składowej dużych zbiorów danych. Arxiv preprint arXiv: 1007.5510, 0526. Źródło: 01 kwietnia 2011, od http://arxiv.org/abs/1007.5510 . ". Jeśli chcesz obciąć SVD, to naprawdę działa znacznie szybciej niż wersje svd w MATLAB. Możesz go pobrać tutaj:
Aby to przetestować, po prostu utwórz obraz w tym samym folderze (podobnie jak duża matryca, możesz sam stworzyć matrycę)
Kiedy uruchamiam go na pulpicie dla obrazu o rozmiarze 635 * 483, otrzymuję
Jak widać, przy niskich wartościach
k
jest on ponad 10 razy szybszy niż przy użyciu Matlab SVD. Nawiasem mówiąc, może być potrzebna następująca prosta funkcja dla funkcji testowej:Nie dodałem metody PCA, ponieważ można ją łatwo wdrożyć za pomocą SVD. Możesz sprawdzić ten link, aby zobaczyć ich związek.
źródło
możesz spróbować użyć kilku opcji.
1- Rozkład kar z matrycą . Stosujesz pewne ograniczenia karne wobec u i v, aby uzyskać odrobinę rzadkości. Szybki algorytm zastosowany w danych genomicznych
Zobacz Whitten Tibshirani. Mają także R-pkg. „Karany rozkład macierzy z aplikacjami do rzadkich głównych komponentów i kanoniczną analizą korelacji”.
2- Randomizowane SVD . Ponieważ SVD jest algorytmem nadrzędnym, pożądane może być bardzo szybkie przybliżenie, szczególnie w przypadku analizy eksploracyjnej. Za pomocą randomizowanego SVD możesz wykonywać PCA na ogromnych zestawach danych.
Zobacz Martinsson, Rokhlin i Tygert „Losowy algorytm rozkładu macierzy”. Tygert ma kod do bardzo szybkiej implementacji PCA.
Poniżej znajduje się prosta implementacja randomizowanego SVD w R.
źródło
Wygląda na to, że chcesz użyć algorytmu Lanczos . W przeciwnym razie możesz skonsultować się z Golubem i Van Loanem. Kiedyś kodowałem algorytm SVD (w SML wszystkich języków) z ich tekstu i działał on całkiem dobrze.
źródło
Sugeruję wypróbowanie jądra PCA, które ma złożoność czasowo-przestrzenną zależną od liczby przykładów (N), a nie od liczby funkcji (P), które moim zdaniem byłyby bardziej odpowiednie w twoim ustawieniu (P >> N)). Jądro PCA działa w zasadzie z macierzą jądra NxN (macierz podobieństw między punktami danych), a nie z macierzą kowariancji PxP, z którą trudno jest sobie poradzić w przypadku dużych P. Kolejną dobrą rzeczą w jądrze PCA jest to, że może nauczyć się projekcji nieliniowych również jeśli używasz go z odpowiednim jądrem. Zobacz ten artykuł na temat PCA jądra .
źródło
Wydaje mi się, że można wykonać PCA, obliczając rozkład własny X ^ TX zamiast XX ^ T, a następnie przekształcić, aby uzyskać komputery PC. Jednak nie pamiętam szczegółów z ręki, ale są one w (doskonałej) książce Jolliffe i sprawdzę je, kiedy będę w pracy. Transliterowałbym procedury algebry liniowej z np. Metod numerycznych w C, zamiast używać jakiegokolwiek innego algorytmu.
źródło
Istnieje również metoda ładowania początkowego autorstwa Fisher i in. , Zaprojektowana dla kilkuset próbek o dużych wymiarach.
Główną ideą tej metody jest sformułowanie: „ponowne próbkowanie jest transformacją niskiego wymiaru”. Tak więc, jeśli masz małą (kilkaset) liczbę wysokowymiarowych próbek, nie możesz uzyskać więcej głównych składników niż liczba twoich próbek. Dlatego sensowne jest rozważenie próbek jako podstawy oszczędnej, rzutowanie danych na podprzestrzeń liniową obejmującą te wektory i obliczenie PCA w tej mniejszej podprzestrzeni. Dostarczają również więcej szczegółów na temat postępowania w przypadku, gdy nie wszystkie próbki mogą być przechowywane w pamięci.
źródło
Zobacz artykuł Sama Roweisa, EM Algorytmy dla PCA i SPCA .
źródło