Como reverter o PCA e reconstruir variáveis ​​originais de vários componentes principais?

113

A análise de componentes principais (PCA) pode ser usada para redução de dimensionalidade. Após a redução dessa dimensionalidade, como se pode reconstruir aproximadamente as variáveis ​​/ características originais de um pequeno número de componentes principais?

Como alternativa, como remover ou descartar vários componentes principais dos dados?

Em outras palavras, como reverter o PCA?


Dado que o PCA está intimamente relacionado à decomposição de valor singular (SVD), a mesma pergunta pode ser feita da seguinte maneira: como reverter o SVD?

ameba
fonte
10
Estou postando este tópico de perguntas e respostas, porque estou cansado de ver dezenas de perguntas fazendo exatamente isso e de não ser capaz de fechá-las como duplicatas porque não temos uma discussão canônica sobre esse tópico. Existem vários tópicos semelhantes com respostas decentes, mas todos parecem ter sérias limitações, como por exemplo, concentrando-se exclusivamente em R.
ameba
4
Agradeço o esforço - acho que há uma necessidade terrível de coletar informações sobre o PCA, o que ele faz e o que não faz em um ou vários encadeamentos de alta qualidade. Fico feliz que você tenha decidido fazer isso!
Sycorax
1
Não estou convencido de que essa resposta canônica "limpeza" sirva a seu propósito. O que temos aqui é uma excelente pergunta genérica e resposta, mas cada uma das perguntas tinha algumas sutilezas sobre o PCA na prática, que são perdidas aqui. Essencialmente, você respondeu a todas as perguntas, executou o PCA e descartou os componentes principais inferiores, onde, às vezes, detalhes ricos e importantes estão ocultos. Além disso, você ter revertido para livros didáticos de Álgebra Linear notação que é precisamente o que faz PCA opaca para muitas pessoas, em vez de usar a língua franca de estatísticos casuais, que é R.
Thomas Browne
1
@ Thomas Obrigado. Acho que temos um desacordo, prazer em discuti-lo no chat ou no Meta. Muito brevemente: (1) De fato, seria melhor responder a cada pergunta individualmente, mas a dura realidade é que isso não acontece. Muitas perguntas permanecem sem resposta, como a sua provavelmente teria. (2) A comunidade aqui prefere fortemente respostas genéricas úteis para muitas pessoas; você pode ver que tipo de respostas são mais votadas. (3) Concordo em matemática, mas foi por isso que dei o código R aqui! (4) Discordo da lingua franca; pessoalmente, eu não sei R.
ameba
@amoeba Receio não saber como encontrar o referido bate-papo, pois nunca participei de meta-discussões antes.
22416 Thomas

Respostas:

147

O PCA calcula os vetores próprios da matriz de covariância ("eixos principais") e os classifica por seus valores próprios (quantidade de variação explicada). Os dados centralizados podem então ser projetados nesses eixos principais para produzir componentes principais ("pontuações"). Para fins de redução de dimensionalidade, é possível manter apenas um subconjunto de componentes principais e descartar o restante. (Veja aqui a introdução de um leigo ao PCA .)

Seja a matriz de dados com linhas (pontos de dados) colunas (variáveis ​​ou recursos). Depois de se subtrair a média vector a partir de cada linha, obtemos o centrado matriz de dados . Seja a matriz de alguns vetores próprios que queremos usar; esses seriam os vetores próprios com os maiores valores próprios. Então a matriz das projeções de PCA ("pontuações") será simplesmente dada por . n×pnpXrawn×pnpμXVp×kkkn×kZ=XV

Isso é ilustrado na figura abaixo: a primeira subparcela mostra alguns dados centralizados (os mesmos dados que uso nas minhas animações no encadeamento vinculado) e suas projeções no primeiro eixo principal. A segunda subparcela mostra apenas os valores dessa projeção; a dimensionalidade foi reduzida de dois para um:

insira a descrição da imagem aqui

Para poder reconstruir as duas variáveis ​​originais desse componente principal, podemos mapeá-lo de volta para as dimensões com . De fato, os valores de cada PC devem ser colocados no mesmo vetor usado para a projeção; compare as subparcelas 1 e 3. O resultado é dado por . Estou exibindo-o na terceira subtrama acima. Para obter a reconstrução final , precisamos adicionar o vetor médio a isso:pVX^=ZV=XVVX^rawμ

PCA reconstruction=PC scoresEigenvectors+Mean

Observe que é possível ir diretamente do primeiro subparcela para o terceiro multiplicando pela matriz ; isso é chamado de matriz de projeção . Se todos os são utilizados vectores próprios, então representa a matriz identidade (sem redução de dimensionalidade é realizada, portanto, "reconstrução" é perfeito). Se apenas um subconjunto de autovetores for usado, não será identidade.XVVpVV

Isso funciona para um ponto arbitrário no espaço do PC; ele pode ser mapeado para o espaço original via .zx^=zV

Descartar (remover) os principais PCs

Às vezes, alguém deseja descartar (remover) um ou alguns dos principais PCs e manter o restante, em vez de manter os PCs principais e descartar o restante (como acima). Nesse caso, todas as fórmulas permanecem exatamente iguais , mas deve consistir em todos os eixos principais, exceto os que se deseja descartar. Em outras palavras, sempre deve incluir todos os PCs que você deseja manter.VV

