¿Cómo generar números aleatorios correlacionados (medias, variaciones y grado de correlación dados)?

53

Lo siento si esto parece demasiado básico, pero supongo que solo estoy buscando confirmar la comprensión aquí. Tengo la sensación de que tendría que hacer esto en dos pasos, y he comenzado a tratar de asimilar las matrices de correlación, pero está empezando a parecer realmente complicado. Estoy buscando una explicación concisa (idealmente con sugerencias para una solución de pseudocódigo) de una forma buena, idealmente rápida, de generar números aleatorios correlacionados.

Dadas dos variables pseudoaleatorias de altura y peso con medias y variaciones conocidas, y una correlación dada, creo que básicamente estoy tratando de entender cómo debería ser este segundo paso:

   height = gaussianPdf(height.mean, height.variance)
   weight = gaussianPdf(correlated_mean(height.mean, correlation_coefficient), 
                        correlated_variance(height.variance, 
                        correlation_coefficient))
  • ¿Cómo calculo la media y la varianza correlacionadas? Pero quiero confirmar que ese es realmente el problema relevante aquí.
  • ¿Necesito recurrir a la manipulación matricial? ¿O tengo algo más muy mal en mi enfoque básico de este problema?
Joseph Weissman
fuente
1
No estoy seguro de que te entiendo correctamente, pero no tienes que calcular "media y varianza correlacionadas". Si está asumiendo que las variables son bivariadas normales, debería ser suficiente para especificar las medias y variaciones individuales y la correlación. ¿Hay algún software en particular que quieras usar para esto?
mark999

Respuestas:

44

Para responder a su pregunta sobre "una forma buena, idealmente rápida, de generar números aleatorios correlacionados": Dada una matriz varianza-covarianza deseada que es, por definición, positiva definida, la descomposición de Cholesky es: C = L L T ; L siendo matriz triangular inferior.CCLLTL

Si ahora usa esta matriz para proyectar un vector variable aleatorio no correlacionado X , la proyección resultante Y = L X será la de las variables aleatorias correlacionadas.LXY=LX

Puede encontrar una explicación concisa de por qué sucede esto aquí .

usεr11852 dice Reinstate Monic
fuente
¡Gracias! Esto fue de gran ayuda. Creo que al menos tengo una mejor idea de lo que necesito mirar a continuación.
Joseph Weissman
77
¿Este método se aplica solo a las distribuciones gaussianas (como se especifica en la pregunta), o puede usarse para generar variables correlacionadas que siguen a otras distribuciones? Si no es así, ¿conoce algún método que pueda usarse en ese caso?
user000001
1
@ Michael: Sí. Dicho esto, dado que es una matriz de covarianza válida, la descomposición de Cholesky es la forma más rápida. También puede obtener la matriz X de raíz cuadrada (simétrica) de C usando SVD (entonces C = X X = X X T , donde X = U S 0.5 V T de C = U S V T ) pero eso sería más costoso también. CXCC=XX=XXTX=US0.5VTC=USVT
usεr11852 dice Reinstate Monic el
1
@ Michael: Por supuesto. Su covarianza será (aproximadamente) la misma, no los números en sí.
usεr11852 dice Reinstate Monic el
1
@Sid: cualquier distribución continua no admitida en toda la línea real fallará inmediatamente. Por ejemplo, si usamos un uniforme no podemos garantizar que los "números correlacionados" estarán en [ 0 , 1 ] ; de manera similar para un Poisson terminaremos con números no discretos. Además, cualquier distribución donde la suma de las distribuciones no sea la misma distribución (por ejemplo, la suma de la distribución t no da como resultado t- distribuciones) también fallará. En todos los casos mencionados, los números producidos se correlacionarán de acuerdo con la CU[0,1][0,1]ttCpero no se corresponderán con la distribución que comenzamos.
usεr11852 dice Reinstate Monic
36

+1 a @ user11852 y @ jem77bfp, estas son buenas respuestas. Permítanme abordar esto desde una perspectiva diferente, no porque piense que es necesariamente mejor en la práctica , sino porque creo que es instructivo. Aquí hay algunos hechos relevantes que ya conocemos:

  1. es la pendiente de la línea de regresión cuando X e Y estánestandarizados, es decir, N ( 0 , 1 ) , rXYN(0,1)
  2. r2YX



    (también, de las reglas para las variaciones ):


  3. Var[aX]=a2Var[X]

  4. Var[X+ε]=Var[X]+Var[ε]

