Como executar a redução de dimensionalidade com o PCA em R

30

Eu tenho um grande conjunto de dados e quero realizar uma redução de dimensionalidade.

Agora, em todos os lugares que leio, posso usar o PCA para isso. No entanto, ainda não consigo entender o que fazer depois de calcular / executar o PCA. Em R isso é facilmente feito com o comando princomp.

Mas o que fazer depois de calcular o PCA? Se decidi usar os primeiros componentes principais, como reduzi exatamente meu conjunto de dados?100

Floris Devriendt
fonte
Essa pergunta não é muito clara (100 PCs são o seu conjunto de dados de dimensionalidade reduzida), mas especificamente sobre a reconstrução das variáveis ​​originais (o tópico da resposta aceita), veja também: Como reverter o PCA e reconstruir as variáveis ​​originais de vários componentes principais?
Ameba diz Reinstate Monica

Respostas:

35

Acredito que o que você está recebendo na sua pergunta esteja relacionado ao truncamento de dados usando um número menor de componentes principais (PC). Para tais operações, acho que a função prcompé mais ilustrativa, pois é mais fácil visualizar a multiplicação de matrizes usada na reconstrução.

Primeiro, forneça um conjunto de dados sintético Xt, você executa o PCA (normalmente você centralizaria amostras para descrever os PCs relacionados a uma matriz de covariância:

#Generate data
m=50
n=100
frac.gaps <- 0.5 # the fraction of data with NaNs
N.S.ratio <- 0.25 # the Noise to Signal ratio for adding noise to data

x <- (seq(m)*2*pi)/m
t <- (seq(n)*2*pi)/n

#True field
Xt <- 
 outer(sin(x), sin(t)) + 
 outer(sin(2.1*x), sin(2.1*t)) + 
 outer(sin(3.1*x), sin(3.1*t)) +
 outer(tanh(x), cos(t)) + 
 outer(tanh(2*x), cos(2.1*t)) + 
 outer(tanh(4*x), cos(0.1*t)) + 
 outer(tanh(2.4*x), cos(1.1*t)) + 
 tanh(outer(x, t, FUN="+")) + 
 tanh(outer(x, 2*t, FUN="+"))

Xt <- t(Xt)

#PCA
res <- prcomp(Xt, center = TRUE, scale = FALSE)
names(res)

Nos resultados ou prcomp, você pode ver os PCs ( res$x), os valores próprios ( res$sdev) fornecendo informações sobre a magnitude de cada PC e as cargas ( res$rotation).

res$sdev
length(res$sdev)
res$rotation
dim(res$rotation)
res$x
dim(res$x)

Ao quadrar os valores próprios, você obtém a variação explicada por cada PC:

plot(cumsum(res$sdev^2/sum(res$sdev^2))) #cumulative explained variance

Por fim, você pode criar uma versão truncada dos seus dados usando apenas os principais PCs (importantes):

pc.use <- 3 # explains 93% of variance
trunc <- res$x[,1:pc.use] %*% t(res$rotation[,1:pc.use])

#and add the center (and re-scale) back to data
if(res$scale != FALSE){
	trunc <- scale(trunc, center = FALSE , scale=1/res$scale)
}
if(res$center != FALSE){
    trunc <- scale(trunc, center = -1 * res$center, scale=FALSE)
}
dim(trunc); dim(Xt)

Você pode ver que o resultado é uma matriz de dados um pouco mais suave, com recursos de pequena escala filtrados:

RAN <- range(cbind(Xt, trunc))
BREAKS <- seq(RAN[1], RAN[2],,100)
COLS <- rainbow(length(BREAKS)-1)
par(mfcol=c(1,2), mar=c(1,1,2,1))
image(Xt, main="Original matrix", xlab="", ylab="", xaxt="n", yaxt="n", breaks=BREAKS, col=COLS)
box()
image(trunc, main="Truncated matrix (3 PCs)", xlab="", ylab="", xaxt="n", yaxt="n", breaks=BREAKS, col=COLS)
box()

insira a descrição da imagem aqui

E aqui está uma abordagem muito básica que você pode fazer fora da função prcomp:

#alternate approach
Xt.cen <- scale(Xt, center=TRUE, scale=FALSE)
C <- cov(Xt.cen, use="pair")
E <- svd(C)
A <- Xt.cen %*% E$u

#To remove units from principal components (A)
#function for the exponent of a matrix
"%^%" <- function(S, power)
     with(eigen(S), vectors %*% (values^power * t(vectors)))
Asc <- A %*% (diag(E$d) %^% -0.5) # scaled principal components

#Relationship between eigenvalues from both approaches
plot(res$sdev^2, E$d) #PCA via a covariance matrix - the eigenvalues now hold variance, not stdev
abline(0,1) # same results

Agora, decidir quais PCs reter é uma questão separada - uma questão em que eu estava interessado há algum tempo . Espero que ajude.

Marc na caixa
fonte
2
Marc, você não precisa registrar o centro e escalar explicitamente, prcompfaz isso por você. Dê uma olhada res$centere res$scale. IMHO é menos propenso a erros de usá-los (nenhuma diferença acidental sobre centralizar ou não / dimensionar ou não entre a chamada explícita scalee a prcompchamada).
Cbeleites suporta Monica
11
Essa resposta precisa ser expandida porque não responde às perguntas do OP sobre what to do after calculating the PCAou how do I reduce my dataset exactly? Dado que o OP conduziu o PCA em sua amostra, sua pergunta é o que fazer com ele e o que realmente acontece com essas subamostras; não como fazer PCA. Poderíamos também propor E <- eigen(cov(Sample)); A<- scale(scale=F, Sample) %*% E$vectorsa realização de outra maneira de obter as pontuações (que é realmente o que o princomp faz stats:::princomp.default).
usεr11852 diz Reinstate Monic
11
@ user11852 - a pergunta faz referência especificamente à redução do conjunto de dados (ou seja, o truncamento que demonstrei aqui). Vou deixar que ele decida se era isso que ele estava procurando ou não.
Marc na caixa
11
@ Marc, obrigado pela resposta. Acho que preciso dar um passo atrás e reler tudo novamente, porque estou preso em como qualquer uma das respostas acima lida com a redução da dimensionalidade. Porque, como você mostra, dim (trunc) = dim (Xt). Qual era o benefício disso, as dimensões não foram reduzidas.
B_Miner 18/07/2013
2
@B_Miner - Lembre-se de que o truncamento é usado para se concentrar nos principais padrões de dados e para filtrar padrões e ruídos de pequena escala. Os dados truncados não são menores em termos de dimensões, mas "mais limpos". No entanto, o truncamento reduz a quantidade de dados em que toda a matriz pode ser reconstruída com apenas alguns vetores. Um bom exemplo está no uso do PCA para compactação de imagem, em que um número menor de PCs pode ser usado para reconstruir a imagem. Esse subconjunto menor de vetores ocupa menos memória, mas a reconstrução terá algumas perdas nos detalhes em pequena escala.
Marc na caixa
3

Essas outras respostas são muito boas e detalhadas, mas estou me perguntando se você está realmente fazendo uma pergunta muito mais básica: o que você faz depois de ter seus PCs?

Cada PC simplesmente se torna uma nova variável. Digamos que PC1 seja responsável por 60% da variação total e PC2 seja responsável por 30%. Como são 90% da variação total contabilizada, você pode simplesmente considerar essas duas novas variáveis ​​(PCs) como uma versão simplificada de suas variáveis ​​originais. Isso significa ajustá-los aos modelos, se é disso que você está interessado. Quando chega a hora de interpretar seus resultados, você o faz no contexto das variáveis ​​originais que são correlacionadas com cada PC.

Desculpe se subestimei o escopo da pergunta!

atrichornis
fonte
2

iλiΣk=1pλkpp=784λ

Praticamente com o PCA, você está usando as projeções dos PCs (as "pontuações") como dados substitutos para sua amostra original. Você faz toda a sua análise das pontuações e depois reconstrói sua amostra original de volta usando os PCs para descobrir o que aconteceu no seu espaço original (que é basicamente a Regressão dos Componentes Principais ). Claramente, se você é capaz de interpretar significativamente seus vetores próprios ("loadings"), então você está em uma posição ainda melhor: você pode descrever o que acontece com sua amostra no modo de variação apresentado por esse carregamento, fazendo inferência diretamente nesse carregamento e não me importo com reconstrução. :)

