SVD와 PCA의 관계. SVD를 사용하여 PCA를 수행하는 방법?


351

주성분 분석 (PCA)은 공분산 행렬의 고유 분해를 통해 설명됩니다. 그러나 데이터 행렬 의 단일 값 분해 (SVD)를 통해 수행 할 수도 있습니다 . 어떻게 작동합니까? 이 두 가지 방법의 관계는 무엇입니까? SVD와 PCA의 관계는 무엇입니까?X

즉, 데이터 행렬의 SVD를 사용하여 차원 축소를 수행하는 방법은 무엇입니까?


8
이 FAQ 스타일 질문은 다양한 형태로 자주 요청되기 때문에 내 대답과 함께 작성되었지만 표준 스레드가 없으므로 복제본을 닫기가 어렵습니다. 이 메타 스레드 에 메타 주석을 제공하십시오 .
amoeba


2
향후의 링크 우수하고 자세한 아메바의 대답 이외에 내가 확인하는 것이 좋습니다 수있는 PCA가 나란히 다른 SVD 기반 기술로 간주되는 경우를. 거기에 대한 논의는 PCA를 설명 할 때 [또는 ]의 svd 분해에 관한 연설에서 약간의 차이점을 제외하고는 아메바와 거의 대수를 나타냅니다 . 대신 -공분산 행렬의 고유 분해를 통해 수행 된 PCA와 관련되어있어 편리합니다. X/X/n XX/n1X
ttnphns

PCA는 SVD의 특별한 경우입니다. PCA는 데이터가 이상적이고 동일한 단위로 표준화되어야합니다. 매트릭스는 PCA에서 nxn입니다.
Orvar Korvar

@ OrvarKorvar : 무슨 nxn 행렬에 대해 이야기하고 있습니까?
Cbhihe

답변:


412

데이터 행렬 를 크기로 설정하십시오. 여기서 은 샘플 수이고 는 변수 수입니다. 중심 이 있다고 가정합시다 . 즉, 열 평균을 빼고 이제 0과 같습니다. N × P는 n 개의 페이지Xn×pnp

그런 다음 공분산 행렬 는 됩니다. 대칭 행렬이므로 대각선으로 나타낼 수 있습니다. 여기서 는 고유 벡터 행렬 (각 열은 고유 벡터)이고 은 대각선 에서 내림차순 으로 고유 값이 대각선 행렬 . 고유 벡터를 데이터의 주축 또는 주 방향 이라고합니다. 주축의 데이터 투영을 주성분 이라고하며 PC 점수 라고도 함C C = XX / ( n - 1 ) C = V L V , V L λ i j j X V i i X Vp×pCC=XX/(n1)

C=VLV,
VLλi; 이들은 새롭고 변형 된 변수로 볼 수 있습니다. 주성분이 주어진다 번째 의 열 번째 . 새 PC 공간에서 번째 데이터 포인트 의 좌표는 의 번째 행에 의해 제공됩니다 .jjXViiXV

이제 의 특이 값 분해를 수행 하면 분해 을 얻습니다 여기서 는 단일 행렬이고 는 대각선 행렬입니다. 특이 값 . 여기에서 즉 오른쪽 특이 벡터 는 주 방향이며 특이 값은 를 통해 공분산 행렬의 고유 값과 . 주요 구성 요소는X = U S V , U S s i C = V S UU S V/ ( n - 1 ) = V S 2X

X=USV,
USsiVλi=s 2 i /(n1)XV=USVV=US
C=VSUUSV/(n1)=VS2n1V,
Vλi=si2/(n1)XV=USVV=US .

요약:

  1. 만약 다음의 열 주 방향 / 축이된다.VX=USVV
  2. 열 은 주요 구성 요소 ( "점수")입니다.US
  3. 특이 값은 통한 공분산 행렬의 고유 값과 관련이 있습니다. 고유 값 는 각 PC의 분산을 보여줍니다.λ iλi=si2/(n1)λi
  4. 표준화 된 점수는 열에 의해 주어지고 로딩은 열에 의해 주어집니다 . "로딩"이 주요 방향과 혼동되어서는 안되는 이유는 여기여기 를 참조하십시오 .VS/n1UVS/n1
  5. 위의 내용은 가 중앙에있는 경우에만 정확합니다 . X그러면 공분산 행렬은 .XX/(n1)
  6. 위의 내용은 행에 샘플이 있고 열에 변수가있는 대해서만 정확합니다 . 변수가 행에 있고 열에 샘플이 있으면 및 해석을 교환합니다.U VXUV
  7. 공분산 행렬 대신 상관 행렬에서 PCA를 수행하려면 열을 중심에 두어야 할뿐만 아니라 표준화해야합니다. 즉 표준 편차로 나눕니다.X
  8. 에서 데이터의 차원을 감소시키기 위해 하는 선택 의 첫 번째 열 , 및 의 좌상 부 . 그들의 곱 는 첫 PC를 포함 하는 필수 행렬 입니다.k < p k U k × k S U k S k n × k kpk<pkUk×kSUkSkn×kk
  9. 첫 번째 PC에 해당 주축 하면 행렬이 원래 크기이지만 더 낮은 순위입니다 (순위 ). 이 행렬 는 처음 PC 에서 원본 데이터를 재구성 합니다 . 재구성 오류가 가장 적습니다 . 여기에서 내 대답을 참조하십시오 .kVkXk=UkSkVkn×pkXkk
  10. 엄밀히 말하면, 는 크기이고 는 크기입니다. 그러나 이면 의 마지막 열 은 임의적입니다 ( 의 해당 행 은 상수 0 임). 따라서 크기 의 를 반환 하는 이코노미 크기 (또는 얇은 ) SVD를 사용해야합니다 . 큰 경우 행렬 는 불필요하게 거대합니다. 의 반대 상황에도 동일하게 적용됩니다.Un×nVp×pn>pnpUSUn×pnpUnp.

