@amoeba มีคำตอบที่ยอดเยี่ยมสำหรับคำถาม PCA รวมถึงเรื่องนี้เกี่ยวกับ SVD ถึง PCA ตอบคำถามของคุณแน่นอนฉันจะให้สามคะแนน:
- ในทางคณิตศาสตร์ไม่มีความแตกต่างไม่ว่าคุณจะคำนวณ PCA บนเมทริกซ์ข้อมูลโดยตรงหรือบนเมทริกซ์ความแปรปรวนร่วม
- ความแตกต่างนั้นเกิดจากความแม่นยำและความซับซ้อนของตัวเลข การใช้การใช้ SVD โดยตรงกับเมทริกซ์ข้อมูลนั้นมีเสถียรภาพมากกว่าตัวเลขกับเมทริกซ์ความแปรปรวนร่วม
- SVD สามารถนำไปใช้กับเมทริกซ์ความแปรปรวนร่วมเพื่อทำการ PCA หรือรับค่าไอเก็นอันที่จริงแล้วมันเป็นวิธีที่ฉันโปรดปรานในการแก้ปัญหาไอเก็น
ปรากฎว่า SVD นั้นมีความเสถียรมากกว่าขั้นตอนการสลายตัวของไอคิกแวลูแบบทั่วไป ในการเรียนรู้ของเครื่องมันเป็นเรื่องง่ายที่จะจบลงด้วย regressors collinear สูง SVD ทำงานได้ดีขึ้นในกรณีเหล่านี้
นี่คือรหัสไพ ธ อนเพื่อสาธิตจุด ฉันสร้างเมทริกซ์ข้อมูล collinear สูงรับเมทริกซ์ความแปรปรวนร่วมและพยายามหาค่าลักษณะเฉพาะของหลัง SVD ยังคงใช้งานได้ในขณะที่การสลายตัวของไอจีนธรรมดาล้มเหลวในกรณีนี้
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)
เอาท์พุท:
Cov: [[ 0.08311516 0.08311516]
[ 0.08311516 0.08311516]]
SVDs: [ 1.66230312e-01 5.66687522e-18]
eigen vals: [ 0. 0.16623031]
ปรับปรุง
ตอบรับความคิดเห็นของ Federico Poloni นี่คือรหัสที่มีการทดสอบความเสถียรของ SVD กับ Eig ในตัวอย่างสุ่ม 1,000 ตัวอย่างของเมทริกซ์เดียวกันข้างต้น ในหลายกรณี Eig แสดง 0 ค่าไอเกนขนาดเล็กซึ่งจะนำไปสู่ภาวะเอกฐานของเมทริกซ์และ SVD ไม่ได้ทำที่นี่ SVD มีความแม่นยำมากขึ้นเกี่ยวกับการกำหนดค่าไอเก็ตขนาดเล็กเป็นสองเท่าซึ่งอาจมีหรือไม่มีความสำคัญขึ้นอยู่กับปัญหาของคุณ
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)
เอาท์พุท:
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,ρ
ค่าลักษณะเฉพาะที่เล็กที่สุด:
ค่าลักษณะเฉพาะขนาดเล็กไม่สามารถคำนวณได้โดยเพียงเสียบเข้ากับสูตรเนื่องจากความแม่นยำที่ จำกัด ดังนั้นคุณต้องขยาย Taylor:
λ=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
ผมทำงานจำลองของความเข้าใจของเมทริกซ์ข้อมูลในการคำนวณค่าลักษณะเฉพาะของการจำลองความแปรปรวนเมทริกซ์และได้รับข้อผิดพลาดe_jλญจJ = λ - λเจj=1,…,mλ^jej=λ−λ^j