Sorunuzda ne elde edeceğinize, daha az sayıda ana bileşen (PC) kullanarak verilerin kesilmesiyle ilgili olduğuna inanıyorum. Bu tür işlemler için, prcomp
yeniden yapılanmada kullanılan matris çarpımını görselleştirmenin daha kolay olması nedeniyle fonksiyonun daha açıklayıcı olduğunu düşünüyorum.
İlk önce, sentetik bir veri seti verin Xt
, PCA'yı uygulayın (tipik olarak PC'leri bir kovaryans matrisi ile ilgili tanımlamak için numuneleri ortalarsınız:
#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)
Sonuçlarda veya prcomp
PC'lerin ( res$x
), res$sdev
her bir bilgisayarın büyüklüğü ve yükler ( res$rotation
) hakkında bilgi veren özdeğerlerini ( ) görebilirsiniz.
res$sdev
length(res$sdev)
res$rotation
dim(res$rotation)
res$x
dim(res$x)
Özdeğerleri karelerek, her bir PC tarafından açıklanan varyansı elde edersiniz:
plot(cumsum(res$sdev^2/sum(res$sdev^2))) #cumulative explained variance
Son olarak, yalnızca önde gelen (önemli) bilgisayarları kullanarak verilerinizin kesilmiş bir sürümünü oluşturabilirsiniz:
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)
Küçük ölçek özellikleri filtrelenmiş olarak, sonucun biraz daha yumuşak bir veri matrisi olduğunu görebilirsiniz:
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()
Ve burada prcomp işlevinin dışında yapabileceğiniz çok basit bir yaklaşım var:
#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
Şimdi, hangi bilgisayarları tutacağınıza karar vermek ayrı bir soru - bir süre önce ilgilendiğim bir soru . Umarım yardımcı olur.