추가 링크

PCA 애니메이션 회전


5
@Antoine, 공분산 행렬은 정의에 따라 과 같습니다. 여기서 꺾쇠 괄호는 평균값을 나타냅니다. . 모든 가 하나의 행렬 에서 행으로 쌓인 경우이 표현식은 . 가 중심에 있으면 단순화됩니다 . 차이를 생각하십시오. 그것은 동일한이다 . 그러나 (즉 데이터가 중심에 은 단순히 의 평균 값입니다 .(xix¯)(xix¯)xiX(XX¯)(XX¯)/(n1)XXX/(n1)(xix¯)2x¯=0xi2
amoeba


1
Amoeba, 귀하의 링크에 따라 링크를 하나 더 추가 할 책임이 있습니다. 당신이 그것을 알기를 바랍니다.
ttnphns

2
@amoeba 예, 왜 사용합니까? 또한 동일한 분모를 사용할 수 있습니까? 문제는 수식을보고 이해하는 방법을 알고 있다는 것입니다. λ i = s 2 iSλi=si2
Dims

1
@sera 그냥 행렬을 바꾸고 문제를 제거하십시오. 그렇지 않으면 혼란 스러울 것입니다.
amoeba

22

@amoeba의 답변과 함께 제공되는 Python & Numpy 스 니펫을 작성했으며 누군가에게 유용 할 수 있도록 여기에 남겨 둡니다. 의견은 대부분 @amoeba의 답변에서 가져온 것입니다.

import numpy as np
from numpy import linalg as la
np.random.seed(42)


def flip_signs(A, B):
    """
    utility function for resolving the sign ambiguity in SVD
    http://stats.stackexchange.com/q/34396/115202
    """
    signs = np.sign(A) * np.sign(B)
    return A, B * signs


# Let the data matrix X be of n x p size,
# where n is the number of samples and p is the number of variables
n, p = 5, 3
X = np.random.rand(n, p)
# Let us assume that it is centered
X -= np.mean(X, axis=0)

# the p x p covariance matrix
C = np.cov(X, rowvar=False)
print "C = \n", C
# C is a symmetric matrix and so it can be diagonalized:
l, principal_axes = la.eig(C)
# sort results wrt. eigenvalues
idx = l.argsort()[::-1]
l, principal_axes = l[idx], principal_axes[:, idx]
# the eigenvalues in decreasing order
print "l = \n", l
# a matrix of eigenvectors (each column is an eigenvector)
print "V = \n", principal_axes
# projections of X on the principal axes are called principal components
principal_components = X.dot(principal_axes)
print "Y = \n", principal_components

# we now perform singular value decomposition of X
# "economy size" (or "thin") SVD
U, s, Vt = la.svd(X, full_matrices=False)
V = Vt.T
S = np.diag(s)

# 1) then columns of V are principal directions/axes.
assert np.allclose(*flip_signs(V, principal_axes))

# 2) columns of US are principal components
assert np.allclose(*flip_signs(U.dot(S), principal_components))

# 3) singular values are related to the eigenvalues of covariance matrix
assert np.allclose((s ** 2) / (n - 1), l)

# 8) dimensionality reduction
k = 2
PC_k = principal_components[:, 0:k]
US_k = U[:, 0:k].dot(S[0:k, 0:k])
assert np.allclose(*flip_signs(PC_k, US_k))

# 10) we used "economy size" (or "thin") SVD
assert U.shape == (n, p)
assert S.shape == (p, p)
assert V.shape == (p, p)

21

μxi

X=(x1TμTx2TμTxnTμT).

공분산 행렬

S=1n1i=1n(xiμ)(xiμ)T=1n1XTX

S

S=VΛVT=i=1rλiviviT,

viiλiiSi

임의로 생성 된 가우스 데이터 세트의 PCA

A=(1201)uivi

2x2 예제의 SVD

ASuivi

XA=X

X=i=1rσiuivjT,

{ui}{vi}Svi

ui=1(n1)λiXvi,

σi

σi2=(n1)λi.

uiXuiXiviX

이 긴 기사에서 PCA와 SVD의 관계대한 자세한 내용과 이점을 살펴 보겠습니다 .


anser 앙드레 감사합니다. 두 번의 작은 오타 수정 : 1. 마지막 단락에서 왼쪽과 오른쪽을 혼동합니다. 2. X의 (자본) 수식에서 v_i 대신 v_j를 사용하고 있습니다.
Alon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.