Warum bevorzugt Andrew Ng SVD und nicht EIG der Kovarianzmatrix, um PCA zu machen?


29

Ich studiere PCA von Andrew Ngs Coursera-Kurs und anderen Materialien. In der ersten Aufgabe des Stanford NLP-Kurses cs224n und im Vorlesungsvideo von Andrew Ng wird anstelle der Eigenvektorzerlegung der Kovarianzmatrix eine Singulärwertzerlegung durchgeführt, und Ng sagt sogar, dass SVD numerisch stabiler ist als eigendecomposition.

Nach meinem Verständnis sollten wir für PCA eine SVD der Datenmatrix der (m,n)Größe durchführen, nicht der Kovarianzmatrix der (n,n)Größe. Und Eigenvektorzerlegung der Kovarianzmatrix.

Warum machen sie SVD der Kovarianzmatrix, nicht der Datenmatrix?


8
Für quadratische symmetrische positive semidefinite Matrizen (wie Kovarianzmatrizen) sind Eigenwert- und Singulärwertzerlegungen genau gleich.
Amöbe sagt Reinstate Monica

5
Ich meine, sie sind mathematisch gleich. Numerisch könnten sie tatsächlich unterschiedliche Algorithmen verwenden und einer könnte stabiler sein als der andere (wie Ng sagt). Dies wäre interessant, um mehr über +1 zu erfahren.
Amöbe sagt Reinstate Monica

4
Einige Informationen dazu hier: de.mathworks.com/matlabcentral/newsreader/view_thread/21268 . Es ist jedoch zu beachten, dass jede Erklärung, warum ein Algorithmus stabiler als ein anderer ist, sehr technisch sein wird.
Amöbe sagt Reinstate Monica

2
In Matlab x=randn(10000); x=x'*x; tic; eig(x); toc; tic; svd(x); toc;auf meinem Computer werden 12s für eig () und 26s für svd () ausgegeben. Wenn es so viel langsamer ist, muss es zumindest stabiler sein! :-)
Amöbe sagt Reinstate Monica

4
Dies könnte auf einem falschen Verständnis beruhen: Die Erstellung einer SVD der Datenmatrix ist stabiler als die Verwendung eigoder Verwendung svdder Kovarianzmatrix, aber meines Wissens gibt es keinen großen Unterschied zwischen der Verwendung eigoder Verwendung svdder Kovarianzmatrix beide abwärtsstabilen Algorithmen. Wenn überhaupt, würde ich mein Geld auf eig sein setze mehr stabil, da es weniger Berechnungen durchführt (vorausgesetzt , beide mit state-of-the-art Algorithmen implementiert sind).
Federico Poloni

Antworten:


17

Amöbe gab bereits eine gute Antwort in den Kommentaren, aber wenn Sie ein formelles Argument wollen, hier geht es.

Die Singularwertzerlegung einer Matrix ist , wobei die Spalten von Eigenvektoren von und die diagonalen Einträge von die Quadratwurzeln ihrer Eigenwerte sind, dh .A = U V T V A T A σ i i = AA=UΣVTVATAΣσii=λi(ATA)

Wie Sie wissen, sind die Hauptkomponenten die orthogonalen Projektionen Ihrer Variablen auf den Raum der Eigenvektoren der empirischen Kovarianzmatrix . Die Varianz der Komponenten ergibt sich aus ihren Eigenwerten .λi(11n1ATAλi(1n1ATA)

Betrachte eine beliebige quadratische Matrix , und einen Vektor so dass . Dannα R v B v = λ vBαRvBv=λv

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

Definieren wir . Die SVD von berechnet die eigendezusammensetzung von zu ergebenSSTS=1S=1n1ATASSTS=1(n1)2ATAATA

  1. die Eigenvektoren von , die nach Eigenschaft 1 diejenigen vonA T A(ATA)TATA=ATAATAATA
  2. die Quadratwurzeln der Eigenwerte von , die nach Eigenschaft 2, dann 1, dann wieder 2 .1(n1)2ATAATA1(n1)2λi(ATAATA)=1(n1)2λi2(ATA)=1n1λi(ATA)=λi(1n1ATA)

Voilà!

In Bezug auf die numerische Stabilität müsste man herausfinden, welche Algorithmen verwendet werden. Wenn Sie dazu bereit sind, glaube ich, dass dies die von numpy verwendeten LAPACK-Routinen sind:

Update: In Bezug auf die Stabilität scheint die SVD-Implementierung einen Divide-and-Conquer-Ansatz zu verwenden, während die eigendecomposition einen einfachen QR-Algorithmus verwendet. Ich kann nicht auf einige relevante SIAM-Papiere meiner Institution zugreifen (Kürzungen bei der Schuldforschung), aber ich habe etwas gefunden, das die Einschätzung unterstützen könnte, dass die SVD-Routine stabiler ist.

Im

Nakatsukasa, Yuji und Nicholas J. Higham. "Stabile und effiziente Spektralteilungs- und Eroberungsalgorithmen für die symmetrische Eigenwertzerlegung und die SVD." SIAM Journal on Scientific Computing 35.3 (2013): A1325-A1349.

Sie vergleichen die Stabilität verschiedener Eigenwertalgorithmen, und es scheint, dass der Divide-and-Conquer-Ansatz (sie verwenden denselben Ansatz wie Numpy in einem der Experimente!) stabiler ist als der QR-Algorithmus. Dies, zusammen mit den Behauptungen an anderer Stelle, dass D & C-Methoden tatsächlich stabiler sind, stützt Ngs Wahl.


Die Eigenwerte, die ich aus svd für Kovarianz und svd für mittlere zentrierte Daten erhalten habe, sind nicht die gleichen.
theGD

Die Punktzahlen, dh X * V (wobei V aus [U, S, V] = svd (x) oder svd (covx) erhalten wird), sind jedoch gleich.
theGD

1
@theGD Eigenwerte von cov (X) und Singularwerte von (X) sind nicht identisch, siehe stats.stackexchange.com/questions/134282 .
Amöbe sagt Reinstate Monica

Kein Grund zur Verzweiflung, da Sie keinen Zugang zu SIAM-Zeitschriften haben: Das von Ihnen zitierte Papier ist hier: opt.mist.iu-tokyo.ac.jp/~nakatsukasa/publishedpdf/pub13.pdf
Dima Pasechnik

2
@broncoAbierto the tech. Der Bericht ist hier: cpsc.yale.edu/sites/default/files/files/tr932.pdf (man kann ihn wahrscheinlich nicht leicht finden, weil der Titel auf cpsc.yale.edu/research/technical-reports den Tipp "Symetric" enthält / 1992-technical-reports :-))
Dima Pasechnik

