calcolare il SVD troncato, un valore / vettore singolare alla volta


11

Esiste un algoritmo SVD troncato che calcola i valori singolari uno alla volta?

Il mio problema: vorrei calcolare i primi K valori singolari (e vettori singolari) di una matrice densa di grandi dimensioni M , ma non so quale sarebbe un valore appropriato di k . M è grande, quindi per motivi di efficienza, preferirei non valutare l'intero SVD solo per troncare successivamente il più piccolo SV.

Idealmente, ci sarebbe un modo per calcolare i valori singolari σ1,σ2, serie, dal più grande ( σ1 ) al più piccolo ( σn ). In questo modo, potrei semplicemente interrompere il calcolo dopo aver calcolato il k ° valore singolare se σk/σ1 scende al di sotto di qualche soglia.

Esiste un tale algoritmo (preferibilmente con un'implementazione di Python)? Nel mio google, ho trovato solo funzioni troncate SVD che prendono k come parametro, costringendoti così a indovinarlo a priori.


La tua M è quadrata o rettangolare? Se rettangolare, vuoi i vettori singolari lunghi o corti? Cioè, se M è (mxn) con m> n, vuoi (mxk) o (kxn)?
Max Hutchinson,

M è rettangolare, con molte più righe delle colonne. Voglio i vettori singolari corti (cioè V, in M ​​= U S V ^ T).
SuperElectric

Risposte:


6

Ci sono un paio di opzioni disponibili se si desidera una fattorizzazione approssimativa di grado k.

  1. Fattorizzazioni QR di grande rilevanza
  2. Decomposizione interpolativa (ID) e altre tecniche randomizzate.

UN-MNTfattore×σK+1(UN): =ε

Una fattorizzazione approssimativa della forma sopra può essere convertita in una decomposizione standard come QR o SVD usando tecniche standard. Una buona recensione è disponibile nell'articolo di Halko, Martinsson e Tropp "Trovare una struttura con casualità: algoritmi probabilistici per costruire scomposizioni di matrici approssimative"

In termini di software è disponibile un'interfaccia per algoritmi ID in scipy (scipy.linalg.interpolative) http://docs.scipy.org/doc/scipy-dev/reference/linalg.interpolative.html che consente all'utente di specificare .ε


2

(Modificato, perché all'inizio ho letto male la domanda; sai già che ci sono routine disponibili per calcolare i primi valori singolari.)K

Se si esclude l'approccio del calcolo dell'intero SVD, gli algoritmi SVD parziali si riducono all'utilizzo di metodi iterativi per risolvere un problema di autovalore eremitico correlato. Quindi, una strategia che potresti prendere sarebbe quella di codificare manualmente questo tipo di cose da te, e continuare a risolvere il più grande valore singolare irrisolto rimanente fino a quando non vuoi fermarti, usando qualcosa come una strategia di spostamento e inversione. Ci possono essere modi eleganti di fare questo genere di cose in pacchetti sofisticati come SLEPc .

Un'altra strategia sarebbe la seguente:

  • S1
  • τS1fτ0<f1
  • Chiamare la routine sparsa SVD.

K


Se non specifichi 'k' in scipy.sparse.linalg.svds, il valore predefinito sarà k = 6, indipendentemente dal parametro 'tol'. Non è chiaro se si tratta di un bug o se si suppone che 'tol' si riferisca all'accuratezza dei valori singolari calcolati (piuttosto che alla loro dimensione)
Nick Alger,
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.