Advertência sobre PCA na correlação

Quando o PCA é feito na matriz de correlação (e não na matriz de covariância), os dados brutos não são centralizados apenas subtraindo mas também dimensionados dividindo cada coluna por seu desvio padrão . Nesse caso, para reconstruir os dados originais, é necessário redimensionar as colunas de com e somente depois adicionar novamente o vetor médio .XrawμσiX^σiμ


Exemplo de processamento de imagem

Este tópico geralmente aparece no contexto do processamento de imagens. Considere Lenna - uma das imagens padrão na literatura sobre processamento de imagens (siga os links para descobrir de onde vem). Abaixo, à esquerda, mostro a variante em escala de cinza dessa imagem (arquivo disponível aqui ).512×512

Duas versões em escala de cinza da imagem Lenna.  O da direita é granulado, mas definitivamente reconhecível.

Podemos tratar essa imagem em escala de cinza como uma matriz de dados . Eu executo o PCA nele e computo usando os 50 primeiros componentes principais. O resultado é exibido à direita.512×512XrawX^raw


Revertendo SVD

O PCA está intimamente relacionado à decomposição de valor singular (SVD), consulte Relação entre SVD e PCA. Como usar o SVD para executar o PCA? para mais detalhes. Se uma matriz for editada como SVD como e você selecionar um vetor dimensional que represente o ponto no espaço em "reduzido" de dimensões, para mapeá-lo de volta para dimensões, é necessário multiplicá-lo com .n×pXX=USVkzUkpS1:k,1:kV:,1:k


Exemplos em R, Matlab, Python e Stata

Conduzirei o PCA com os dados da Fisher Iris e depois reconstruí-lo usando os dois primeiros componentes principais. Estou fazendo PCA na matriz de covariância, não na matriz de correlação, ou seja, não estou escalando as variáveis ​​aqui. Mas ainda tenho que adicionar a média de volta. Alguns pacotes, como o Stata, cuidam disso através da sintaxe padrão. Agradecemos a @StasK e @Kodiologist por sua ajuda com o código.

Vamos verificar a reconstrução do primeiro ponto de dados, que é:

5.1        3.5         1.4        0.2

Matlab

load fisheriris
X = meas;
mu = mean(X);

[eigenvectors, scores] = pca(X);

nComp = 2;
Xhat = scores(:,1:nComp) * eigenvectors(:,1:nComp)';
Xhat = bsxfun(@plus, Xhat, mu);

Xhat(1,:)

Resultado:

5.083      3.5174      1.4032     0.21353

R

X = iris[,1:4]
mu = colMeans(X)

Xpca = prcomp(X)

nComp = 2
Xhat = Xpca$x[,1:nComp] %*% t(Xpca$rotation[,1:nComp])
Xhat = scale(Xhat, center = -mu, scale = FALSE)

Xhat[1,]

Resultado:

Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
   5.0830390    3.5174139    1.4032137    0.2135317

Para um exemplo R elaborado de reconstrução de imagens por PCA, veja também esta resposta .

Pitão

import numpy as np
import sklearn.datasets, sklearn.decomposition

X = sklearn.datasets.load_iris().data
mu = np.mean(X, axis=0)

pca = sklearn.decomposition.PCA()
pca.fit(X)

nComp = 2
Xhat = np.dot(pca.transform(X)[:,:nComp], pca.components_[:nComp,:])
Xhat += mu

print(Xhat[0,])

Resultado:

[ 5.08718247  3.51315614  1.4020428   0.21105556]

Observe que isso difere um pouco dos resultados em outros idiomas. Isso ocorre porque a versão do Python do conjunto de dados Iris contém erros .

Stata

webuse iris, clear
pca sep* pet*, components(2) covariance
predict _seplen _sepwid _petlen _petwid, fit
list in 1

  iris   seplen   sepwid   petlen   petwid    _seplen    _sepwid    _petlen    _petwid  
setosa      5.1      3.5      1.4      0.2   5.083039   3.517414   1.403214   .2135317  
ameba
fonte
1
No MATLAB, você pode recuperar o mu das saídas PCA padrão e também pode fornecer o número de componentes nas entradas.
Aksakal
2
@ Aksakal Tentei fazer todos os três trechos de código o mais semelhante (e o mais claro) possível; em particular, eu queria calcular manualmente antes de ligar para pca () e também executar o PCA com todos os componentes e usar apenas componentes ao executar produtos pontuais entre pontuações e autovetores. Agora modifiquei o código Python para seguir o mesmo padrão. μnComp
Ameba
3
Eu removeria tudo da resposta que não está relacionada à resposta direta à pergunta, como a imagem e o processamento de imagem dessa linda garota. Se alguém não está interessado em imagens, isso dificulta o consumo. Lembre-se de que quem está fazendo a pergunta já está profundamente confuso.
Aksakal
5
Lenna é um conjunto de dados tão padrão quanto a íris.
StasK
2
@amoeba Eu estava falando sobre tamanho, profundidade de bits e até pixels pretos na borda. Não tenho uma versão definitiva http://www.ece.rice.edu/~wakin/images/ : "Parece haver muitas versões da imagem de teste de Lena (também conhecida como" Lenna ") disponíveis. Esse problema foi observado por Shapiro em seu trabalho de 1993, e continua surpreendentemente verdadeiro hoje "
Laurent Duval