Я не знаю универсального метода для генерации коррелированных случайных величин с любым заданным предельным распределением. Итак, я предложу специальный метод для генерации пар равномерно распределенных случайных величин с заданной (Pearson) корреляцией. Без ограничения общности я предполагаю, что желаемое предельное распределение является стандартным равномерным (т. Е. Поддержка [0,1] ).
Предлагаемый подход основан на следующем:
a) Для стандартных равномерных случайных величин и U 2 с соответствующими функциями распределения F 1 и F 2 имеем F i ( U i ) = U i , для i = 1 , 2 . Таким образом, по определению число Спирмена равно
ρ S ( U 1 , U 2 ) = c o r r ( FU1U2F1F2Fi(Ui)=Uii=1,2
Таким образом, коэффициенты корреляции Спирмена и Пирсона равны (примерные версии могут отличаться).
ρS(U1,U2)=corr(F1(U1),F2(U2))=corr(U1,U2).
б) Если являются случайными величинами с непрерывными полями и гауссовой копулой с коэффициентом корреляции (Пирсона) ρ , то число Спирмена равно
ρ S ( X 1 , X 2 ) = 6X1,X2ρ
Это позволяет легко генерировать случайные величины, которые имеют желаемое значение ро Спирмена.
ρS(X1,X2)=6πarcsin(ρ2).
Подход заключается в том, чтобы генерировать данные из гауссовой связки с подходящим коэффициентом корреляции , так что относительное число Спирмена соответствует желаемой корреляции для однородных случайных величин.ρ
Алгоритм моделирования
Пусть обозначает желаемый уровень корреляции, а n - количество генерируемых пар. Алгоритм:rn
- Вычислить .ρ=2sin(rπ/6)
- Генерация пары случайных величин из гауссовой связки (например, при таком подходе )
- Повторите шаг 2 раз.n
Пример
Следующий код является примером реализации этого алгоритма с использованием R с целевой корреляцией и n = 500 пар.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))})
На рисунке ниже, диагональные графики показывают гистограммы переменных и U 2 , а недиагональные графики показывают графики рассеяния U 1 и U 2 .
U1U2U1U2
По построению случайные величины имеют одинаковые поля и коэффициент корреляции (близкий к) . Но из-за эффекта выборки коэффициент корреляции смоделированных данных не точно равен r .rr
cor(U)[1, 2]
# [1] 0.5337697
Обратите внимание, что gen.gauss.cop
функция должна работать с более чем двумя переменными, просто указав большую корреляционную матрицу.
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")