Tôi tin rằng những gì bạn đang nhận được trong câu hỏi của bạn liên quan đến việc cắt dữ liệu bằng cách sử dụng số lượng nhỏ hơn các thành phần chính (PC). Đối với các hoạt động như vậy, tôi nghĩ rằng chức năngprcomp
này có tính minh họa cao hơn ở chỗ dễ hình dung hơn về phép nhân ma trận được sử dụng trong tái thiết.
Trước tiên, đưa ra một tập dữ liệu tổng hợp Xt
, bạn thực hiện PCA (thông thường bạn sẽ căn giữa các mẫu để mô tả PC liên quan đến ma trận hiệp phương sai:
#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)
Trong kết quả hoặc prcomp
, bạn có thể thấy PC ( res$x
), giá trị riêng ( res$sdev
) cung cấp thông tin về cường độ của từng PC và tải ( res$rotation
).
res$sdev
length(res$sdev)
res$rotation
dim(res$rotation)
res$x
dim(res$x)
Bằng cách bình phương các giá trị riêng, bạn có được phương sai được giải thích bởi mỗi PC:
plot(cumsum(res$sdev^2/sum(res$sdev^2))) #cumulative explained variance
Cuối cùng, bạn có thể tạo một phiên bản rút gọn của dữ liệu của mình bằng cách chỉ sử dụng các PC hàng đầu (quan trọng):
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)
Bạn có thể thấy rằng kết quả là một ma trận dữ liệu mượt mà hơn một chút, với các tính năng quy mô nhỏ được lọc ra:
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()
Và đây là một cách tiếp cận rất cơ bản mà bạn có thể thực hiện ngoài chức năng 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
Bây giờ, quyết định giữ lại PC nào là một câu hỏi riêng biệt - một câu hỏi mà tôi đã quan tâm một thời gian trước . Mong rằng sẽ giúp.