Relação entre SVD e PCA. Como usar o SVD para executar o PCA?


352

A análise de componentes principais (PCA) é geralmente explicada por meio de uma decomposição por si própria da matriz de covariância. No entanto, também pode ser realizado via decomposição de valor singular (SVD) da matriz de dados X . Como funciona? Qual é a conexão entre essas duas abordagens? Qual é a relação entre SVD e PCA?

Ou, em outras palavras, como usar o SVD da matriz de dados para realizar a redução da dimensionalidade?


8
Eu escrevi essa pergunta no estilo FAQ juntamente com a minha própria resposta, porque ela é frequentemente solicitada de várias formas, mas não há thread canônico e, portanto, é difícil fechar duplicatas. Forneça meta comentários neste meta thread em anexo .
Ameba


2
Além da excelente e detalhada resposta da ameba com seus links adicionais, eu recomendo verificar isso , onde o PCA é considerado lado a lado algumas outras técnicas baseadas em SVD. A discussão lá apresenta álgebra quase idêntica à da ameba, com apenas uma pequena diferença de que o discurso ali, ao descrever o PCA, trata da decomposição de X / √ no svd [ouX/X/n ] em vez de X- o que é simplesmente conveniente no que se refere ao PCA feito através da composição automática da matriz de covariância. X/n1X
ttnphns

PCA é um caso especial de SVD. O PCA precisa dos dados normalizados, idealmente mesma unidade. A matriz é nxn no PCA.
Orvar Korvar

@OrvarKorvar: De que matriz nxn você está falando?
Cbhihe

Respostas:


412

Seja a matriz de dados tamanho de n × p , onde n é o número de amostras ep é o número de variáveis. Vamos supor que ele esteja centralizado , ou seja, os meios das colunas foram subtraídos e agora são iguais a zero.Xn×pnp

Em seguida, o matriz covariância C é dada por C = XX / ( n - 1 ) . É uma matriz simétrica e, portanto, pode ser diagonalizada: C = V L V , onde V é uma matriz de vetores próprios (cada coluna é um vetor próprio) e L é uma matriz diagonal com valores próprios λ i em ordem decrescente na diagonal . Os autovetores são chamados eixos principais oup×pCC=XX/(n1)

C=VLV,
VLλi principais direções principaisdos dados. As projeções dos dados nos eixos principais são denominadas componentes principais , também conhecidas como pontuação do PC ; elas podem ser vistas como novas variáveis ​​transformadas. O -ésimo componente principal é dada por J coluna -ésimo de X V . As coordenadas do i ponto de dados -ésimo no novo espaço PC são dadas pelo i fileira -ésimo de X V .jjXViiXV

Se agora realizarmos a decomposição do valor singular de , obteremos uma decomposição X = U S V , onde U é uma matriz unitária e S é a matriz diagonal dos valores singulares s i . A partir daqui, pode-se ver facilmente que C = V S UU S V/ ( n - 1 ) = V S 2X

X=USV,
USsio que significa que os vectores singulares certasVsão direcções principais e que os valores singulares estão relacionados com os valores próprios da matriz covariância por meio deλi=s 2 i /(n-1). Os componentes principais são dadas porXV=LSVV=LS.
C=VSUUSV/(n1)=VS2n1V,
Vλi=si2/(n1)XV=USVV=US

Para resumir:

  1. Se , as colunas de V são as principais direções / eixos.X=USVV
  2. US
  3. λi=si2/(n1)λi
  4. n1UVS/n1
  5. XXX/(n1)
  6. XUV
  7. X
  8. pk<pkUk×kSUkSkn×kk
  9. kVkXk=UkSkVkn×pkXkk
  10. Un×nVp×pn>pnpUSUn×pnpUnp

Links adicionais

Animação PCA rotativa


5
(xix¯)(xix¯)xiX(XX¯)(XX¯)/(n1)XXX/(n1)(xix¯)2x¯=0xi2

2
Um exemplo de código para PCA por SVD: stackoverflow.com/questions/3181593/…
optimist

1
Ameba, assumi a responsabilidade de adicionar mais um link, de acordo com os links fornecidos. Espero que você ache apropriado.
precisa saber é

2
Sλi=si2

1
@sera Basta transpor sua matriz e se livrar do seu problema. Você só ficará confuso caso contrário.
Ameba

22

Eu escrevi um trecho de código Python & Numpy que acompanha a resposta da @ amoeba e deixo aqui caso seja útil para alguém. Os comentários são retirados principalmente da resposta da @ 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).

A matriz de covariância

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

S

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

viiλiiSi

PCA de um conjunto de dados Gaussian gerado aleatoriamente

A=(1201)uivi

SVD para um exemplo 2x2

ASuivi

XA=X

X=i=1rσiuivjT,

{ui}{vi}Svi

ui=1(n1)λiXvi,

σi

σi2=(n1)λi.

uiXuiXiviX

Entro em mais alguns detalhes e benefícios do relacionamento entre PCA e SVD neste artigo mais longo .


Obrigado pelo seu anser Andre. Apenas duas pequenas correções de erros de digitação: 1. No último parágrafo, você está confundindo esquerda e direita. 2. Na fórmula (capital) de X, você está usando v_j em vez de v_i.
Alon
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.