2011-12-19 10 views
10

Podczas korzystania z funkcji princomp() w R, napotkano następujący błąd: "covariance matrix is not non-negative definite".Jak korzystać z funkcji princomp() w R, gdy macierz kowariancji ma zero?

Myślę, że jest to spowodowane tym, że niektóre wartości są zerowe (faktycznie bliskie zeru, ale stają się zerami podczas zaokrąglania) w macierzy kowariancji.

Czy jest jakieś obejście, aby przystąpić do PCA, gdy macierz kowariancji zawiera zera?

[FYI: uzyskanie macierzy kowariancji jest etapem pośrednim w ramach wywołania princomp(). Plik danych do odtworzenia tego błędu można pobrać stąd - http://tinyurl.com/6rtxrc3]

+0

Dodanie przykładowego wejścia, aby problem mógł być odtwarzany, jest przydatny dla osób, które odpowiedziały. –

+1

Jeśli spojrzysz na 'stats ::: princomp.default' zobaczysz, że błąd występuje, gdy masz ujemne wartości własne w macierzy kowariancji. –

+0

@ Richie Cotton: Chciałbym zapewnić. Moje dane są ogromne (10K x 10K) i nie znalazłem części powodującej błąd. Z przyjemnością dowiem się, czy istnieje sposób, w jaki mogę wyodrębnić niepokojące dane i opublikować je tutaj! – 384X21

Odpowiedz

9

Pierwsza strategia może polegać na zmniejszeniu argumentu tolerancji. Wygląda mi na to, że princomp nie przekazuje argumentu tolerancji, ale to prcomp przyjmuje argument "tol". Jeśli nie działa, to powinien identyfikować wektory, które mają prawie zerową kowariancji:

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

I to by zidentyfikować wektory z ujemnych wartości własnych:

which(eigen(M)$values < 0) 

Używanie H9 przykład na pomoc (QR) Strona:

> 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 

Innym rozwiązaniem może być wykorzystanie alias funkcję:

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

Nice. Nie natknąłem się wcześniej na "alias". –