Andrew Ng neden PCA yapmak için koordine matrisinin EIG'sini değil SVD'yi kullanmayı tercih ediyor?


29

Andrew Ng's Coursera dersinden ve diğer materyallerden PCA okuyorum. Stanford NLP dersinde cs224n'nin ilk ödevinde ve Andrew Ng'un ders videosunda kovaryans matrisinin özvektör ayrışması yerine tekil değer ayrıştırması yapıyorlar ve Ng, SVD'nin özerk kompozisyondan sayısal olarak daha kararlı olduğunu söylüyor.

Anladığım kadarıyla PCA için, (m,n)boyutun kovaryans matrisinden değil, boyut veri matrisinin SVD'sini yapmalıyız (n,n). Ve kovaryans matrisinin özvektör ayrışımı.

Neden veri matrisi değil de kovaryans matrisinin SVD'sini yapıyorlar?


8
Kare simetrik pozitif yarı kesin matris için (kovaryans matrisi gibi), özdeğer ve tekil değer ayrışımları tamamen aynıdır.
amip diyor Reinstate Monica

5
Yani matematiksel olarak aynılar. Sayısal olarak, gerçekten de farklı algoritmalar kullanabilirler ve biri diğerinden daha kararlı olabilir (Ng dediği gibi). +1 hakkında daha fazla şey bilmek ilginç olurdu.
amip diyor Reinstate Monica,

4
Bununla ilgili bazı bilgiler: de.mathworks.com/matlabcentral/newsreader/view_thread/21268 . Ancak, bir algoritmanın neden diğerinden daha istikrarlı olacağına dair herhangi bir açıklamanın çok teknik olacağına dikkat edin.
amip diyor Reinstate Monica

2
Makinemdeki Matlab'da x=randn(10000); x=x'*x; tic; eig(x); toc; tic; svd(x); toc;eig () için 12s ve svd () için 26s çıktılar. Çok yavaşsa, en azından daha kararlı olmalı! :-)
amip

4
Bu yanlış bir anlayışa dayalı olabilir: karekod bir SVD yapıyor olduğu kullanmaktan daha istikrarlı eigveya svdkovaryans matrisi üzerinde, ancak bildiğim kadarıyla kullanma arasında büyük bir fark var eigya svdbunlar --- kovaryans matrisi üzerinde her ikisi de geriye dönük kararlı algoritmalar. Eğer bir şey olursa, daha az hesaplama yaptığı için (her ikisinin de modern algoritmalarla uygulandığını varsayarsak), e- paramın daha istikrarlı olmasına para harcardım .
Federico Poloni

Yanıtlar:


17

Amip yorumlarda zaten iyi bir cevap verdi, ancak resmi bir tartışma istiyorsanız, işte burada.

Bir matris tekil değer ayrışımı olan sütunları, özvektörleri ve köşegen girişleri olan karekök kendi öz değerleri arasında, örneğin, .A = U Σ V T V A T A Σ σ i i = AA=UΣVTVATAΣσii=λi(ATA)

Bildiğiniz gibi, temel bileşenler değişkenlerinizin ampirik kovaryans matrisinin özvektörlerinin uzayı üzerindeki ortogonal izdüşümleri . Bileşenlerin varyansı özdeğerleri .λi(1)1n1ATAλi(1n1ATA)

Herhangi bir kare matris düşünün , ve bir vektör şekilde . Sonraα R v B v = λ vBαRvBv=λv

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

tanımını verelim . SVD ve eigendecomposition hesaplamak verimSSTS=1S=1n1ATASSTS=1(n1)2ATAATA

  1. özvektörleri , ki bu özellik 1'e göreA , T bir(ATA)TATA=ATAATAATA
  2. karekök eigen değerlerinin sonra tekrar özelliği 2, daha sonra 1, 2 ile olan, .1(n1)2ATAATA1(n1)2λi(ATAATA)=1(n1)2λi2(ATA)=1n1λi(ATA)=λi(1n1ATA)

Voila

Sayısal stabilite ile ilgili olarak, kullanılan alogitimlerin ne olduğunu bulmak gerekir. Buna kalkarsan, bunların numpy tarafından kullanılan LAPACK rutinleri olduğuna inanıyorum:

