Nie znam uniwersalnej metody generowania skorelowanych zmiennych losowych z dowolnymi rozkładami krańcowymi. Tak więc zaproponuję metodę ad hoc do generowania par równomiernie rozmieszczonych zmiennych losowych o zadanej korelacji (Pearsona). Bez utraty ogólności, zakładam, że pożądany rozkład krańcowy jest standardowy jednolity (tj. Wsparcie wynosi ).[ 0 , 1 ]
Proponowane podejście opiera się na:
a) Dla standardowych jednorodnych zmiennych losowych i U 2 z odpowiednimi funkcjami rozkładu F 1 i F 2 , mamy F i ( U i ) = U i , dla i = 1 , 2 . Zatem z definicji rho Spearmana wynosi
ρ S ( U 1 , U 2 ) =U1U2F1F2Fi(Ui)=Uii=1,2
Tak więc rho Spearmana i współczynnik korelacji Pearsona są równe (wersje przykładowe mogą się jednak różnić).
ρS.( U1, U2))=corr(F1(U1),F2(U2))=corr(U1,U2).
b) Jeśli są zmiennymi losowymi z ciągłymi marginesami i kopulą Gaussa ze współczynnikiem korelacji (Pearsona) ρ , wówczas rho Spearmana wynosi
ρ S ( X 1 , XX1,X2ρ
Ułatwia to generowanie losowych zmiennych, które mają pożądaną wartość rho Spearmana.
ρS(X1,X2)=6πarcsin(ρ2).
Podejście polega na generowaniu danych z kopuły Gaussa z odpowiednim współczynnikiem korelacji tak aby rho Spearmana odpowiadało pożądanej korelacji dla jednolitych zmiennych losowych.ρ
Algorytm symulacji
Niech r oznacza pożądany poziom korelacji, a liczbę generowanych par. Algorytm to:n
- Oblicz .ρ=2sin(rπ/6)
- Wygeneruj parę zmiennych losowych z kopuły Gaussa (np. Przy takim podejściu )
- Powtórz krok 2 razy.n
Przykład
Poniższy kod jest przykładem implementacji tego algorytmu przy użyciu R z korelacją docelową i n = 500 par.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 poniższym rysunku wykresy ukośne pokazują histogramy zmiennych i U 2 , a wykresy nie przekątne pokazują wykresy rozproszenia U 1 iU1U2U1 .
U2
Konstruując, zmienne losowe mają jednolite marginesy i współczynnik korelacji (bliski) . Ale ze względu na efekt próbkowania współczynnik korelacji symulowanych danych nie jest dokładnie równyr .r
cor(U)[1, 2]
# [1] 0.5337697
Zauważ, że gen.gauss.cop
funkcja powinna działać z więcej niż dwiema zmiennymi, po prostu określając większą macierz korelacji.
Badanie symulacyjne
Poniższe badanie symulacyjne powtórzone dla korelacji docelowej sugeruje, że rozkład współczynnika korelacji zbliża się do pożądanej korelacji wraz ze wzrostem wielkości próby 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")