Andrew Ng가 PCA를 수행하기 위해 공분산 행렬의 EIG가 아닌 SVD를 선호하는 이유는 무엇입니까?


29

Andrew Ng의 Coursera 코스 및 기타 자료에서 PCA를 공부하고 있습니다. 스탠포드 NLP 과정에서 cs224n의 첫 번째 과제Andrew Ng강의 비디오에서 공분산 행렬의 고유 벡터 분해 대신 특이 값 분해를 수행하며 Ng는 SVD가 고유 분해보다 수치 적으로 더 안정적이라고 말합니다.

PCA의 경우 (m,n)크기의 공분산 행렬이 아닌 크기 의 데이터 행렬의 SVD를 수행해야 (n,n)합니다. 공분산 행렬의 고유 벡터 분해.

왜 데이터 행렬이 아닌 공분산 행렬의 SVD를 수행합니까?


8
공분산 행렬과 같은 정사각형 양의 반올림 행렬의 경우 고유 값과 특이 값 분해가 동일합니다.
amoeba는 Reinstate Monica가

5
나는 수학적 으로 동일 하다는 것을 의미 합니다. 숫자 적으로 그들은 실제로 다른 알고리즘을 사용하고 하나는 다른 알고리즘보다 안정적 일 수 있습니다 (Ng가 말한 것처럼). +1에 대해 더 알면 흥미로울 것입니다.
아메바는

4
여기에 대한 정보는 de.mathworks.com/matlabcentral/newsreader/view_thread/21268 입니다. 그러나 한 알고리즘이 다른 알고리즘보다 안정적인 이유에 대한 설명은 매우 기술적 인 것입니다.
amoeba는

2
x=randn(10000); x=x'*x; tic; eig(x); toc; tic; svd(x); toc;내 컴퓨터의 Matlab에서는 eig ()의 경우 12s, svd ()의 경우 26s를 출력합니다. 너무 느리면 적어도 더 안정적이어야합니다! :-)
amoeba는 Reinstate Monica가

4
그는 잘못된 이해를 바탕으로 될 수 있습니다 데이터 매트릭스의 SVD를하고는 있습니다 사용하는 것보다 더 안정 eig또는 svd공분산 행렬에,하지만 내가 아는 한 사용 사이에 큰 차이가 없다 eig거나 svd그들이 --- 공분산 행렬에이 두 가지 안정적인 알고리즘. 어쨌든 계산이 적기 때문에 eig에 더 많은 돈을 투자 할 것입니다 (두 가지 모두 최신 알고리즘으로 구현되었다고 가정).
Federico Poloni

답변:


17

amoeba는 이미 의견에 좋은 대답을했지만 공식적인 주장을 원한다면 여기에 간다.

행렬의 특이 값 분해 = U Σ V T 의 열, V는 의 고유 벡터이다 T 그리고 대각선 엔트리 Σ 있다 제곱근 그 고유의, 즉 σ I I = 에이A=UΣVTVATAΣ .σii=λi(ATA)

