Aggiungerò una risposta più visiva alla tua domanda, attraverso l'uso di un confronto del modello nullo. La procedura mescola casualmente i dati in ciascuna colonna per preservare la varianza complessiva mentre si perde la covarianza tra variabili (colonne). Questo viene eseguito più volte e la risultante distribuzione di valori singolari nella matrice randomizzata viene confrontata con i valori originali.
Uso prcompinvece svdla decomposizione della matrice, ma i risultati sono simili:
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
Il confronto del modello null viene eseguito sulla matrice centrata di seguito:
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)
Di seguito è riportato un diagramma a scatole della matrice permutata con il 95% quantile di ciascun valore singolare mostrato come linea continua. I valori originali di PCA di msono i punti. tutti i quali si trovano al di sotto della linea del 95% - Quindi la loro ampiezza è indistinguibile dal rumore casuale.

La stessa procedura può essere eseguita sulla versione non centrata mcon lo stesso risultato - Nessun valore singolare significativo:
# 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)

Per un confronto, diamo un'occhiata a un set di dati con un set di dati non casuale: 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)

Qui, il 1o valore singolare è significativo e spiega oltre il 92% della varianza totale:
P <- prcomp(m, center = TRUE)
P$sdev^2 / sum(P$sdev^2)
# [1] 0.924618723 0.053066483 0.017102610 0.005212184