No conozco un método universal para generar variables aleatorias correlacionadas con cualquier distribución marginal dada. Por lo tanto, propondré un método ad hoc para generar pares de variables aleatorias distribuidas uniformemente con una correlación dada (Pearson). Sin pérdida de generalidad, supongo que la distribución marginal deseada es uniforme estándar (es decir, el soporte es ).[0,1]
El enfoque propuesto se basa en lo siguiente:
a) Para las variables aleatorias uniformes estándar y U 2 con las funciones de distribución respectivas F 1 y F 2 , tenemos F i ( U i ) = U i , para i = 1 , 2 . Por lo tanto, por definición , rho de Spearman es
ρ S ( U 1 , U 2 ) = c o r r ( FU1U2F1F2Fi(Ui)=Uii=1,2
Entonces, el coeficiente de correlación de Spearman rho y Pearson son iguales (las versiones de muestra pueden, sin embargo, diferir).
ρS(U1,U2)=corr(F1(U1),F2(U2))=corr(U1,U2).
b) Si son variables aleatorias con márgenes continuos y cópula gaussiana con coeficiente de correlación (Pearson) ρ , entonces rho de Spearman es
ρ S ( X 1 , X 2 ) = 6X1,X2ρ
Esto facilita la generación de variables aleatorias que tienen un valor deseado de rho de Spearman.
ρS(X1,X2)=6πarcsin(ρ2).
El enfoque consiste en generar datos de la cópula gaussiana con un coeficiente de correlación apropiado tal que el rho de Spearman corresponda a la correlación deseada para las variables aleatorias uniformes.ρ
Algoritmo de simulación
Deje denotar el nivel deseado de correlación, yn el número de pares que se generarán. El algoritmo es:rn
- Calcule .ρ=2sin(rπ/6)
- Genere un par de variables aleatorias a partir de la cópula gaussiana (por ejemplo, con este enfoque )
- Repita el paso 2 veces.n
Ejemplo
El siguiente código es un ejemplo de implementación de este algoritmo usando R con una correlación objetivo y n = 500r=0.6n=500 parejas.
## Initialization and parameters
set.seed(123)
r <- 0.6 # Target (Spearman) correlation
n <- 500 # Number of samples
## Functions
gen.gauss.cop <- function(r, n){
rho <- 2 * sin(r * pi/6) # Pearson correlation
P <- toeplitz(c(1, rho)) # Correlation matrix
d <- nrow(P) # Dimension
## Generate sample
U <- pnorm(matrix(rnorm(n*d), ncol = d) %*% chol(P))
return(U)
}
## Data generation and visualization
U <- gen.gauss.cop(r = r, n = n)
pairs(U, diag.panel = function(x){
h <- hist(x, plot = FALSE)
rect(head(h$breaks, -1), 0, tail(h$breaks, -1), h$counts/max(h$counts))})
En la figura siguiente, las gráficas diagonales muestran histogramas de las variables y U 2 , y las gráficas fuera de la diagonal muestran gráficas de dispersión de U 1 yU1U2U1 .
U2
Por construcción, las variables aleatorias tienen márgenes uniformes y un coeficiente de correlación (cercano a) . Pero debido al efecto del muestreo, el coeficiente de correlación de los datos simulados no es exactamente igual a rrr .
cor(U)[1, 2]
# [1] 0.5337697
Tenga en cuenta que la gen.gauss.cop
función debería funcionar con más de dos variables simplemente especificando una matriz de correlación más grande.
r=−0.5,0.1,0.6n
## Simulation
set.seed(921)
r <- 0.6 # Target correlation
n <- c(10, 50, 100, 500, 1000, 5000); names(n) <- n # Number of samples
S <- 1000 # Number of simulations
res <- sapply(n,
function(n, r, S){
replicate(S, cor(gen.gauss.cop(r, n))[1, 2])
},
r = r, S = S)
boxplot(res, xlab = "Sample size", ylab = "Correlation")
abline(h = r, col = "red")