Quali algoritmi veloci esistono per il calcolo dell'SVD troncato?


14

Forse fuori tema qui, ma esistono già diverse ( una , due ) domande correlate.

Frugando in letteratura (o una ricerca su google per algoritmi SVD troncati ) si presentano molti documenti che usano SVD troncati in vari modi e affermano (frustrantemente, spesso senza citazione) che ci sono algoritmi veloci per calcolarlo, ma nessuno sembra indicare quali siano questi algoritmi.

L'unica cosa che posso trovare è un singolo algoritmo randomizzato , usato nella libreria redSVD .

Quello che mi piacerebbe vedere è un insieme di algoritmi esatti e inesatti, adatti a capire come funzionano i sistemi (ma non necessariamente per implementarli effettivamente!).

Qualcuno ha un buon riferimento per questo genere di cose?


Se voglio archiviare bene i dati, uso un b-tree (o rb-tree) nell'hash (pensate a ram). Se avessi un albero b per i dati, allora potrei in O (log (n)) campionare i quantili e così via. Scommetto che con dati di grandi dimensioni, tale campionamento potrebbe essere usato per calcolare in breve tempo un'approssimazione sparsa decente alle matrici svd. Potresti anche cercare il "rilevamento compresso" che è un approccio molto statistico alla compressione estrema dei dati.
EngrStudent - Ripristina Monica il

Con SVD troncato intendi che sei interessato a trovare solo diversi vettori / valori singolari, al contrario di tutti?
ameba dice Reinstate Monica il

@amoeba Sì, questa è l'idea.
John Doucette,

Risposte:


16

In termini molto generali, ci sono due approcci per calcolare autovalori o scomposizioni di valori singolari. Un approccio consiste nel diagonalizzare la matrice e ciò produce essenzialmente la decomposizione dell'intero autovalore / valore singolare (l'intero spettro degli autovalori) allo stesso tempo, vedere una panoramica qui: Quali sono algoritmi efficienti per calcolare la decomposizione di valore singolare (SVD)? L'alternativa è utilizzare un algoritmo iterativo che produce uno (o più) autovettori alla volta. Le iterazioni possono essere arrestate dopo che è stato calcolato il numero desiderato di autovettori.

Non credo che esistano algoritmi iterativi specifici per SVD. Questo perché si può calcolare SVD di una matrice B facendo un'eigendecomposition di un quadrata simmetrica ( n + m ) x ( n + m ) matrice A = ( 0 B B 0 ) . Pertanto, invece di chiedere quali algoritmi calcolano SVD troncato, dovresti chiedere quali algoritmi iterativi calcolano la composizione elettronica: algoritmo per SVD troncato algoritmo iterativo per la composizione elettronica .n×mB(n+m)×(n+m)

UN=(0BB0).
algoritmo per SVD troncatoalgoritmo iterativo per la composizione elettronica.

L'algoritmo iterativo più semplice si chiama power iteration ed è davvero molto semplice:

  1. Inizializza casuale .X
  2. Aggiornamento .XUNX
  3. Normalizza .XX/X
  4. Andare al passaggio n. 2 a meno che non sia convergente.

Tutti gli algoritmi più complessi si basano in definitiva sull'idea dell'iterazione di potenza, ma diventano piuttosto sofisticati. La matematica necessaria è data dai sottospazi di Krylov . Gli algoritmi sono iterazione di Arnoldi (per matrici quadrate non simmetriche), iterazione di Lanczos (per matrici simmetriche quadrate) e loro varianti come ad esempio "metodo Lanczos a riavvio implicito" e quant'altro.

Puoi trovarlo descritto ad esempio nei seguenti libri di testo:

  1. Prestito Golub & Van, calcoli con matrici
  2. Trefethen & Bau, algebra lineare numerica
  3. Demmel, algebra lineare numerica applicata
  4. Saad, metodi numerici per problemi di autovalori di grandi dimensioni

Tutti i ragionevoli linguaggi di programmazione e pacchetti statistici (Matlab, R, Python numpy, tu lo chiami) usano le stesse librerie Fortran per eseguire decomposizioni eigen / singular value. Questi sono LAPACK e ARPACK . ARPACK sta per ARnoldi PACKage ed è tutto incentrato sulle iterazioni di Arnoldi / Lanczos. Ad esempio in Matlab ci sono due funzioni per SVD: svdesegue la decomposizione completa tramite LAPACK, e svdscalcola un determinato numero di singoli vettori tramite ARPACK ed è in realtà solo un wrapper per una eigschiamata sulla matrice "quadrata".

Aggiornare

BUNUNBUN

Esiste una libreria Fortran anche per questi metodi, si chiama PROPACK :

