2011-12-19 14 views
10

Mentre si utilizza la funzione princomp() in R, si verifica il seguente errore: "covariance matrix is not non-negative definite".Come usare la funzione princomp() in R quando la matrice di covarianza ha zero?

Penso, questo è dovuto al fatto che alcuni valori sono pari a zero (in realtà vicino a zero, ma diventa zero durante l'arrotondamento) nella matrice di covarianza.

Esiste un modo per aggirare il PCA quando la matrice di covarianza contiene zeri?

[FYI: l'ottenimento della matrice di covarianza è un passaggio intermedio all'interno della chiamata princomp(). Il file di dati per riprodurre questo errore può essere scaricato da qui - http://tinyurl.com/6rtxrc3]

+0

L'aggiunta di un input di esempio per rendere riproducibile il problema è utile per i risponditori. –

+1

Se guardi a 'stats ::: princomp.default' vedrai che l'errore si verifica quando hai autovalori negativi nella matrice di covarianza. –

+0

@ Richie Cotton: Vorrei poter fornire. I miei dati sono enormi (10K x 10K) e non ho capito la parte che sta causando l'errore. Sarò felice di sapere se c'è un modo in cui posso estrarre una parte preoccupante dei dati e postarla qui! – 384X21

risposta

9

La prima strategia potrebbe essere la riduzione dell'argomento di tolleranza. Mi sembra che princomp non trasmetta un argomento di tolleranza ma che prcomp accetta un argomento 'tol'. Se non è efficace, questo dovrebbe individuare vettori che hanno quasi zero covarianza:

nr0=0.001 
which(abs(cov(M)) < nr0, arr.ind=TRUE) 

E questo sarebbe identificare i vettori con autovalori negativi:

which(eigen(M)$values < 0) 

Utilizzando l'esempio h9 sull'aiuto (QR) pagina:

> which(abs(cov(h9)) < .001, arr.ind=TRUE) 
     row col 
[1,] 9 4 
[2,] 8 5 
[3,] 9 5 
[4,] 7 6 
[5,] 8 6 
[6,] 9 6 
[7,] 6 7 
[8,] 7 7 
[9,] 8 7 
[10,] 9 7 
[11,] 5 8 
[12,] 6 8 
[13,] 7 8 
[14,] 8 8 
[15,] 9 8 
[16,] 4 9 
[17,] 5 9 
[18,] 6 9 
[19,] 7 9 
[20,] 8 9 
[21,] 9 9 
> qr(h9[-9,-9])$rank 
[1] 7     # rank deficient, at least at the default tolerance 
> qr(h9[-(8:9),-(8:9)])$ take out only the vector with the most dependencies 
[1] 6     #Still rank deficient 
> qr(h9[-(7:9),-(7:9)])$rank 
[1] 6 

altro approccio potrebbe essere quello di utilizzare la funzione alias:

alias(lm(rnorm(NROW(dfrm)) ~ dfrm)) 
+0

Bello. Non avevo mai incontrato "alias" prima. –

Problemi correlati