12

@amoeba hatte ausgezeichnete Antworten auf PCA Fragen, darunter diese auf Bezug von SVD zu PCA. Bei der Beantwortung Ihrer genauen Frage werde ich drei Punkte ansprechen:

  • Mathematisch gibt es keinen Unterschied, ob Sie PCA direkt in der Datenmatrix oder in ihrer Kovarianzmatrix berechnen
  • Der Unterschied liegt lediglich in der numerischen Präzision und Komplexität. Das Anwenden von SVD direkt auf die Datenmatrix ist numerisch stabiler als auf die Kovarianzmatrix
  • SVD kann auf die Kovarianzmatrix angewendet werden, um PCA durchzuführen oder Eigenwerte zu erhalten. Tatsächlich ist es meine bevorzugte Methode zur Lösung von Eigenproblemen

Es stellt sich heraus, dass SVD insbesondere für maschinelles Lernen stabiler ist als typische Verfahren zur Zerlegung von Eigenwerten. Beim maschinellen Lernen kommt es leicht zu hochkollinearen Regressoren. SVD funktioniert in diesen Fällen besser.

Hier ist Python-Code, um den Punkt zu demonstrieren. Ich habe eine hochkollineare Datenmatrix erstellt, ihre Kovarianzmatrix erhalten und versucht, deren Eigenwerte zu ermitteln. SVD funktioniert immer noch, während die gewöhnliche Eigenzerlegung in diesem Fall fehlschlägt.

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)

Ausgabe:

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

Aktualisieren

Als Antwort auf Federico Polonis Kommentar hier der Code mit Stabilitätsprüfungen von SVD gegen Eig an 1000 Zufallsstichproben derselben Matrix oben. In vielen Fällen zeigt Eig einen kleinen Eigenwert von 0 an, was zur Singularität der Matrix führen würde, und SVD tut dies hier nicht. SVD ist bei einer kleinen Eigenwertbestimmung etwa doppelt so genau, was je nach Problem möglicherweise wichtig ist oder nicht.

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)

Ausgabe:

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

Hier Code funktioniert der Code. Anstatt die zufällige Kovarianzmatrix zum Testen der Routinen zu generieren, generiere ich die zufällige Datenmatrix mit zwei Variablen: wobei - unabhängige einheitliche Zufallsvariablen. Die Kovarianzmatrix lautet also wobei - Varianzen der Uniformen und der Korrelationskoeffizienten zwischen Sie.u , v ( σ 2 1 σ 2 1 + ε & rgr; σ 1 σ 2 σ 2 1 + ε & rgr; σ 1 σ 2 σ 2 1 + 2 ε & rgr; σ 1

x1=ux2=u+εv
u,v
(σ12σ12+ερσ1σ2σ12+ερσ1σ2σ12+2ερσ1σ2+ε2σ22σ2)
σ12,σ22,ρ

Sein kleinster Eigenwert: Der kleine Eigenwert kann nicht durch einfaches Einstecken des in die Formel berechnet werden, da die Genauigkeit begrenzt ist. Sie müssen ihn also erweitern:

λ=12(σ22ε2σ24ε4+4σ23ρσ1ε3+8σ22ρ2σ12ε2+8σ2ρσ13ε+4σ14+2σ2ρσ1ε+2σ12)
ε
λσ22ε2(1ρ2)/2

Ich führe Simulationen der Realisierungen der Datenmatrix aus, berechne die Eigenwerte der simulierten Kovarianzmatrix und die Fehler .λ j e j = λ - λ jj=1,,mλ^jej=λλ^j


4
Ja, aber hier fragt OP nach SVD und EIG, die beide auf die Kovarianzmatrix angewendet werden.
Amöbe sagt Reinstate Monica

1
@amoeba, ich habe die Beziehung zwischen SVD und PCA
Aksakal 16.11.17

Das ist eine gute Antwort. Ich möchte jedoch erwähnen, dass svd negative Eigenwerte nicht erkennen kann, wenn es welche gibt, und Sie möchten sie sehen (wenn die Kovarianzmatrix nicht original ist, sondern geglättet oder geschätzt wird oder aus einer paarweisen Löschung stammt) fehlender Werte). Außerdem bleibt eig on cov matrix ein bisschen schneller als svd on it.
TTNPHNS

