2011-12-19 23 views
10

Al usar la función princomp() en R, se encuentra el siguiente error: "covariance matrix is not non-negative definite".Cómo usar la función de princomp() en R cuando la matriz de covarianza tiene cero?

Creo que esto se debe a que algunos valores son cero (en realidad cerca de cero, pero se vuelve cero durante el redondeo) en la matriz de covarianza.

¿Existe un problema para proceder con PCA cuando la matriz de covarianza contiene ceros?

[FYI: la obtención de la matriz de covarianza es un paso intermedio dentro de la llamada princomp(). El archivo de datos para reproducir este error se puede descargar desde aquí - http://tinyurl.com/6rtxrc3]

+0

Agregar una entrada de muestra para que el problema sea reproducible es útil para los respondedores. –

+1

Si observa 'stats ::: princomp.default' verá que el error ocurre cuando tiene valores propios negativos en la matriz de covarianza. –

+0

@ Richie Cotton: desearía poder brindarle. Mis datos son enormes (10K x 10K) y no he descubierto la parte que está causando el error. Estaré encantado de saber si hay una forma en que pueda extraer una parte problemática de los datos y publicarla aquí. – 384X21

Respuesta

9

La primera estrategia podría ser disminuir el argumento de tolerancia. Me parece que princomp no pasará un argumento de tolerancia pero que prcomp acepta un argumento 'tol'. Si no es efectivo, este debe identificar vectores que tienen casi cero covarianza:

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

Y esto sería identificar vectores con valores propios negativos:

which(eigen(M)$values < 0) 

Usando el ejemplo h9 en la página de ayuda (QR):

> 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 

Otro enfoque podría ser utilizar la función alias:

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

Agradable. No me había encontrado con 'alias' antes. –

Cuestiones relacionadas