Perché Andrew Ng preferisce utilizzare SVD e non EIG della matrice di covarianza per fare PCA?


29

Sto studiando PCA dal corso Coursera di Andrew Ng e altri materiali. Nel primo incarico di Stanford sulla PNL cs224n , e nel video della lezione di Andrew Ng , fanno una scomposizione di valore singolare invece della decomposizione di autovettori della matrice di covarianza, e Ng dice persino che SVD è numericamente più stabile della composizione elettronica.

Da quanto ho capito, per PCA dovremmo fare SVD della matrice dei dati di (m,n)dimensione, non della matrice di covarianza della (n,n)dimensione. E decomposizione degli autovettori della matrice di covarianza.

Perché fanno SVD della matrice di covarianza, non della matrice dei dati?


8
Per la matrice semidefinita positiva simmetrica quadrata (come la matrice di covarianza), gli autovalori e le scomposizioni del valore singolare sono esattamente le stesse.
ameba dice di reintegrare Monica il

5
Voglio dire, sono matematicamente uguali. Numericamente potrebbero effettivamente utilizzare algoritmi diversi e uno potrebbe essere più stabile di un altro (come dice Ng). Sarebbe interessante sapere di più su +1.
ameba dice di reintegrare Monica il

4
Alcune informazioni al riguardo qui: de.mathworks.com/matlabcentral/newsreader/view_thread/21268 . Ma nota che qualsiasi spiegazione sul perché un algoritmo sarebbe più stabile di un altro sarà molto tecnica.
ameba dice di reintegrare Monica il

2
In Matlab x=randn(10000); x=x'*x; tic; eig(x); toc; tic; svd(x); toc;sulla mia macchina esce 12s per eig () e 26s per svd (). Se è molto più lento, deve almeno essere più stabile! :-)
ameba dice Reinstate Monica il

4
Ciò potrebbe essere basato su una comprensione errata: fare un SVD della matrice di dati è più stabile dell'uso eigo svddella matrice di covarianza, ma per quanto ne so non c'è grande differenza tra l'usoeig o svdsulla matrice di covarianza --- sono entrambi algoritmi stabili all'indietro. Semmai, metterei i miei soldi sull'eig essere più stabile, dal momento che fa meno calcoli (supponendo che entrambi siano implementati con algoritmi all'avanguardia).
Federico Poloni,

Risposte:


17

L'ameba ha già dato una buona risposta nei commenti, ma se vuoi un argomento formale, eccolo qui.

La decomposizione del valore singolare di una matrice è A = U Σ V T , dove le colonne di V sono autovettori di A T A e le voci diagonali di Σ sono le radici quadrate dei suoi autovalori, ovvero σ i i = UNA=UΣVTVATAΣ .σii=λi(ATA)

Come sapete, i componenti principali sono le proiezioni ortogonali delle vostre variabili sullo spazio degli autovettori della matrice di covarianza empirica . La varianza dei componenti è data dai suoi autovalori,1n1ATA .λi(1n1ATA)

Considera qualsiasi matrice quadrata , α R e un vettore v tale che BBαRv . PoiBv=λv

  1. Bkv=λkv
  2. λ(αB)=αλ(B)

Definiamo . L'SVD diScalcolerà la composizione elettronica diSS=1n1ATAS per cedereSTS=1(n-1)2UNTUNUNTUN

  1. gli autovettori di (UNTUN)TUNTUN=UNTUNUNTUN , che per proprietà 1 sono quelli di UNTUN
  2. il radici quadrate degli autovalori di , che per proprietà 2, quindi 1, quindi di nuovo 2, sono1(n-1)2UNTUNUNTUN .1(n-1)2λio(UNTUNUNTUN)=1(n-1)2λio2(UNTUN)=1n-1λio(UNTUN)=λio(1n-1UNTUN)

Ecco!

Per quanto riguarda la stabilità numerica, bisognerebbe capire quali sono gli alogritmi impiegati. Se sei all'altezza, credo che queste siano le routine LAPACK utilizzate da numpy:

Aggiornamento: sulla stabilità, l'implementazione SVD sembra utilizzare un approccio di divisione e conquista, mentre la composizione elettronica usa un semplice algoritmo QR. Non posso accedere ad alcuni documenti SIAM pertinenti dal mio istituto (incolpare i tagli alla ricerca) ma ho trovato qualcosa che potrebbe supportare la valutazione che la routine SVD è più stabile.

Nel

Nakatsukasa, Yuji e Nicholas J. Higham. "Algoritmi di divisione e conquista spettrali stabili ed efficienti per la decomposizione degli autovalori simmetrici e SVD." SIAM Journal on Scientific Computing 35.3 (2013): A1325-A1349.

confrontano la stabilità di vari algoritmi di autovalori e sembra che l'approccio divide-and-conquer (usano lo stesso di numpy in uno degli esperimenti!) sia più stabile dell'algoritmo QR. Questo, insieme alle affermazioni altrove che i metodi D&C sono davvero più stabili, supporta la scelta di Ng.


