Non sono a conoscenza di un metodo universale per generare variabili casuali correlate con una determinata distribuzione marginale. Quindi, proporrò un metodo ad hoc per generare coppie di variabili casuali distribuite uniformemente con una data correlazione (Pearson). Senza perdita di generalità, presumo che la distribuzione marginale desiderata sia uniforme standard (ovvero, il supporto è ).[0,1]
L'approccio proposto si basa su quanto segue:
a) Per le variabili casuali uniformi standard e U 2 con le rispettive funzioni di distribuzione F 1 e F 2 , abbiamo F i ( U i ) = U i , per i = 1 , 2 . Quindi, per definizione, il rho di Spearman è
ρ S ( U 1 , U 2 ) = c o r r ( FU1U2F1F2Fi(Ui)=Uii=1,2
Quindi, il coefficiente di correlazione rho e Pearson di Spearman sono uguali (le versioni del campione potrebbero tuttavia differire).
ρS(U1,U2)=corr(F1(U1),F2(U2))=corr(U1,U2).
b) Se sono variabili casuali con margini continui e copula gaussiana con coefficiente di correlazione (Pearson) ρ , allora il rho di Spearman è
ρ S ( X 1 , X 2 ) = 6X1,X2ρ
Ciò semplifica la generazione di variabili casuali che hanno un valore desiderato del rho di Spearman.
ρS(X1,X2)=6πarcsin(ρ2).
L'approccio è generare dati dalla copula gaussiana con un coefficiente di correlazione appropriato tale che il rho di Spearman corrisponda alla correlazione desiderata per le variabili casuali uniformi.ρ
Algoritmo di simulazione
Indichiamo il livello di correlazione desiderato e n il numero di coppie da generare. L'algoritmo è:rn
- Calcola .ρ=2sin(rπ/6)
- Genera una coppia di variabili casuali dalla copula gaussiana (ad esempio, con questo approccio )
- Ripetere il passaggio 2 volte.n
Esempio
Il seguente codice è un esempio di implementazione di questo algoritmo usando R con una correlazione target e n = 500 coppie.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))})
Nella figura seguente, i grafici diagonali mostrano istogrammi delle variabili e U 2 e i grafici off-diagonali mostrano grafici a dispersione di U 1 e U 2 .
U1U2U1U2
Per costruzione, le variabili casuali hanno margini uniformi e un coefficiente di correlazione (vicino a) . Ma a causa dell'effetto del campionamento, il coefficiente di correlazione dei dati simulati non è esattamente uguale a r .rr
cor(U)[1, 2]
# [1] 0.5337697
Si noti che la gen.gauss.cop
funzione dovrebbe funzionare con più di due variabili semplicemente specificando una matrice di correlazione più ampia.
Studio di simulazione
Il seguente studio di simulazione ripetuto per la correlazione target suggerisce che la distribuzione del coefficiente di correlazione converge alla correlazione desiderata all'aumentare della dimensione del campione n .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")