rρXN(0,1)aveYN(0,a2+ve)a2+ve=1|a| 1a=rra1r2xieiveyi

Si desea hacer esto en R, el siguiente código podría funcionar para usted:

correlatedValue = function(x, r){
  r2 = r**2
  ve = 1-r2
  SD = sqrt(ve)
  e  = rnorm(length(x), mean=0, sd=SD)
  y  = r*x + e
  return(y)
}

set.seed(5)
x = rnorm(10000)
y = correlatedValue(x=x, r=.5)

cor(x,y)
[1] 0.4945964

0

Nuevamente, esto, en su forma más simple, solo le permite generar un par de variables correlacionadas (esto podría ampliarse, pero se vuelve feo rápido), y ciertamente no es la forma más conveniente de hacer el trabajo. En R, desearía usar ? Mvrnorm en el paquete MASS , tanto porque es más fácil como porque puede generar muchas variables con una matriz de correlación de población dada. No obstante, creo que vale la pena haber recorrido este proceso para ver cómo se desarrollan algunos principios básicos de una manera simple.

gung - Restablece a Monica
fuente
Este enfoque esencialmente regresivo es particularmente agradable al permitir que uno genere una Y aleatoria correlacionada con cualquier número de "predictores" X existentes . ¿Estoy en lo cierto?
ttnphns
Depende exactamente de qué patrón de correlaciones entre las variables que desee, @ttnphns. Puede repetir esto uno tras otro, pero sería tedioso. Para crear muchas variables correlacionadas con un patrón dado, es mejor usar la descomposición de Cholesky.
gung - Restablece a Monica
Gung, ¿sabes cómo usar Cholesky para generar una Y correlacionada (aproximadamente, como en tu método) de acuerdo con un vector de correlaciones con varias X existentes (no simuladas)?
ttnphns
@ttnphns, ¿desea generar una sola Y con una correlación de población dada con un conjunto de X, no un conjunto de variables p que todas tengan correlaciones de población previamente especificadas? Una manera simple sería escribir una ecuación de regresión para generar un solo sombrero Y a partir de sus X, luego usar el método anterior para generar Y como correlato de su sombrero Y. Puede hacer una nueva pregunta al respecto, si lo desea.
gung - Reinstale a Monica
1
Esto es lo que quise decir en mi comentario inicial: este método sería una extensión directa de lo que hablas en tu respuesta: esencialmente un método regresivo (Hat).
ttnphns
16

En general, esto no es algo simple de hacer, pero creo que hay paquetes para la generación de variables normales multivariadas (al menos en R, ver mvrnormen el MASSpaquete), donde simplemente ingresas una matriz de covarianza y un vector medio.

(X1,X2)F(x1,x2)Fx2

FX1(x1)=F(x1,x2)dx2.
FX11FX1ξ1[0,1]x^1=FX11(ξ)

F(x1,x2)x1=x^1

F(x2|X1=x^1)=F(x^1,x2)fX1(x^1),
fX1X1FX1(x1)=fX1(x1)

ξ2[0,1]ξ1F(x2|X1=x^1)x^2=(F(x2|X1=x^1))1(ξ)x^2F(x^2|X1=x^1)=ξ

Si no comprende el significado de conectar una variable uniforme en una función de distribución de probabilidad inversa, intente hacer un bosquejo del caso univariado y luego recuerde cuál es la interpretación geométrica de la función inversa.

jem77bfp
fuente
¡Idea inteligente! Tiene un atractivo intuitivo simple. Pero sí parece caro computacionalmente.
MichaelChirico
fX,Y(x,y)=fX(x)fY|X(y)
1

Si está listo para renunciar a la eficiencia, puede usar un alogoritmo desechable. Su ventaja es que permite cualquier tipo de distribución (no solo gaussiana).

{xi}i=1N{yi}i=1NC

cold=corr({xi},{yi})

n1n2:1n1,2N

xn1xn2

cnew=corr({xi},{yi})

|Ccnew|<|Ccold|

|Cc|<ϵ

xi

¡Buena suerte!

F. Jatpil
fuente
xicorr(xi,yi)
xi{xi}ycorr(xi,yi)corr({xi},{yi})=(1/N)Σi=1N(xix¯)(yyy¯)
{}corr({xi},{yi})