아시다시피 주성분은 경험적 공분산 행렬의 고유 벡터 공간에 대한 변수의 직교 투영입니다 . 성분의 분산은 고유 값λi(11n1ATA.λi(1n1ATA)

B v = λ v가 되도록 정사각 행렬 , α R 및 벡터 v를 고려하십시오 . 그때BαRvBv=λV

  1. Bkv=λ케이V
  2. λ(α)=αλ()

S = 1을 정의하자. SVD의S는의 계산한다 eigendecompositionSTS=1에스=11에이에이에스를 산출STS=1(n1)2ATAATA

  1. 의 고유 벡터 속성 1의 것이며, T(ATA)TATA=ATAATAATA
  2. 제곱근 의 고유의 , 특성 2, 1, 2는 다시1(n1)2ATAATA.1(n1)2λi(ATAATA)=1(n1)2λi2(ATA)=1n1λi(ATA)=λi(1n1ATA)

oil!

수치 안정성과 관련하여, 사용 된 알고리즘이 무엇인지 알아 내야합니다. 당신이 그것에 달려 있다면, 나는 이것이 numpy에 의해 사용되는 LAPACK 루틴이라고 생각합니다 :

업데이트 : 안정성에서 SVD 구현은 분할 및 정복 접근법을 사용하는 것처럼 보이지만 고유 분해는 일반 QR 알고리즘을 사용합니다. 기관에서 제공하는 관련 SIAM 논문 (비난 연구 삭감)에 액세스 할 수 없지만 SVD 루틴이 더 안정적이라는 평가를 뒷받침 할 수있는 것을 발견했습니다.

에서

Nakatsukasa, Yuji 및 Nicholas J. Higham. "대칭 고유 값 분해 및 SVD를위한 안정적이고 효율적인 스펙트럼 분할 및 정복 알고리즘." 과학 컴퓨팅에 관한 SIAM Journal 35.3 (2013) : A1325-A1349.

그들은 다양한 고유 값 알고리즘의 안정성을 비교하며, 분할 및 정복 접근법 (실험 중 하나에서 numpy와 동일한 방식을 사용합니다!)이 QR 알고리즘보다 더 안정적인 것으로 보입니다. 이것은 D & C 방법이 더 안정적이라는 다른 주장과 함께 Ng의 선택을 뒷받침합니다.


공분산에 대한 svd와 평균 중심 데이터의 svd에서 얻은 고유 값은 동일하지 않습니다.
theGD

그러나 점수, 즉 X * V (여기서 V는 [U, S, V] = svd (x) 또는 svd (covx)에서 얻음)는 동일합니다.
theGD

1
cov (X)의 @theGD 고유 값과 (X)의 특이 값은 동일하지 않습니다 ( stats.stackexchange.com/questions/134282 참조) .
amoeba는

SIAM 저널에 대한 접근의 부족 WRT 절망 할 필요가 없습니다 : 당신이 인용 용지가 여기에 있습니다 : opt.mist.iu-tokyo.ac.jp/~nakatsukasa/publishedpdf/pub13.pdf
디마 Pasechnik

2
@broncoAbierto 기술. 보고서는 여기에 있습니다 : cpsc.yale.edu/sites/default/files/files/tr932.pdf (하나는 아마 쉽게 인해에 제목에 오타 "Symetric"에 그것을 찾을 수 없습니다 cpsc.yale.edu/research/technical-reports / 1992-technical-reports :-))
Dima Pasechnik

12

@amoeba 포함 PCA 질문에 훌륭한 대답했다 이 한 PCA에 SVD의 관계에있다. 정확한 질문에 대답하면 세 가지 점을 알려 드리겠습니다.

  • 수학적으로 데이터 행렬에서 직접 또는 공분산 행렬에서 PCA를 계산하는지 여부에는 차이가 없습니다.
  • 그 차이는 순전히 수치 정밀도와 복잡성 때문입니다. SVD를 데이터 행렬에 직접 적용하는 것은 공분산 행렬보다 수치 적으로 더 안정적입니다.
  • SVD를 공분산 행렬에 적용하여 PCA를 수행하거나 고유 값을 얻을 수 있습니다. 실제로 고유 문제를 해결하는 것이 가장 좋아하는 방법입니다.

SVD는 특히 머신 러닝의 일반적인 고유 값 감소 절차보다 안정적입니다. 머신 러닝에서는 공 선형 회귀 분석을 쉽게 수행 할 수 있습니다. 이 경우 SVD가 더 잘 작동합니다.

요점을 시연하는 Python 코드가 있습니다. 나는 매우 공선적인 데이터 행렬을 만들고 공분산 행렬을 가져 와서 후자의 고유 값을 얻으려고했습니다. 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의 안정성 테스트가 위의 동일한 행렬의 무작위 샘플 1000 개에 대한 코드가 있습니다. 많은 경우에, 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
(σ12σ12+ερσ1σ2σ12+ερσ1σ2σ12+2ερσ1σ2+ε2σ22σ2)
σ12,σ22,ρ - 유니폼과 그들 사이의 상관 관계 coeffient의 편차를.