Gli autovalori che ho ottenuto da svd sulla covarianza e svd sulla media dei dati centrati non sono gli stessi.
theDG

Tuttavia, i punteggi, ovvero X * V (dove V è ottenuto da [U, S, V] = svd (x) o svd (covx)), sono gli stessi.
theDG

1
@theGD Gli autovalori di cov (X) e i valori singolari di (X) non sono identici, vedere stats.stackexchange.com/questions/134282 .
ameba dice di reintegrare Monica il

non c'è bisogno di disperare per la mancanza di accesso alle riviste SIAM: il documento che citi è qui: opt.mist.iu-tokyo.ac.jp/~nakatsukasa/publishedpdf/pub13.pdf
Dima Pasechnik

2
@broncoAbierto the tech. il rapporto è qui: cpsc.yale.edu/sites/default/files/files/tr932.pdf (probabilmente non è possibile trovarlo facilmente a causa di un refuso "Symetric" nel titolo su cpsc.yale.edu/research/technical-reports / 1992-technical-reports :-))
Dima Pasechnik,

12

@amoeba ha avuto risposte eccellenti alle domande sulla PCA, inclusa questa sulla relazione tra SVD e PCA. Rispondendo alla tua domanda esatta farò tre punti:

  • matematicamente non c'è differenza se si calcola il PCA direttamente sulla matrice di dati o sulla sua matrice di covarianza
  • la differenza è dovuta esclusivamente alla precisione e alla complessità numerica. L'applicazione di SVD direttamente alla matrice di dati è numericamente più stabile rispetto alla matrice di covarianza
  • L'SVD può essere applicato alla matrice di covarianza per eseguire la PCA o ottenere valori di autigeni, infatti è il mio metodo preferito per risolvere i problemi di autigeni

Si scopre che SVD è più stabile rispetto alle tipiche procedure di decomposizione degli autovalori, in particolare per l'apprendimento automatico. Nell'apprendimento automatico è facile finire con regressori altamente collineari. SVD funziona meglio in questi casi.

Ecco il codice Python per dimostrare il punto. Ho creato una matrice di dati altamente collineare, ho ottenuto la sua matrice di covarianza e ho cercato di ottenere gli autovalori di quest'ultima. SVD funziona ancora, mentre in questo caso la normale decomposizione degli automi non riesce.

import numpy as np
import math
from numpy import linalg as LA

np.random.seed(1)

# create the highly collinear series
T = 1000
X = np.random.rand(T,2)
eps = 1e-11
X[:,1] = X[:,0] + eps*X[:,1]

C = np.cov(np.transpose(X))
print('Cov: ',C)

U, s, V = LA.svd(C)
print('SVDs: ',s)

w, v = LA.eig(C)
print('eigen vals: ',w)

Produzione:

Cov:  [[ 0.08311516  0.08311516]
 [ 0.08311516  0.08311516]]
SVDs:  [  1.66230312e-01   5.66687522e-18]
eigen vals:  [ 0.          0.16623031]

Aggiornare

In risposta al commento di Federico Poloni, ecco il codice con test di stabilità di SVD vs Eig su 1000 campioni casuali della stessa matrice sopra. In molti casi Eig mostra 0 un piccolo valore di autov, che porterebbe alla singolarità della matrice, e SVD non lo fa qui. SVD è circa due volte più preciso su una determinazione del valore di un piccolo autovena, che può essere o meno importante a seconda del problema.

import numpy as np
import math
from scipy.linalg import toeplitz
from numpy import linalg as LA

np.random.seed(1)

# create the highly collinear series
T = 100
p = 2
eps = 1e-8

m = 1000 # simulations
err = np.ones((m,2)) # accuracy of small eig value
for j in range(m):
    u = np.random.rand(T,p)
    X = np.ones(u.shape)
    X[:,0] = u[:,0]
    for i in range(1,p):
        X[:,i] = eps*u[:,i]+u[:,0]

    C = np.cov(np.transpose(X))

    U, s, V = LA.svd(C)

    w, v = LA.eig(C)

    # true eigen values
    te = eps**2/2 * np.var(u[:,1])*(1-np.corrcoef(u,rowvar=False)[0,1]**2)
    err[j,0] = s[p-1] - te
    err[j,1] = np.amin(w) - te


print('Cov: ',C)
print('SVDs: ',s)
print('eigen vals: ',w)
print('true small eigenvals: ',te)

acc = np.mean(np.abs(err),axis=0)    
print("small eigenval, accuracy SVD, Eig: ",acc[0]/te,acc[1]/te)

Produzione:

Cov:  [[ 0.09189421  0.09189421]
 [ 0.09189421  0.09189421]]
SVDs:  [ 0.18378843  0.        ]
eigen vals:  [  1.38777878e-17   1.83788428e-01]
true small eigenvals:  4.02633695086e-18
small eigenval, accuracy SVD, Eig:  2.43114702041 3.31970128319

