2011-02-09 13 views
10

Ho un rado Matrix in R che è apparentemente troppo grande per me per eseguire as.matrix() su (anche se non è neanche super-enorme). La chiamata as.matrix() si trova all'interno della funzione svd(), quindi mi chiedo se qualcuno conosce un'implementazione diversa di SVD che non richiede prima la conversione in una matrice densa.SVD per matrice sparsa in R

+0

Non riesco a trovare nulla per R. Un sacco di cose per C, Fortran, Python ecc. –

+0

Forse proverò SVDLIBC. Costruisce come una libreria C, quindi se funziona bene potrei in futuro avvolgerlo come un modulo (anche se probabilmente la mia ambizione non reggerà così a lungo, se la storia è una guida ...). –

+2

Che ne dite di questo http://cran.r-project.org/web/packages/irlba/ Un metodo veloce e efficiente in termini di memoria per calcolare alcuni valori singolari approssimativi e vettori singolari di matrici di grandi dimensioni. –

risposta

10

Il pacchetto irlba ha una molto veloce SVD implementazione per matrici sparse.

+1

Il commento che menziona il pacchetto 'irlba' (terzo sotto la domanda) era in ritardo di un anno quando pubblicato. La tua risposta duplica il commento * un altro anno * più tardi ... –

+1

@ Ferdinand.kraft Mi scuso, come ho perso il commento.Questa pagina è il primo risultato quando si cerca "R svd sparse" e considerando che 'irlba' è il miglior pacchetto R per sparso svd, sembra una risposta appropriata. Se l'autore del commento desidera pubblicare una risposta, sarei felice di revocarlo ed eliminare il mio. – Zach

6

Quindi ecco cosa ho fatto. E 'relativamente semplice per scrivere una routine che scarica una matrice sparsa (classe dgCMatrix) in un file di testo in formato "text sparse" di SVDLIBC, quindi chiamare l'eseguibile svd, e leggere i file tre testo risultante nuovamente dentro R.

Il la cattura è che è piuttosto inefficiente - mi ci vogliono circa 10 secondi per leggere & scrivere i file, ma il calcolo SVD effettivo richiede solo circa 0,2 secondi o giù di lì. Tuttavia, questo è ovviamente il modo migliore di non essere in grado di eseguire il calcolo a tutti, quindi sono felice. =)

+0

Domanda di followup pubblicata su http://stackoverflow.com/questions/5009026/extract-long-from-r-object. –

+1

Concedersi un segno di spunta senza offrire dati di esempio o codice di soluzione sembra contrario ai principi di SO. –

+0

Non sono più nella compagnia in cui l'ho fatto, quindi non ho accesso a quel codice. Intendevo dire che il segno di spunta significasse "questa è la soluzione che ho finito per usare". È abbastanza diverso dagli altri suggerimenti e molto semplice da implementare. Per avviare, è davvero il modo "sbagliato" per farlo, perché richiede la scrittura di file di testo che rappresentano matrici numeriche. Quindi non so se vale davvero la pena copiare come esempio. –

8

Si può fare un po 'molto impressionante di scarsa SVD in R utilizzando la proiezione casuale come descritto nel http://arxiv.org/abs/0909.4061

Ecco alcuni esempi di codice:

# 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, molto bello. Dovrò provarlo. –

+2

Così l'ho provato e sembra che non dia risultati molto buoni a meno che non abbiate preso 'p 'su, nel qual caso non risparmia molte risorse. Come test, ho creato una matrice casuale sparsa 10000x12000 con 1000 voci diverse da zero campionate come runif (1000), che dovrebbe avere autovalori attorno a 0,999 o 1. Ma questo metodo mostra i primi autovalori come '0,8461391, 0,8423876, 0,8353727, 0,8321352, 0,8271768 , 0.8203687'. –

+2

Leggi la carta originale. Se i tuoi autovalori sono tutti sullo stesso valore, allora non ti salverà più così com'è. In questi casi, è necessario eseguire alcune iterazioni di quadratura della matrice di origine per ottenere una migliore diffusione. –

3

rARPACK è il pacchetto che ti serve. Funziona come un fascino ed è Superfast perché si parallelizza tramite C e C++.

+0

Nel 2017, il file DESCRIZIONE v0.11.0 di rArpack dice: Ora rARPACK diventa una semplice shell del pacchetto RSpectra. – knb

+0

Saltando ancora più anni dopo, devo dire che RARPACK e RSpectra sono pacchetti incredibili. irlba ha un posto speciale nel mio cuore, ma RSpectra è incredibilmente veloce – Zach

Problemi correlati