Il pacchetto software PROPACK contiene una serie di funzioni per calcolare la scomposizione del valore singolare di matrici grandi, sparse o strutturate. Le routine SVD si basano sull'algoritmo di bidiagonalizzazione di Lanczos con reorthogonalization parziale (BPRO).

Tuttavia, PROPACK sembra essere molto meno standard di ARPACK e non è supportato nativamente nei linguaggi di programmazione standard. È stato scritto da Rasmus Larsen, che ha una grande bidiagonalizzazione di Lanczos del 1998, lunga 90 pagine, con parzializzazione parziale con quella che sembra una buona visione d'insieme. Grazie a @MichaelGrant tramite questo thread di Computational Science SE .

Tra gli articoli più recenti, il più popolare sembra essere Baglama & Reichel, 2005, Augmented ha ricominciato implicitamente i metodi di bidiagonalizzazione di Lanczos , che è probabilmente intorno allo stato dell'arte. Grazie a @Dougal per aver fornito questo link nei commenti.

Aggiornamento 2

C'è davvero un approccio completamente diverso descritto in dettaglio nel documento di sintesi che hai citato tu stesso: Halko et al. 2009, Trovare una struttura con casualità: algoritmi probabilistici per la costruzione di decomposizioni di matrice approssimative . Non ne so abbastanza per commentare.


Si noti che esistono metodi di iterazione specifici per SVD; ad es. Metodi di bidiagonalizzazione Lanczos Riavviati implicitamente aumentati , J. Baglama e L. Reichel, SIAM J. Sci. Comput. 2005. (Non ho letto il documento per sapere se è fondamentalmente diverso dall'approccio autovalore che hai dato, sappi solo che alla gente piace quel metodo.)
Dougal,

1
Grazie per il link, @Dougal. Dovrei dire che non conosco bene nessuno di questi metodi, quindi non posso davvero commentarlo. Sarebbe bello se qualcuno più esperto spiegasse la relazione tra vari metodi iterativi. Per quanto ho capito, il metodo Vanilla Lanczos è per calcolare gli autovalori di una matrice quadrata e non per SVD; "Lanczos implicitamente riavviato aumentato" dovrebbe essere strettamente correlato ad esso, ma hai ragione - sembra essere direttamente su SVD. Non sono sicuro di come si adatta tutto insieme. Aggiornerò la mia risposta se dovessi mai dare un'occhiata più da vicino.
ameba dice Ripristina Monica il

1
@Dougal, ho fatto qualche lettura superficiale e fatto un aggiornamento.
ameba dice Ripristina Monica il

@amoeba "troncare SVD" nel contesto di minimi quadrati regolarizzati sarebbe sostanzialmente lo stesso di "regressione dei componenti principali" ?
GeoMatt22,

1
@amoeba Puoi commentare l' implementazione SVD randomizzata di Facebook , alcune persone sembrano dire che sia tra le soluzioni più veloci possibili in questo momento. Sarebbe bello se potessi modificare per commentare anche questo.
Tim

4

Mi sono appena imbattuto nel thread tramite gli SVD veloci su Google, quindi sto cercando di capire le cose da solo, ma forse dovresti esaminare l'approssimazione incrociata adattiva (ACA).

MM=Σio=0KUioVioTN×NO(N)

Ancora una volta, dipende dal tuo problema se funziona. In molti casi che incontro personalmente, l'ACA è uno strumento numerico molto utile.

Nota: volevo scrivere questo come commento, ma poiché ho appena creato questo account non ho abbastanza reputazione per i commenti ... Ma la pubblicazione funziona.


2

Ecco una tecnica che ho usato con successo in passato per calcolare un SVD troncato (nel set di dati Netflix). È tratto da questo documento . In un'impostazione di filtro collaborativo, dovrei notare che la maggior parte dei valori mancano e il punto è prevederli , quindi per usare SVD troncato per risolvere un tale problema, devi usare una tecnica che funziona in quella condizione. Una breve descrizione:

  1. Prima di fare qualsiasi cosa, inserisci un modello semplice (ad esempio, media globale + valori di colonna e costante di riga) e solo una volta che hai fatto ciò dovresti passare a utilizzare SVD troncato per adattarsi ai residui.
  2. Inizializza un vettore casuale di lunghezza k (dove è il grado a cui stai troncando) per ogni riga e colonna (per ogni film e utente nel caso Netflix).
  3. Mantieni fissi i vettori di riga e aggiorna i vettori di colonna per ridurre al minimo l'errore rispetto alle voci note nella matrice. La procedura è indicata in codice matlab nel documento.
  4. Mantieni fissi i vettori di colonna e aggiorna i vettori di riga in modo analogo.
  5. Ripeti 3 e 4 fino a quando convergi o non ottieni risultati abbastanza buoni.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.