Güncelleme: İstikrar konusunda, SVD uygulaması bir ayrıştırma ve fethetme yaklaşımı kullanıyor gibi gözüküyor, eigendebilgisi ise basit bir QR algoritması kullanıyor. Kurumumdan bazı SIAM belgelerine erişemiyorum (araştırma kesintilerini azaltıyorum) ancak SVD rutininin daha kararlı olduğu değerlendirmesini destekleyebilecek bir şey buldum.

İçinde

Nakatsukasa, Yuji ve Nicholas J. Higham. "Kararlı ve verimli spektral bölme ve simetrik özdeğer ayrıştırma ve SVD için algoritmalar fethetmek." SIAM Bilimsel Hesaplama Dergisi 35.3 (2013): A1325-A1349.

çeşitli özdeğer algoritmalarının kararlılığını karşılaştırırlar ve bölme-fethetme yaklaşımının (deneylerden birinde numpy ile aynı şeyi kullanırlar!) QR algoritmasından daha stabil görünüyorlar. Bu, D&C yöntemlerinin gerçekten daha istikrarlı olduğu yönündeki iddialarla birlikte Ng'nin seçimini destekliyor.


Kovalyansta svd'den, ortalama merkezli veride svd'den elde ettiğim özdeğerler aynı değil.
GD

Ancak, X * V (V [U, S, V] = svd (x) veya svd'den (covx) elde edilir) olan puanlar aynıdır.
-GD,

1
@ theGD cov (X) 'un özdeğerleri ve (X)' un tekil değerleri aynı değildir, bkz. stats.stackexchange.com/questions/134282 .
amip diyor Reinstate Monica,

SIAM dergilere erişim eksikliği wrt umutsuzluğa gerek: Eğer alıntı kağıt buradadır: opt.mist.iu-tokyo.ac.jp/~nakatsukasa/publishedpdf/pub13.pdf
Dima Pasechnik

2
TeknisyeninbroncoAbier. rapor burada: cpsc.yale.edu/sites/default/files/files/tr932.pdf (biri muhtemelen, " Symetric " yazım hatası nedeniyle cpsc.yale.edu/research/technical-reports adresindeki " Symetric " yazım hatası nedeniyle kolayca bulunamaz. / 1992-teknik raporlar :-))
Dima Pasechnik 17:17

12

@amoeba dahil PCA sorulara mükemmel yanıtlar vardı bu bir PCA için SVD ilişkiye. Tam sorunuza cevap vererek üç puan vereceğim:

  • matematiksel olarak PCA'yı doğrudan veri matrisinde mi, yoksa kovaryans matrisinde mi hesapladığınız konusunda hiçbir fark yoktur.
  • fark tamamen sayısal hassasiyet ve karmaşıklıktan kaynaklanmaktadır. SVD'yi doğrudan veri matrisine uygulamak, kovaryans matrisinden sayısal olarak daha kararlıdır.
  • SVD, PCA'yı gerçekleştirmek veya öz değerlerini elde etmek için kovaryans matrisine uygulanabilir, aslında, özdeğer problemlerini çözmede en sevdiğim yöntemdir.

SVD'nin, özellikle makine öğrenmesi için, özdeğerin bozulma işlemlerinden tipik olarak daha istikrarlı olduğu ortaya çıktı. Makine öğreniminde son derece collressear regresörleri kullanmak kolaydır. SVD bu durumlarda daha iyi çalışır.

İşte nokta demo için Python kodu. Son derece collinear bir veri matrisi oluşturdum, kovaryans matrisini aldım ve ikincisinin özdeğerlerini elde etmeye çalıştım. SVD hala çalışıyor, sıradan öz ayrışma bu durumda başarısız oluyor.

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)

Çıktı:

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

Güncelleştirme

Federico Poloni'nin yorumuna cevap olarak, işte SVD ve Eig'in yukarıdaki aynı matriksin 1000 rastgele örneğinde stabilite testine sahip kod. Birçok durumda Eig, matrisin tekilliğine yol açacak olan 0 küçük öz değeri gösterir ve SVD burada yapmaz. SVD, sorununuza bağlı olarak önemli olabilecek veya olmayabilir önemli olan küçük bir öz değer tespiti için yaklaşık iki kat daha kesindir.

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)

Çıktı:

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,ρ

λ=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

j=1,,mλ^jej=λλ^j


4
EIG uygulanan vs Evet, ama burada OP SVD soruyor hem kovaryans matrisine.
amip diyor Reinstate Monica,