@ttnphns, nicht positive definite Matrix ist natürlich ein Problem
Aksakal

1
@FedericoPoloni, über FP-Arithmetik und nicht die genaue Antwort weiß ich nicht. In diesem Fall kenne ich die Antwort genau genug für diese Aufgabe. Auf 2x2 hast du einen fairen Punkt. Ich werde an etwas denken.
Aksakal

6

Für Python-Benutzer möchte ich darauf hinweisen, dass es für symmetrische Matrizen (wie die Kovarianzmatrix) besser ist, numpy.linalg.eighFunktion anstelle einer allgemeinen numpy.linalg.eigFunktion zu verwenden.

eighist 9-10 mal schneller als eigauf meinem Computer (unabhängig von der Matrixgröße) und hat eine bessere Genauigkeit (basierend auf dem Genauigkeitstest von @ Aksakal).

Ich bin nicht überzeugt von der Demonstration des Genauigkeitsvorteils der SVD mit kleinen Eigenwerten. @ Aksakals Test ist 1-2 Größenordnungen empfindlicher für den Zufallszustand als für den Algorithmus (versuchen Sie, alle Fehler aufzuzeichnen, anstatt sie auf ein absolutes Maximum zu reduzieren). Dies bedeutet, dass kleine Fehler in der Kovarianzmatrix eine größere Auswirkung auf die Genauigkeit haben als die Wahl eines Algorithmus für die Neuzusammenstellung. Dies hat auch nichts mit der Hauptfrage zu tun, bei der es um PCA geht. Die kleinsten Komponenten werden in PCA ignoriert.

Ein ähnliches Argument kann zur numerischen Stabilität angeführt werden. Wenn ich die Kovarianzmatrixmethode für PCA verwenden muss, würde ich sie mit eighanstelle von zerlegen svd. Wenn dies fehlschlägt (was hier noch nicht demonstriert wurde), lohnt es sich wahrscheinlich, das zu lösende Problem zu überdenken, bevor Sie nach einem besseren Algorithmus suchen.



2

Um den letzten Teil Ihrer Frage zu beantworten: "Warum machen sie SVD der Kovarianzmatrix, nicht der Datenmatrix?" Ich glaube, es ist aus Performance- und Speichergründen. Typischerweise ist eine sehr große Zahl, und selbst wenn groß ist, würden wir erwarten .n m nmnmn

Das Berechnen der Kovarianzmatrix und das anschließende Durchführen einer SVD ist unter diesen Bedingungen erheblich schneller als das Berechnen der SVD für die vollständige Datenmatrix, um dasselbe Ergebnis zu erzielen.

Selbst bei relativ kleinen Werten beträgt der Leistungszuwachs mehrere tausend Faktoren (Millisekunden gegenüber Sekunden). Ich habe ein paar Tests auf meinem Computer durchgeführt, um Matlab zu vergleichen: Bildbeschreibung hier eingeben

Das ist nur CPU-Zeit, aber der Speicherbedarf ist genauso wichtig, wenn nicht noch wichtiger. Wenn Sie in Matlab SVD auf einer Million mal Tausend-Matrix versuchen, tritt standardmäßig ein Fehler auf, da eine funktionierende Array-Größe von 7,4 TB erforderlich ist.


Dies schließt nicht die Frage beantworten , die über EIG des cov Matrix vs. SVD des Kovarianzmatrix .
Amöbe sagt Reinstate Monica

1
Seine Frage am Ende, fett hervorgehoben, lautet: "Warum machen sie SVD der Kovarianzmatrix, nicht der Datenmatrix?" was ich beantwortet habe.
Gruff

Ich werde den Eröffnungssatz überarbeiten, um zu verdeutlichen, dass ich diesen Teil der Frage des OP beantwortet habe. Ich sehe, wie verwirrend das sein könnte. Vielen Dank.
Gruff

Wenn Sie in Matlab versuchen, eine Million mal tausend-Matrix mit SVD zu bearbeiten, tritt standardmäßig ein Fehler auf . Dadurch werden Speichergröße und Leistung erheblich verbessert.
Federico Poloni
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.