2011-02-09 29 views
10

Mam rzadki Matrix w R, który jest najwyraźniej zbyt duży dla mnie, aby uruchomić as.matrix() na (choć nie jest też super-ogromny). Wywołanie as.matrix() jest wewnątrz funkcji svd(), więc zastanawiam się, czy ktoś wie o innej implementacji SVD, która nie wymaga wcześniejszej konwersji na gęstą matrycę.SVD dla macierzy rzadkiej w R

+0

Nie mogę znaleźć niczego dla R. Mnóstwo rzeczy dla C, Fortran, Python itp. –

+0

Może spróbuję SVDLIBC. Buduje się jako biblioteka C, więc jeśli działa dobrze, mógłbym w przyszłości zawrzeć ją jako moduł (choć moja ambicja prawdopodobnie nie wytrzyma tak długo, jeśli historia jest jakimkolwiek przewodnikiem ...). –

+2

Co powiesz na ten http://cran.r-project.org/web/packages/irlba/ Szybka i efektywna pamięćowo metoda obliczania kilku przybliżonych wartości liczby pojedynczej i pojedynczych wektorów dużych macierzy. –

Odpowiedz

10

Pakiet irlba ma bardzo szybki SVD implementacja dla rzadkich macierzy.

+1

Komentarz do pakietu 'irlba' (trzeci pod pytaniem) był spóźniony o rok, kiedy został opublikowany. Twoja odpowiedź powtarza komentarz * kolejny rok * później ... –

+1

@ Ferdinand.kraft Przepraszam, ponieważ przegapiłem komentarz.Ta strona jest pierwszym wynikiem, gdy szuka się "R rzadkiego svd" i biorąc pod uwagę, że 'irlba' jest najlepszym pakietem R dla rzadkiego svd, wydaje się odpowiednią odpowiedzią. Jeśli autor komentarza chciałby wysłać odpowiedź, byłbym szczęśliwy, gdyby udało mi się go upublicznić i usunąć. – Zach

6

Oto, co zrobiłem. Jest to stosunkowo proste napisać procedurę, która zrzuca rzadki macierzy (klasa dgCMatrix) do pliku tekstowego w formacie SVDLIBC za „rzadki tekst”, a następnie wywołać svd wykonywalny i czytać trzy wypadkowa pliki tekstowe z powrotem do R.

The złapać to, że jest to dość nieefektywne - odczytanie plików zajmuje mi około 10 sekund, ale faktyczne obliczenia SVD trwają tylko około 0,2 sekundy. Mimo wszystko jest to oczywiście dużo lepsze niż brak możliwości wykonywania obliczeń, więc jestem szczęśliwy. =)

+0

Następne pytanie zadane na http://stackoverflow.com/questions/5009026/extract-long-from-r-object. –

+1

Podanie sobie znacznika wyboru bez oferowania przykładowych danych lub kodu rozwiązania wydaje się być sprzeczne z zasadami SO. –

+0

Nie jestem już w firmie, w której to zrobiłem, więc nie mam dostępu do tego kodu. Oznaczało to, że znacznik wyboru oznacza "to jest rozwiązanie, którego faktycznie używałem". Różni się ona od innych sugestii i bardzo prosta do wdrożenia. Aby uruchomić, jest to naprawdę "zły" sposób, aby to zrobić, ponieważ wymaga zapisywania plików tekstowych reprezentujących matryce numeryczne. Więc nie wiem, czy naprawdę warto to skopiować jako przykład. –

8

Można zrobić bardzo imponujący kawałek rzadki SVD w R stosując przypadkowy występ w sposób opisany w http://arxiv.org/abs/0909.4061

Oto przykładowy kod:

# computes first k singular values of A with corresponding singular vectors 
incore_stoch_svd = function(A, k) { 
    p = 10    # may need a larger value here 
    n = dim(A)[1] 
    m = dim(A)[2] 

    # random projection of A  
    Y = (A %*% matrix(rnorm((k+p) * m), ncol=k+p)) 
    # the left part of the decomposition works for A (approximately) 
    Q = qr.Q(qr(Y)) 
    # taking that off gives us something small to decompose 
    B = t(Q) %*% A 

    # decomposing B gives us singular values and right vectors for A 
    s = svd(B) 
    U = Q %*% s$u 
    # and then we can put it all together for a complete result 
    return (list(u=U, v=s$v, d=s$d)) 
} 
+0

Wow, bardzo fajne. Będę musiał spróbować tego. –

+2

Więc wypróbowałem to i wygląda na to, że nie daje bardzo dobrych rezultatów, chyba że podniosę 'p' w górę, w takim przypadku nie oszczędza to dużo zasobów. Jako test, stworzyłem losową rzadką matrycę 10000x12000 z 1000 niezerowymi wpisami próbkowanymi jako runif (1000), które powinny mieć wartości własne około 0.999 lub 1. Ale ta metoda pokazuje kilka pierwszych wartości własnych jako '0.8461391, 0.8423876, 0.8353727, 0.8321352, 0.8271768 0,8203687 ". –

+2

Przeczytaj oryginalny dokument. Jeśli twoje wartości własne mają mniej więcej tę samą wartość, to nie oszczędzą cię tak bardzo, jak to jest. W takich przypadkach należy wykonać kilka iteracji kwadratu macierzy źródłowej, aby uzyskać lepszy spread. –

3

rARPACK to pakiet, którego potrzebujesz. Działa jak urok i jest Superfast, ponieważ jest równoległy do ​​C i C++.

+0

W 2017 r. Plik OPCJE v0.11.0 rArpack mówi: Teraz rARPACK staje się prostą powłoką pakietu RSpectra. – knb

+0

Skacząc jeszcze więcej lat, muszę powiedzieć, że RARPACK i RSpectra to niesamowite pakiety. irlba ma szczególne miejsce w moim sercu, ale RSpectra jest niesamowicie szybka – Zach