@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(σ21σ21+ερσ1σ2σ21+ερσ1σ2σ21+2ερσ1σ2+ε2σ22σ2)
σ21,σ22,ρ
λ=12(σ22ε2−σ42ε4+4σ32ρσ1ε3+8σ22ρ2σ21ε2+8σ2ρσ31ε+4σ41−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−√+2σ2ρσ1ε+2σ21)
ελ≈σ22ε2(1−ρ2)/2
j=1,…,mλ^jej=λ−λ^j