λ=12(σ22ε2σ24ε4+4σ23ρσ1ε3+8σ22ρ2σ12ε2+8σ2ρσ13ε+4σ14+2σ2ρσ1ε+2σ12)
The small eigenvalue can't be calculated by simply plugging the ε into formula due to limited precision, so you need to Taylor expand it:
λσ22ε2(1ρ2)/2

I run j=1,,m simulations of the realizations of the data matrix, calculate the eigenvalues of the simulated covariance matrix λ^j, and obtain the errors ej=λλ^j.


4
Yes, but here OP is asking about SVD vs EIG applied both to the covariance matrix.
amoeba says Reinstate Monica

1
@amoeba, I clarified the relation of SVD and PCA
Aksakal

This is a good answer. I wish, to mention, however, that svd can't detect negative eigenvalues when there are any and you want to see them (if covariance matrix is not original but is, say, smoothed or estimated somehow or inferred or comes out of pairwise deletion of missing values). Moreover, eig on cov matrix remains a little bit faster than svd on it.
ttnphns

@ttnphns, non positive definite matrix is an issue, of course
Aksakal

1
@FedericoPoloni, on FP arithmetic and not knowing the exact answer I disagree. In this case I do know the answer with enough precision for this task. On 2x2 you have a fair point. I'll think of something.
Aksakal

6

For Python users, I'd like to point out that for symmetric matrices (like the covariance matrix), it is better to use numpy.linalg.eigh function instead of a general numpy.linalg.eig function.

eigh is 9-10 times faster than eig on my computer (regardless of matrix size) and has better accuracy (based on @Aksakal's accuracy test).

I am not convinced with the demonstration of the accuracy benefit of SVD with small eigenvalues. @Aksakal's test is 1-2 orders of magnitude more sensitive to random state than to the algorithm (try plotting all errors instead of reducing them to one absolute maximum). It means that small errors in the covariance matrix will have a greater effect on accuracy than the choice of an eigendecomposition algorithm. Also, this is not related to the main question, which is about PCA. The smallest components are ignored in PCA.

A similar argument can be made about numerical stability. If I have to use the covariance matrix method for PCA, I would decompose it with eigh instead of svd. If it fails (which has not been demonstrated here yet), then it is probably worth rethinking the problem that you are trying to solve before starting to look for a better algorithm.



2

질문의 마지막 부분에 답하기 위해 "왜 그들은 데이터 행렬이 아닌 공분산 행렬의 SVD를 수행합니까?" 나는 그것이 성능 및 저장상의 이유라고 생각합니다. 일반적으로 매우 큰 숫자가 될지라도 크다, 우리는 기대할 것이다 .

공분산 행렬을 계산 한 다음 SVD를 수행하는 것은 동일한 결과를 위해 이러한 조건에서 전체 데이터 행렬에 대한 SVD를 계산하는 것보다 훨씬 빠릅니다.

상당히 작은 값이라도 성능 향상은 수천 배 (밀리 초 대 초)입니다. Matlab을 사용하여 비교하기 위해 컴퓨터에서 몇 가지 테스트를 실행했습니다. enter image description here

그것은 CPU 시간 일 뿐이지 만 스토리지 요구는 그다지 중요하지 않습니다. Matlab에서 백만 x 천 개의 매트릭스에서 SVD를 시도하면 7.4TB의 작업 배열 크기가 필요하기 때문에 기본적으로 오류가 발생합니다.


This does not answer the question which is about EIG of the cov matrix vs. SVD of the covariance matrix.
amoeba says Reinstate Monica

1
His question at the end, highlighted in bold, states, "Why do they do SVD of covariance matrix, not data matrix?" which I answered.
Gruff

I'll edit the opening sentence to make it clear I was answering that part of the OP's question. I see how that could be confusing. Thanks.
Gruff

If you attempt SVD on a million by a thousand matrix in Matlab it will error by default Good numerical practice is using the thin SVD, in these cases. This will vastly improve storage size and performance.
Federico Poloni
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.