1
@ amoeba, SVD ile PCA arasındaki ilişkiyi açıklığa kavuşturdum
Aksakal

Bu iyi bir cevap. Bununla birlikte, svd'nin herhangi bir var olduğunda ve onları görmek istediğinizde negatif özdeğerleri tespit edememesini istiyorum (eğer kovaryans matrisi orijinal değilse, fakat düzelirse, bir şekilde çıkarıldıysa veya çıktısı varsa veya ikili olarak siliniyorsa). eksik değerler). Ayrıca, cov matrisindeki eig, svd'den biraz daha hızlı kalır.
ttnphns,

@ ttnphns, pozitif olmayan kesin matris bir konudur, tabii ki
Aksakal

1
@ FedericoPoloni, FP aritmetik ve kesin cevabı bilmeden ben katılmıyorum. Bu durumda cevabı bu görev için yeterince hassasiyetle biliyorum. 2x2'de senin için iyi bir nokta var. Bir şey düşüneceğim.
Aksakal

6

Python kullanıcıları için, simetrik matrisler için (kovaryans matrisi gibi), numpy.linalg.eighgenel bir işlev yerine işlevi kullanmanın daha iyi olduğunu belirtmek isterim numpy.linalg.eig.

eigheigbilgisayarıma göre (matris boyutundan bağımsız olarak) 9-10 kat daha hızlı ve @ Aksakal'ın doğruluk testine dayanarak daha iyi doğruluğa sahip.

SVD'nin küçük özdeğerlere sahip olduğu doğruluk faydasının gösterilmesi konusunda ikna olmadım. @ Aksakal'ın testi, algoritmaya göre rastgele duruma karşı daha hassas 1-2 büyüklük sırasıdır (tüm hataları tek bir mutlak maksimum değere düşürmek yerine çizmeyi deneyin). Bu, kovaryans matrisindeki küçük hataların, bir öznitelik oluşturma algoritması seçiminden daha doğruluk üzerinde daha büyük bir etkiye sahip olacağı anlamına gelir. Ayrıca, bu PCA ile ilgili ana soru ile ilgili değildir. En küçük parçalar PCA'da yoksayılır.

Sayısal kararlılık konusunda da benzer bir tartışma yapılabilir. PCA için kovaryans matris yöntemini kullanmak zorunda kalırsam, eighbunun yerine onu ayrıştırırım svd. Başarısız olursa (henüz burada gösterilmemiş olan), o zaman daha iyi bir algoritma aramaya başlamadan önce çözmeye çalıştığınız problemi yeniden düşünmeye değer.



2

mnmn

Kovaryans matrisinin hesaplanması ve bunun üzerine SVD yapılması, aynı sonuç için, bu koşullar altında tam veri matrisi üzerindeki SVD'yi hesaplamaktan çok daha hızlıdır.

Oldukça küçük değerler için bile, performans kazancı binlerce faktördür (milisaniye ile saniye). Matlab kullanarak karşılaştırmak için makinemde birkaç test yaptım: görüntü tanımını buraya girin

Bu sadece CPU zamanı, ancak depolama ihtiyaçları, daha fazla olmasa da, önemli. Matlab'da bir milyon matriste milyonlarca SVD denerseniz, varsayılan olarak hata verir, çünkü 7.4TB'lik bir çalışma dizisi boyutuna ihtiyaç duyar.


Bu, cov matrisinin EIG'si ile kovaryans matrisinin SVD'si hakkındaki soruyu cevaplamaz .
amip diyor Reinstate Monica

1
Sonunda sorusu, koyu renkle vurgulandı: “Neden veri matrisi değil, koordine matrisinin SVD'sini yapıyorlar?” hangi cevap verdim.
Gruff

Açılış cümlesini OP'nin sorusunun bu kısmına cevap verdiğimi netleştirmek için düzenleyeceğim. Bunun nasıl kafa karıştırıcı olabileceğini anlıyorum. Teşekkürler.
Gruff

Eğer Matlab'da bir milyon matriste SVD'yi bir milyon matrisle denerseniz, varsayılan olarak hata verir . Bu durumda, iyi sayısal uygulama, ince SVD'yi kullanıyordur. Bu, depolama boyutunu ve performansını büyük ölçüde geliştirir.
Federico Poloni
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.