Não conheço um método universal para gerar variáveis aleatórias correlacionadas com qualquer distribuição marginal. Então, proponho um método ad hoc para gerar pares de variáveis aleatórias distribuídas uniformemente com uma dada correlação (Pearson). Sem perda de generalidade, presumo que a distribuição marginal desejada seja uniforme padrão (ou seja, o suporte é ).[0,1]
A abordagem proposta baseia-se no seguinte:
a) Para as variáveis aleatórias uniformes padrão e L 2 com as respectivas funções de distribuição de F 1 e F 2 , temos F i ( L i ) = L i , para i = 1 , 2 . Assim, por definição Rho de Spearman é
ρ S ( L 1 , L 2 ) = c o r r ( FU1U2F1F2Fi(Ui)=Uii=1,2
Portanto, o rho de Spearman e o coeficiente de correlação de Pearson são iguais (versões amostrais podem, no entanto, diferir).
ρS(U1,U2)=corr(F1(U1),F2(U2))=corr(U1,U2).
b) Se são variáveis aleatórias com margens contínuas e Gaussiana cópula com (Pearson) correlação coeficiente ρ , em seguida, Rho de Spearman é
ρ S ( X 1 , X 2 ) = 6X1,X2ρ
Isso facilita a geração de variáveis aleatórias com o valor desejado do rho de Spearman.
ρS(X1,X2)=6πarcsin(ρ2).
A abordagem é gerar dados da cópula gaussiana com um coeficiente de correlação adequado modo que o rho de Spearman corresponda à correlação desejada para as variáveis aleatórias uniformes.ρ
Algoritmo de simulação
Deixe denotar o nível de correlação desejado e n o número de pares a serem gerados. O algoritmo é:rn
- Calcule .ρ=2sin(rπ/6)
- Gere um par de variáveis aleatórias da cópula gaussiana (por exemplo, com esta abordagem )
- Repita o passo 2 vezes.n
Exemplo
O seguinte código é um exemplo de execução deste algoritmo com R com um alvo de correlação e n = 500 pares.r=0.6n=500
## 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))})
Na figura abaixo, os gráficos diagonais mostram histogramas das variáveis e U 2 e os gráficos fora da diagonal mostram gráficos de dispersão de U 1 e U 2 .
U1U2U1U2
Por construção, as variáveis aleatórias têm margens uniformes e um coeficiente de correlação (próximo a) . Porém, devido ao efeito da amostragem, o coeficiente de correlação dos dados simulados não é exatamente igual a r .rr
cor(U)[1, 2]
# [1] 0.5337697
Observe que a gen.gauss.cop
função deve funcionar com mais de duas variáveis simplesmente especificando uma matriz de correlação maior.
Estudo de simulação
O estudo de simulação a seguir repetido para a correlação alvo sugere que a distribuição do coeficiente de correlação converge para a correlação desejada conforme o tamanho da amostra n aumenta.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")