Come posso generare dati con una matrice di correlazione prespecificata?


19

Sto cercando di generare una sequenza casuale correlata con media = , varianza = , coefficiente di correlazione = . Nel codice seguente, utilizzo & come deviazioni standard e & come mezzo.1 0,8010.8s1s2m1m2

p = 0.8 
u = randn(1, n)
v = randn(1, n)
x = s1 * u + m1
y = s2 * (p * u + sqrt(1 - p^2) * v) + m2

Questo mi dà la corretta corrcoef()di 0,8 tra xe y. La mia domanda è come posso generare una serie significa se voglio zche sia anche correlato con y(con la stessa correlazione ), ma non con . C'è una formula particolare che devo conoscere? Ne ho trovato uno ma non sono riuscito a capirlo.r=0.8x


Risposte:


21

Sembra che tu stia chiedendo come generare dati con una particolare matrice di correlazione.

Un fatto utile è che se si dispone di un vettore casuale con la matrice di covarianza Σ , allora il vettore casuale A x ha medio A E ( x ) e la matrice di covarianza Ω = A Σ A T . Quindi, se inizi con dati con zero medio, la moltiplicazione per A non lo cambierà, quindi il tuo primo requisito sarà facilmente soddisfatto. xΣAxAE(x)Ω=AΣATA

Diciamo che si inizia con i dati non correlati (media zero) (cioè la matrice di covarianza è diagonale) - dal momento che stiamo parlando della matrice di correlazione, facciamo solo prendere . Puoi trasformarlo in dati con una data matrice di covarianza scegliendo A per essere la radice quadrata cholesky di Ω - quindi A x avrebbe la matrice di covarianza desiderata Ω .Σ=IAΩAxΩ

Nel tuo esempio, sembra che desideri qualcosa del genere:

Ω=(1.80.81.80.81)

Sfortunatamente quella matrice non è definita positiva, quindi non può essere una matrice di covarianza - puoi verificarla vedendo che il determinante è negativo. Forse, invece

Ω=(1.8.3.81.8.3.81)    or   Ω=(12/302/312/302/31)

basterebbe. Non sono sicuro di come calcolare la radice quadrata cholesky in matlab (che sembra essere quello che stai usando) ma in Rte puoi usare la chol()funzione.

In questo esempio, per i due elencati sopra, i multipli di matrice appropriati (rispettivamente) sarebberoΩ

A=(100.8.60.3.933.1972)    or   A=(1002/3.745300.8944.4472)

Il Rcodice usato per arrivare a questo era:

x = matrix(0,3,3)
x[1,]=c(1,.8,.3)
x[2,]=c(.8,1,.8)
x[3,]=c(.3,.8,1)
t(chol(x))

     [,1]      [,2]      [,3]
[1,]  1.0 0.0000000 0.0000000
[2,]  0.8 0.6000000 0.0000000
[3,]  0.3 0.9333333 0.1972027

x[1,]=c(1,2/3,0)
x[2,]=c(2/3,1,2/3)
x[3,]=c(0,2/3,1)
t(chol(x))

      [,1]      [,2]      [,3]
[1,] 1.0000000 0.0000000 0.0000000
[2,] 0.6666667 0.7453560 0.0000000
[3,] 0.0000000 0.8944272 0.4472136

1
La funzione di MATLAB è anche chiamato chol. Si noti che questo può essere abbastanza numericamente instabile se è quasi singolare. In tal caso, l'uso della radice quadrata simmetrica ottenuta, ad esempio tramite SVD, è spesso una scelta migliore in termini di stabilità numerica. :)Ω
cardinale il

1
Certo che è giusto @cardinale - molte cose teoricamente giustificate vanno male quando stai cercando di fare le cose numericamente con matrici quasi singolari. Stavo (convenientemente) immaginando la situazione in cui la matrice di correlazione del bersaglio non era nel regno in cui questo era un problema. È bello che tu l'abbia sottolineato - grazie (e grazie per la modifica alla mia altra risposta)
Macro

1
Il motivo principale per cui stavo pensando a questo era dovuto al tuo occhio acuto nel riconoscere che il primo suggerimento del PO non era nemmeno definito positivamente. E, si spera, la modifica all'altra domanda non era troppo zelante; Mi piacciono entrambe queste risposte.
cardinale il

7

Se stai usando R, puoi anche usare la funzione mvrnorm dal pacchetto MASS, supponendo che tu voglia variabili normalmente distribuite. L'implementazione è simile alla descrizione di Macro sopra, ma utilizza gli autovettori della matrice di correlazione anziché la scomposizione e il ridimensionamento cholesky con una scomposizione di valore singolare (se l'opzione empirica è impostata su true).

XΣγλΣ

X=γλXT

ΣX

Si noti che la matrice di correlazione deve essere definita positiva, ma sarà utile convertirla con la funzione nearPD dal pacchetto Matrix in R.


1

ΣyxΣx=IΣyΛV

Σy=VΛVT=(VΛ)(ΛTVT)=AAT

y=Ax

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.