Je crois que ce que vous voulez dire dans votre question concerne la troncature des données en utilisant un plus petit nombre de composants principaux (PC). Pour de telles opérations, je pense que la fonction prcomp
est plus illustrative en ce sens qu'il est plus facile de visualiser la multiplication matricielle utilisée en reconstruction.
Tout d'abord, donnez un ensemble de données synthétiques Xt
, vous effectuez l'ACP (en général, vous centrez les échantillons afin de décrire les PC liés à une matrice de covariance:
#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)
Dans les résultats ou prcomp
, vous pouvez voir les PC ( res$x
), les valeurs propres ( res$sdev
) donnant des informations sur la magnitude de chaque PC et les chargements ( res$rotation
).
res$sdev
length(res$sdev)
res$rotation
dim(res$rotation)
res$x
dim(res$x)
En quadrillant les valeurs propres, vous obtenez la variance expliquée par chaque PC:
plot(cumsum(res$sdev^2/sum(res$sdev^2))) #cumulative explained variance
Enfin, vous pouvez créer une version tronquée de vos données en utilisant uniquement les principaux PC (importants):
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)
Vous pouvez voir que le résultat est une matrice de données légèrement plus lisse, avec des fonctionnalités à petite échelle filtrées:
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()

Et voici une approche très basique que vous pouvez faire en dehors de la fonction 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
Maintenant, décider quels PC conserver est une question distincte - une question qui m'intéressait il y a quelque temps . J'espère que ça t'as aidé.