[En preguntas recientes, estaba buscando generar vectores aleatorios en R , y quería compartir esa "investigación" como un Q&A independiente sobre un punto específico.]
La generación de datos aleatorios con correlación se puede hacer usando la descomposición de Cholesky de la matriz de correlación aquí , como se refleja en publicaciones anteriores aquí y aquí .
La pregunta que quiero abordar es cómo utilizar la distribución uniforme para generar números aleatorios correlacionados de diferentes distribuciones marginales en R .
r
correlation
sampling
random-variable
random-generation
Antoni Parellada
fuente
fuente
Respuestas:
Ya que la pregunta es
y no solo las variaciones aleatorias normales, la respuesta anterior no produce simulaciones con la correlación prevista para un par arbitrario de distribuciones marginales en .R
La razón es que, para la mayoría de los cdfs y , cuando donde denota el cdf normal estándar.solX solY
A saber, aquí hay un contraejemplo con un Exp (1) y un Gamma (.2,1) como mi par de distribuciones marginales en .R
Otro contraejemplo obvio es cuando es el cdf de Cauchy, en cuyo caso la correlación no está definida.solX
Para dar una imagen más amplia, aquí hay un código R donde y son arbitrarios:solX solY
Jugar con diferentes cdfs me llevó a destacar este caso especial de una para y una distribución log-Normal para :χ23 solX solY
que muestra qué tan lejos de la diagonal puede estar la correlación.
fuente
Escribí el
correlate
paquete. La gente dijo que es prometedor (digno de una publicación en el Journal of Statistical Software), pero nunca escribí el artículo porque elegí no seguir una carrera académica.Creo que el
correlate
paquete no mantenido todavía está en CRAN.Cuando lo instales, puedes hacer lo siguiente:
El resultado es que los nuevos datos tendrán una correlación de 0.5, sin cambiar las distribuciones univariadas de
a
yb
(los mismos valores están allí, simplemente se mueven hasta que se alcanza la correlación multivariada 0.5.Contestaré preguntas aquí, perdón por la falta de documentación.
fuente
Genere dos muestras de datos correlacionados a partir de una distribución aleatoria normal estándar siguiendo una correlación predeterminada .
Como ejemplo, escojamos una correlación r = 0.7 y codifiquemos una matriz de correlación como:
(C <- matrix(c(1,0.7,0.7,1), nrow = 2)) [,1] [,2] [1,] 1.0 0.7 [2,] 0.7 1.0
Podemos usar
mvtnorm
para generar ahora estas dos muestras como un vector aleatorio bivariado:set.seed(0)
SN <- rmvnorm(mean = c(0,0), sig = C, n = 1e5)
resultando en dos componentes vectoriales distribuidos como ~ y con a . Ambos componentes se pueden extraer de la siguiente manera:cor(SN[,1],SN[,2])= 0.6996197 ~ 0.7
X1 <- SN[,1]; X2 <- SN[,2]
Aquí está la trama con la línea de regresión superpuesta:
Use la Transformación integral de probabilidad aquí para obtener un vector aleatorio bivariado con distribuciones marginales ~U(0,1) y la misma correlación :
U <- pnorm(SN)
- entonces estamos alimentandopnorm
elSN
vector para encontrarcor(U[,1], U[,2]) = 0.6816123 ~ 0.7
.Nuevamente podemos descomponer el vector
U1 <- U[,1]; U2 <- U[,2]
y producir un diagrama de dispersión con distribuciones marginales en los bordes, mostrando claramente su naturaleza uniforme:Aplique el método de muestreo de transformación inversa aquí para obtener finalmente el bivector de puntos igualmente correlacionados que pertenezcan a cualquier familia de distribución que nos propongamos reproducir.
A partir de aquí, podemos generar dos vectores distribuidos normalmente y con variaciones iguales o diferentes . Por ejemplo:
Y1 <- qnorm(U1, mean = 8,sd = 10)
yY2 <- qnorm(U2, mean = -5, sd = 4)
, que mantendrá la correlación deseada,cor(Y1,Y2) = 0.6996197 ~ 0.7
.O optar por diferentes distribuciones. Si las distribuciones elegidas son muy diferentes, la correlación puede no ser tan precisa. Por ejemplo, sigamost distribución con 3 df, y λ = 1:
U1
aU2
una exponencial con unZ1 <- qt(U1, df = 3)
yZ2 <- qexp(U2, rate = 1)
elcor(Z1,Z2) [1] 0.5941299 < 0.7
. Aquí están los histogramas respectivos:Aquí hay un ejemplo de código para todo el proceso y los márgenes normales:
A modo de comparación, he reunido una función basada en la descomposición de Cholesky:
Probar ambos métodos para generar correlacionados (por ejemplo,r=0.7 ) muestras distribuidas ~ N(97,23) y N(32,8) obtenemos, configurando
set.seed(99)
:Usando el uniforme:
y usando el Cholesky:
fuente