Come creare una matrice di covarianza arbitraria


21

Ad esempio, in R, la MASS::mvrnorm()funzione è utile per generare dati per dimostrare varie cose nelle statistiche. Prende un Sigmaargomento obbligatorio che è una matrice simmetrica che specifica la matrice di covarianza delle variabili. Come potrei creare una matrice simmetrica con voci arbitrarie?n×n


3
Penso che questa domanda trarrebbe beneficio dall'essere modificata per concentrarsi su "come posso creare una matrice di covarianza arbitraria" e meno sull'aspetto della codifica. C'è sicuramente un problema statistico alla base qui, come dimostrato dalla risposta.
Silverfish

Risposte:


22

Crea una matrice A con valori arbitrarin×nA

e quindi usa Σ=ATA come matrice di covarianza.

Per esempio

n <- 4  
A <- matrix(runif(n^2)*2-1, ncol=n) 
Sigma <- t(A) %*% A

Analogamente, Sigma <- A + t(A).
rsl

6
@MoazzemHossen: il tuo suggerimento produrrà una matrice simmetrica, ma potrebbe non essere sempre semidefinito positivo (ad esempio, il tuo suggerimento potrebbe produrre una matrice con autovalori negativi) e quindi potrebbe non essere adatto come matrice di covarianza
Henry,

Sì, ho notato che R restituisce un errore nel caso in cui il mio modo suggerito abbia prodotto una matrice inadatta.
rsl

4
Si noti che se si preferisce una matrice di correlazione per una migliore interpretabilità, esiste la funzione ? Cov2cor , che può essere applicata successivamente.
gung - Ripristina Monica

1
@ B11b: hai bisogno che la tua matrice di covarianza sia semi-definita positiva. Ciò metterebbe alcuni limiti ai valori di covarianza, non del tutto ovvi quando n>2
Henry,

24

Mi piace avere il controllo sugli oggetti che creo, anche quando potrebbero essere arbitrari.

Si consideri, poi, che tutti i possibili covarianza matrici Σ può essere espresso nella forman×nΣ

Σ=P Diagonal(σ1,σ2,,σn) P

dove è una matrice ortogonale e σ 1σ 2σ n0 .Pσ1σ2σn0

Geograficamente questo descrive una struttura di covarianza con una gamma di componenti principali di dimensioni . Questi componenti puntano nelle direzioni delle righe di P . Vedere le figure in Analisi delle componenti principali, autovettori e autovalori per esempi con n = 3 . Impostando σ i si imposteranno le magnitudini delle covarianze e le loro dimensioni relative, determinando così qualsiasi forma ellissoidale desiderata. Le file di P orientano gli assi della forma come preferisci.σiPn=3σiP

Un vantaggio algebrico e di calcolo di questo approccio è che quando , Σ viene prontamente invertito (operazione che è un'operazione comune sulle matrici di covarianza):σn>0Σ

Σ1=P Diagonal(1/σ1,1/σ2,,1/σn) P.

Non ti interessano le direzioni, ma solo le gamme di dimensioni della ? Va bene: puoi facilmente generare una matrice ortogonale casuale. Avvolgi n 2 iid i valori normali standard in una matrice quadrata e poi ortogonali. Funzionerà quasi sicuramente (a condizione che n non sia enorme). La decomposizione QR lo farà, come in questo codiceσin2n

n <- 5
p <- qr.Q(qr(matrix(rnorm(n^2), n)))

Questo funziona perché la distribuzione multinormale a variabili così generata è "ellittica": è invariante sotto tutte le rotazioni e le riflessioni (attraverso l'origine). Pertanto, tutte le matrici ortogonali vengono generate in modo uniforme, come spiegato in Come generare punti distribuiti uniformemente sulla superficie della sfera dell'unità 3-d? .n

Un modo rapido per ottenere da P e σ i , dopo averli specificati o creati, utilizza e sfrutta il riutilizzo di array in operazioni aritmetiche, come in questo esempio con σ = ( σ 1 , , σ 5 ) = ( 5 , 4 , 3 , 2 , 1 ) :ΣPσicrossprodRσ=(σ1,,σ5)=(5,4,3,2,1)

Sigma <- crossprod(p, p*(5:1))

Come controllo, la decomposizione del valore singolare dovrebbe restituire sia che P . Puoi ispezionarlo con il comandoσP

svd(Sigma)

SigmaNaturalmente, l' inverso si ottiene semplicemente cambiando la moltiplicazione di in una divisione:σ

Tau <- crossprod(p, p/(5:1))

Puoi verificarlo visualizzando zapsmall(Sigma %*% Tau), che dovrebbe essere la matrice di identità . Un inverso generalizzato (essenziale per i calcoli di regressione) si ottiene sostituendo qualsiasi σ i0 con 1 / σ i , esattamente come sopra, ma mantenendo gli zeri tra gli σ i così come erano.n×nσi01/σiσi


Potrebbe aiutare a dimostrare come usare le file di per orientare gli assi come preferiscono. P
gung - Ripristina Monica

1
Vale la pena ricordare che i singoli valori svd(Sigma)verranno riordinati, il che mi ha confuso per un minuto.
FrankD,

1

È possibile simulare matrici definite positive casuali dalla distribuzione di Wishart utilizzando la funzione "rWishart" dal pacchetto "stats" ampiamente utilizzato.

n <- 4
rWishart(1,n,diag(n))

1

Esiste un pacchetto specifico per questo, clusterGeneration(scritto tra l'altro da Harry Joe, un grande nome in quel campo).

Esistono due funzioni principali:

  • genPositiveDefMat generare una matrice di covarianza, 4 metodi diversi
  • rcorrmatrix : genera una matrice di correlazione

Esempio rapido:

library(clusterGeneration)
#> Loading required package: MASS
genPositiveDefMat("unifcorrmat",dim=3)
#> $egvalues
#> [1] 15.408962  5.673916  1.228842
#> 
#> $Sigma
#>          [,1]     [,2]     [,3]
#> [1,] 6.714871 1.643449 6.530493
#> [2,] 1.643449 6.568033 2.312455
#> [3,] 6.530493 2.312455 9.028815
genPositiveDefMat("eigen",dim=3)
#> $egvalues
#> [1] 8.409136 4.076442 2.256715
#> 
#> $Sigma
#>            [,1]       [,2]      [,3]
#> [1,]  2.3217300 -0.1467812 0.5220522
#> [2,] -0.1467812  4.1126757 0.5049819
#> [3,]  0.5220522  0.5049819 8.3078880

Creato il 27-10-2019 dal pacchetto reprex (v0.3.0)

Infine, nota che un approccio alternativo è fare un primo tentativo da zero, quindi usare Matrix::nearPD()per rendere la tua matrice positiva.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.