Aquí hay una receta, en caso de que puedas vivir con la correlación de rango de Spearman. (Lo cual deberías: la correlación lineal a menudo no es adecuada en el caso no normal. Y en el caso normal, casi no hay diferencia entre los dos tipos de correlación.)
-
Genera muestras de tus $k$ características con todos los atributos deseados. Estas muestras pueden ser aleatorias o datos históricos. Las muestras no necesitan tener el mismo tamaño.
-
Supongamos que deseas generar $n$ escenarios. Luego genera $n$ normales $k$-dimensionales con la correlación deseada (es decir, una matriz de tamaño $n$ veces $k$). Aquí puedes usar Cholesky. (Estrictamente hablando, necesitarías modificar las correlaciones en $2\sin(\rho\pi/6)$. Pero esta corrección es tan pequeña que puedes dejarla fuera.)
-
Alimenta estos variados normales correlacionados en la función de distribución normal. El resultado será $n$ vectores de uniformes que tienen la misma correlación de rango que las normales (porque la función de distribución es monótonamente creciente).
-
Alimenta estos uniformes en las inversas de las funciones de distribución empírica de tus muestras del paso 1. (Esto es fácil: para un variable uniforme $u$, ordena una muestra de características dadas y luego elige el elemento en la posición ceiling(u*length(feature_sample))
.) Debido a que las inversas son no decrecientes, la correlación de rango se mantendrá.
En caso de que uses R
: Todo este procedimiento está implementado en la función resampleC
en el paquete NMOF
(que mantengo). Aquí tienes un ejemplo.
library("NMOF")
gdp <- runif(10000, min = 2, max = 3.5)
une <- runif(10000, min = 4.4, max = 5.1)
dji <- runif(10000, min = 22000, max = 24000)
cor <- array(c(1.0, 0.5, 0.3,
0.5, 1.0, 0.9,
0.3, 0.9, 1.0), dim = c(3,3))
smp <- resampleC(gdp, une, dji, cormat = cor, size = 1000)
cor(smp)
## var1 var2 var3
## var1 1.0000000 0.5140693 0.3041248
## var2 0.5140693 1.0000000 0.9012560
## var3 0.3041248 0.9012560 1.0000000
Podemos verificar los rangos.
apply(smp, 2, range)
## var1 var2 var3
## [1,] 2.000432 4.401090 22005.30
## [2,] 3.499644 5.098867 23998.15
Un enfoque completamente diferente es crear muestras de tus características (esta vez de la misma longitud), ponerlas en las columnas de una matriz, y luego reorganizar los elementos dentro de las columnas para que te acerques a la matriz de correlación deseada. Ver esta respuesta.