Ich werde Ihrer Frage eine visuellere Antwort hinzufügen, indem ich einen Nullmodellvergleich verwende. Die Prozedur mischt die Daten in jeder Spalte nach dem Zufallsprinzip, um die Gesamtvarianz beizubehalten, während die Kovarianz zwischen Variablen (Spalten) verloren geht. Dies wird mehrmals durchgeführt und die resultierende Verteilung der Singularwerte in der randomisierten Matrix wird mit den Originalwerten verglichen.
Ich benutze prcomp
statt svd
für die Matrixzerlegung, aber die Ergebnisse sind ähnlich:
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
Der Nullmodellvergleich wird in der folgenden zentrierten Matrix durchgeführt:
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)
Das Folgende ist ein Boxplot der permutierten Matrix, wobei das 95% -Quantil jedes Singularwerts als durchgezogene Linie dargestellt ist. Die ursprünglichen PCA-Werte m
sind die Punkte. alle liegen unterhalb der 95% -Linie - daher ist ihre Amplitude nicht von zufälligem Rauschen zu unterscheiden.
Dieselbe Prozedur kann mit der nicht zentrierten Version von m
mit demselben Ergebnis durchgeführt werden - Keine signifikanten singulären Werte:
# 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)
Schauen wir uns zum Vergleich einen Datensatz mit einem nicht zufälligen Datensatz an: 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)
Hier ist der 1. Singularwert signifikant und erklärt über 92% der Gesamtvarianz:
P <- prcomp(m, center = TRUE)
P$sdev^2 / sum(P$sdev^2)
# [1] 0.924618723 0.053066483 0.017102610 0.005212184