Em geral, o que você "após calcular o PCA" depende do objetivo da sua análise. O PCA fornece apenas uma subamostra linearmente independente de seus dados, que é a ideal sob um critério de reconstrução de RSS. Você pode usá-lo para classificação, regressão ou ambos, ou, como mencionei, pode querer reconhecer modos ortogonais significativos de variações em sua amostra.

Um comentário : Eu acho que a melhor maneira ingênua de decidir o número de componentes a serem retidos é basear sua estimativa em algum limiar de variação de amostra que você gostaria de reter em sua amostra de dimensionalidade reduzida, em vez de apenas um número arbitrário, por exemplo. 3, 100, 200. Conforme explicado pelo usuário4959, você pode verificar essa variação cumulativa verificando o campo relevante da lista sob o $loadingscampo no objeto de lista produzido por princomp.

usεr11852 diz Reinstate Monic
fonte
11
Como você menciona a regressão do componente principal, em R é fornecido pelo pacote pls. Quanto ao número de componentes a serem retidos, não vejo nenhuma vantagem real de decidir a variação% sobre o número não. de componentes (talvez porque trabalhe com dados com níveis de ruído muito diferentes. Como o @ Marc-in-the-box menciona, existem muitas abordagens diferentes para determinar um número apropriado de PCs, e a estratégia será ( deveria) dependem tanto os dados do tipo e do tipo de análise de dados que está a seguir.
cbeleites suporta Monica
plsprincomp {stats}KKDD
11
sim, é ingênuo. Não concordo que definir uma% arbitrária da variação explicada tenha uma vantagem intrínseca a qualquer outro corte arbitrário. De qualquer forma, não vale a pena brigar por causa disso: a) o OP nunca pediu conselhos sobre como escolher o não. de PCs para manter eb) Acho que concordamos que uma inspeção adequada do modelo de PCA deve ser feita de qualquer maneira.
Cbeleites suporta Monica
Sem problemas; foi apenas um comentário que fiz antes da minha resposta. (Eu vou colocar o meu comentário último parágrafo como eu acho que deixa perplexo ao invés de esclarece o que eu quero dizer)
usεr11852 diz Reintegrar Monic
0

Depois de executar o PCA, você poderá selecionar os dois primeiros componentes e a plotagem. É possível ver a variação dos componentes usando uma plotagem de scree em R. Também usando a função de resumo com loadings = T, você pode aprimorar a variação de recursos com os componentes.

Você também pode consultar este http://www.statmethods.net/advstats/factor.html e http://statmath.wu.ac.at/~hornik/QFS1/principal_component-vignette.pdf

Tente pensar o que você quer. Você pode interpretar muitas coisas da análise PCA.

Best Abhik

user4959
fonte