Saya akan menambahkan jawaban yang lebih visual untuk pertanyaan Anda, melalui penggunaan perbandingan model nol. Prosedur secara acak mengocok data di setiap kolom untuk mempertahankan varians keseluruhan sementara kovarians antara variabel (kolom) hilang. Ini dilakukan beberapa kali dan distribusi nilai singular yang dihasilkan dalam matriks acak dibandingkan dengan nilai asli.
Saya menggunakan prcomp
alih-alih svd
untuk dekomposisi matriks, tetapi hasilnya serupa:
set.seed(1)
m <- matrix(runif(10000,min=0,max=25), nrow=100,ncol=100)
S <- svd(scale(m, center = TRUE, scale=FALSE))
P <- prcomp(m, center = TRUE, scale=FALSE)
plot(S$d, P$sdev) # linearly related
Perbandingan model nol dilakukan pada matriks berpusat di bawah ini:
library(sinkr) # https://github.com/marchtaylor/sinkr
# centred data
Pnull <- prcompNull(m, center = TRUE, scale=FALSE, nperm = 100)
Pnull$n.sig
boxplot(Pnull$Lambda[,1:20], ylim=range(Pnull$Lambda[,1:20], Pnull$Lambda.orig[1:20]), outline=FALSE, col=8, border="grey50", log="y", main=paste("m (center=FALSE); n sig. =", Pnull$n.sig))
lines(apply(Pnull$Lambda, 2, FUN=quantile, probs=0.95))
points(Pnull$Lambda.orig[1:20], pch=16)
Berikut ini adalah boxplot dari matriks permutasi dengan kuantil 95% dari setiap nilai singular yang ditunjukkan sebagai garis padat. Nilai asli PCA m
adalah titik. yang semuanya terletak di bawah garis 95% - Dengan demikian amplitudo mereka tidak dapat dibedakan dari derau acak.
Prosedur yang sama dapat dilakukan pada versi yang tidak terpusat m
dengan hasil yang sama - Tidak ada nilai tunggal yang signifikan:
# centred data
Pnull <- prcompNull(m, center = FALSE, scale=FALSE, nperm = 100)
Pnull$n.sig
boxplot(Pnull$Lambda[,1:20], ylim=range(Pnull$Lambda[,1:20], Pnull$Lambda.orig[1:20]), outline=FALSE, col=8, border="grey50", log="y", main=paste("m (center=TRUE); n sig. =", Pnull$n.sig))
lines(apply(Pnull$Lambda, 2, FUN=quantile, probs=0.95))
points(Pnull$Lambda.orig[1:20], pch=16)
Sebagai perbandingan, mari kita lihat dataset dengan dataset non-acak: iris
# iris dataset example
m <- iris[,1:4]
Pnull <- prcompNull(m, center = TRUE, scale=FALSE, nperm = 100)
Pnull$n.sig
boxplot(Pnull$Lambda, ylim=range(Pnull$Lambda, Pnull$Lambda.orig), outline=FALSE, col=8, border="grey50", log="y", main=paste("m (center=FALSE); n sig. =", Pnull$n.sig))
lines(apply(Pnull$Lambda, 2, FUN=quantile, probs=0.95))
points(Pnull$Lambda.orig[1:20], pch=16)
Di sini, nilai tunggal pertama adalah signifikan, dan menjelaskan lebih dari 92% dari total varians:
P <- prcomp(m, center = TRUE)
P$sdev^2 / sum(P$sdev^2)
# [1] 0.924618723 0.053066483 0.017102610 0.005212184