X1=uX2=u+εv
u,v
(σ12σ12+ερσ1σ2σ12+ερσ1σ2σ12+2ερσ1σ2+ε2σ22σ2)
σ12,σ22,ρ - varianze delle uniformi e coefficiente di correlazione tra loro.

λ=12(σ22ε2-σ24ε4+4σ23ρσ1ε3+8σ22ρ2σ12ε2+8σ2ρσ13ε+4σ14+2σ2ρσ1ε+2σ12)
Il piccolo autovalore non può essere calcolato semplicemente collegando il ε in formula a causa della precisione limitata, quindi è necessario Taylor espanderlo:
λσ22ε2(1-ρ2)/2

io corro j=1,...,m simulazioni delle realizzazioni della matrice di dati, calcolare gli autovalori della matrice di covarianza simulata λ^je ottenere gli errori ej=λ-λ^j.


4
Sì, ma qui l'OP chiede informazioni su SVD vs EIG applicato sia alla matrice di covarianza.
ameba dice di reintegrare Monica il

1
@amoeba, ho chiarito la relazione tra SVD e PCA
Aksakal il

Questa è una buona risposta Vorrei, tuttavia, menzionare che svd non è in grado di rilevare autovalori negativi quando ce ne sono e si desidera vederli (se la matrice di covarianza non è originale ma è, per esempio, levigata o stimata in qualche modo o inferita o esce dalla cancellazione in coppia di valori mancanti). Inoltre, eig on cov matrix rimane un po 'più veloce di svd su di esso.
ttnphns,

@ttnphns, la matrice definita non positiva è un problema, ovviamente
Aksakal,

1
@FedericoPoloni, sull'aritmetica di FP e non conoscendo la risposta esatta non sono d'accordo. In questo caso conosco la risposta con sufficiente precisione per questo compito. Su 2x2 hai un punto giusto. Penserò a qualcosa.
Aksakal,

6

Per gli utenti di Python, vorrei sottolineare che per le matrici simmetriche (come la matrice di covarianza), è meglio usare la numpy.linalg.eighfunzione anziché una numpy.linalg.eigfunzione generale .

eighè 9-10 volte più veloce rispetto eigal mio computer (indipendentemente dalle dimensioni della matrice) e ha una migliore precisione (basata sul test di precisione di @ Aksakal).

Non sono convinto della dimostrazione del vantaggio dell'accuratezza dell'SVD con piccoli autovalori. Il test di @ Aksakal è di 1-2 ordini di grandezza più sensibili allo stato casuale che all'algoritmo (prova a tracciare tutti gli errori invece di ridurli ad un massimo assoluto). Significa che piccoli errori nella matrice di covarianza avranno un effetto maggiore sulla precisione rispetto alla scelta di un algoritmo di composizione elettronica. Inoltre, questo non è correlato alla domanda principale, che riguarda la PCA. I componenti più piccoli vengono ignorati in PCA.

Un argomento simile può essere fatto sulla stabilità numerica. Se dovessi usare il metodo della matrice di covarianza per PCA, lo scomporrei eighinvece di svd. Se fallisce (cosa che non è stata ancora dimostrata qui), probabilmente vale la pena ripensare al problema che si sta tentando di risolvere prima di iniziare a cercare un algoritmo migliore.



2

Per rispondere all'ultima parte della tua domanda, "Perché fanno SVD della matrice di covarianza, non della matrice dei dati?" Credo che sia per motivi di prestazioni e archiviazione. Tipicamente,m sarà un numero molto grande e anche se n è grande, ci aspetteremmo m»n.

Calcolare la matrice di covarianza e quindi eseguire SVD su quella è molto più veloce rispetto al calcolare SVD sulla matrice di dati completa in queste condizioni, per lo stesso risultato.

Anche per valori abbastanza piccoli i guadagni in termini di prestazioni sono fattori di migliaia (millisecondi contro secondi). Ho eseguito alcuni test sulla mia macchina per confrontare utilizzando Matlab: inserisci qui la descrizione dell'immagine

Questo è solo il tempo della CPU, ma le esigenze di archiviazione sono altrettanto importanti, se non di più. Se si tenta SVD su un milione per mille di matrice in Matlab, si verificherà un errore per impostazione predefinita, poiché richiede una dimensione di array funzionante di 7,4 TB.


Questo non risponde alla domanda che riguarda l'EIG della matrice cov contro SVD della matrice di covarianza .
ameba dice di reintegrare Monica il

1
La sua domanda alla fine, evidenziata in grassetto, afferma: "Perché fanno SVD della matrice di covarianza, non della matrice dei dati?" a cui ho risposto.
Gruff

Modificherò la frase di apertura per chiarire che stavo rispondendo a quella parte della domanda del PO. Vedo che potrebbe essere fonte di confusione. Grazie.
Gruff

Se si tenta SVD su un milione per mille di matrice in Matlab, per impostazione predefinita si verificherà un errore . In questi casi, la buona pratica numerica sta utilizzando il sottile SVD. Ciò migliorerà notevolmente le dimensioni e le prestazioni di archiviazione.
Federico Poloni,
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.