2012-09-06 8 views
6

Próbuję sprawdzić, czy moja macierz jest pojedyncza przy użyciu podejścia wartości własnych (tj. Jeśli jedna z wartości własnych wynosi zero, to macierz jest pojedyncza). Oto kod:przy użyciu wartości własnych do testowania osobliwości: identyfikacja kolinearnych kolumn

z <- matrix(c(-3,2,1,4,-9,6,3,12,5,5,9,4),nrow=4,ncol=3) 
eigen(t(z)%*%z)$values 

znam wartości własne są sortowane w kolejności malejącej. Czy ktoś może mi powiedzieć, czy istnieje sposób, aby dowiedzieć się, jaka wartość własna jest związana z jaką kolumną w macierzy? Muszę usunąć kolinearne kolumny.

Może to być oczywiste w powyższym przykładzie, ale jest to tylko przykład, który ma zaoszczędzić czas potrzebny na utworzenie nowej macierzy.

+1

'eigen' nie działa non-macierzy kwadratowej –

+0

Trzeba kwadratową macierz do obliczania wartości własnych ... – James

+0

myślę chodziło? 'z <- macierz (c (-3,2,1,4, -9,6,3,12,5,5,9,4), nrow = 4, ncol = 4) eigen (z) $ wartości ' –

Odpowiedz

7

Przykład:

z <- matrix(c(-3,2,1,4,-9,6,3,12,5,5,9,4),nrow=4,ncol=3) 
m <- crossprod(z) ## slightly more efficient than t(z) %*% z 

To powie Ci, że trzeci wektor własny odpowiada współliniowych kombinacjach:

ee <- eigen(m) 
(evals <- zapsmall(ee$values)) 
## [1] 322.7585 124.2415 0.0000 

teraz zbadać odpowiednie wektory własne, które są wymienione jako kolumny odpowiadającej ich wartości własnych:

(evecs <- zapsmall(ee$vectors)) 
    ## [1,] -0.2975496 -0.1070713 0.9486833 
    ## [2,] -0.8926487 -0.3212138 -0.3162278 
    ## [3,] -0.3385891 0.9409343 0.0000000 

Trzecia wartość własna to zero; dwa pierwsze elementy trzeciego wektora własnego (evecs[,3]) są niezerowe, co oznacza, że ​​kolumny 1 i 2 są współliniowe.

Oto sposób zautomatyzować ten test:

testcols <- function(ee) { 
     ## split eigenvector matrix into a list, by columns 
     evecs <- split(zapsmall(ee$vectors),col(ee$vectors)) 
     ## for non-zero eigenvalues, list non-zero evec components 
     mapply(function(val,vec) { 
      if (val!=0) NULL else which(vec!=0) 
     },zapsmall(ee$values),evecs) 
    } 

testcols(ee) 
## [[1]] 
## NULL 
## [[2]] 
## NULL 
## [[3]] 
## [1] 1 2 
+0

@BenBolker, więc jakie kolumny w z są współrzędne? lub mają evals = 0 –

+2

kolumna nie ma wartości własnej zero, z definicji: jest to * liniowa kombinacja * kolumn, które są współliniowe - kolumny 1 i 2 w twoim przykładzie. –

+0

Dla zainteresowanych, oto link do postu SO, który zrobiłem, wdrażając zasadniczo tę samą metodę (specjalnie do kontekstu analizy regresji), ale w języku Julia i dając nieco więcej matematycznego tła: http: // stackoverflow. com/questions/39082724/perfect-or-near-multicollinearity-in-julia/39082831 # 39082831 –

2

Można użyć tmp <- svd(z) zrobić SVD. Wartości własne są następnie zapisywane w tmp$d jako diagonalna macierz wartości własnych. Działa to również z macierzą inną niż kwadrat.

> diag(tmp$d) 
     [,1]  [,2]   [,3] 
[1,] 17.96548 0.00000 0.000000e+00 
[2,] 0.00000 11.14637 0.000000e+00 
[3,] 0.00000 0.00000 8.787239e-16