14
$\begingroup$

I would like to generate pairs of random numbers with certain correlation. However, the usual approach of using a linear combination of two normal variables is not valid here, because a linear combination of uniform variables is not any more an uniformly distributed variable. I need the two variables to be uniform.

Any idea on how to generate pairs of uniform variables with a given correlation?

$\endgroup$
  • 6
    $\begingroup$ Closely related: stats.stackexchange.com/questions/30526. You also want to check out the copula tag--just click on the link here. A quick and dirty technique is to let $X$ be uniform$[0,1]$ and $Y=X$ when $X\le\alpha$ and $Y=1+\alpha-X$ otherwise. The correlation is $\rho=2(\alpha-1)^3+1$, whence $\alpha=1-((1-\rho)/2)^{1/3}$ does the trick. But copulas will give you more control... . $\endgroup$ – whuber Aug 5 '13 at 20:32
  • $\begingroup$ Thanks for the comment, but yes, I think this method is really "dirty" $\endgroup$ – Onturenio Aug 6 '13 at 12:46
  • 1
    $\begingroup$ My hope was that in seeing this approach you would recognize that you can (and ought to) provide additional criteria concerning the properties of your pairs of random numbers. If this is "dirty," then precisely what is wrong with the solution? Tell us so that we can provide more appropriate answers for your situation. $\endgroup$ – whuber Aug 6 '13 at 14:13
  • $\begingroup$ This question was answered incidentally in the response to a closely related question: how to generate pairs of RVs with a linear regression relationship. Because the slope of the linear regression is related in a readily computed way to the correlation coefficient, and all possible slopes can be produced, it gives a way to produce exactly what you want. See stats.stackexchange.com/questions/257779/…. $\endgroup$ – whuber May 23 '17 at 23:38
  • 1
    $\begingroup$ Please also see stats.stackexchange.com/questions/31771, which answers the generalization to three random uniforms. $\endgroup$ – whuber May 23 '17 at 23:40
15
+50
$\begingroup$

I'm not aware of a universal method to generate correlated random variables with any given marginal distributions. So, I'll propose an ad hoc method to generate pairs of uniformly distributed random variables with a given (Pearson) correlation. Without loss of generality, I assume that the desired marginal distribution is standard uniform (i.e., the support is $[0, 1]$).

The proposed approach relies on the following:
a) For standard uniform random variables $U_1$ and $U_2$ with respective distribution functions $F_1$ and $F_2$, we have $F_i(U_i) = U_i$, for $i = 1, 2$. Thus, by definition Spearman's rho is $$ \rho_{\rm S}(U_1, U_2) = {\rm corr}(F_1(U_1), F_2(U_2)) = {\rm corr}(U_1, U_2) . $$ So, Spearman's rho and Pearson's correlation coefficient are equal (sample versions might however differ).

b) If $X_1, X_2$ are random variables with continuous margins and Gaussian copula with (Pearson) correlation coefficient $\rho$, then Spearman's rho is $$ \rho_{\rm S}(X_1, X_2) = \frac{6}{\pi} \arcsin \left(\frac{\rho}{2}\right) . $$ This makes it easy to generate random variables that have a desired value of Spearman's rho.

The approach is to generate data from the Gaussian copula with an appropriate correlation coefficient $\rho$ such that the Spearman's rho corresponds to the desired correlation for the uniform random variables.

Simulation algorithm
Let $r$ denote the desired level of correlation, and $n$ the number of pairs to be generated. The algorithm is:

  1. Compute $\rho = 2\sin (r \pi/6)$.
  2. Generate a pair of random variables from the Gaussian copula (e.g., with this approach)
  3. Repeat step 2 $n$ times.

Example
The following code is an example of implementation of this algorithm using R with a target correlation $r = 0.6$ and $n = 500$ pairs.

## 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))})

In the figure below, the diagonal plots show histograms of variables $U_1$ and $U_2$, and off-diagonal plots show scatter plots of $U_1$ and $U_2$. enter image description here

By constuction, the random variables have uniform margins and a correlation coefficient (close to) $r$. But due to the effect of sampling, the correlation coefficient of the simulated data is not exactly equal to $r$.

cor(U)[1, 2]
# [1] 0.5337697

Note that the gen.gauss.cop function should work with more than two variables simply by specifying a larger correlation matrix.

Simulation study
The following simulation study repeated for target correlation $r= -0.5, 0.1, 0.6$ suggests that the distribution of the correlation coefficient converges to the desired correlation as the sample size $n$ increases.

## 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")

enter image description here enter image description here enter image description here

$\endgroup$
  • 3
    $\begingroup$ The general method to generate correlated multivariate distributions with given marginal distributions is called a copula. $\endgroup$ – whuber Aug 6 '13 at 2:25
  • $\begingroup$ @whuber, the use of copula allows to specify a dependence structure between random variables. The problem is that (Person) correlation is influenced by both the dependence structure and the margins. So, each choice of margins will require a corresponding choice of copula parameters, not to mention that some levels of correlation simply can't be attained for given margins (e.g., see here). If you are aware of a method that allows to 'control' the level of correlation for any choice of margins, I would love to know about it. $\endgroup$ – QuantIbex Aug 6 '13 at 7:11
  • $\begingroup$ Thanks @QuantIbex. But I don't get why "a) implies that Spearman's rho and (Pearson's) correlation coefficient for random variables with standard uniform margins are approximately equal in large sample" $\endgroup$ – Onturenio Aug 6 '13 at 12:45
  • 1
    $\begingroup$ Quantlbex, all you need is to create a continuous path of copulas from the lower to the upper Frechet-Hoeffding bounds. For identical marginals, the correlation coefficient will be a continuous function from that path into the interval $[-1,1]$. My "quick and dirty" example in a comment to the question is one such path, but obviously there are many others: copulas give you the fullest, most general way to create and describe such paths. What this shows is that the original question is (grossly) underdetermined: it ought to stipulate additional criteria for the solution. $\endgroup$ – whuber Aug 6 '13 at 13:44
  • 1
    $\begingroup$ @Quantibex I took the liberty of adding a sentence that points out your gen.gauss.cop function will work for more than two variables with a (trivial) tweak. If you don't like the addition or wish to put it differently please revert or change as needed. $\endgroup$ – Glen_b May 24 '17 at 0:26
0
$\begingroup$

Intuitively, $u_1$ is $U(0,1)$ because $u_1$ equals $w_1$ [which is $U(0,1)$] if $I = 1$, and $u_1$ equals $w_2$ [which is $U(0,1)$] if $I = 0$, so $u_1$ is $U(0,1)$ in either case. The same for $u_2$. As for the correlation:

$E(u_1 u_2) = E[I w_1 + (1-I) w_2][I w_1 + (1-I) w_3]$

Expanding this, note first that $I(I-1)=0$, $I^2=I$, and $(1-I)^2=(1-I)$ because $I$ is always either $0$ or $1$. Note also that $I$ is independent of the $w$'s, which are also independent of each other. So:

$E(u_1 u_2) = E(I)E(w_1^2) + E(1-I)E(w_2)E(w_3)$ $=pE(w_1^2)+(1-p)/4$

From the fact that $V(w_1)=1/12$, we get $E(w_1^2)=1/3$, so $E(u_1 u_2) = p/12 + 1/4$, that is: $cov(u_1 u_2) = p/12$. Since $V(u_1)=V(u_2)=1/12$, we get finally that $cor(u_1, u_2) = p$.

$\endgroup$
0
$\begingroup$

Here is one easy method for positive correlation: Let $(u_1, u_2) = Iw_1 + (1-I) (w_2, w_3)$, where $w_1, w_2,$ and $w_3$ are independent $U(0,1)$ and $I$ is Bernoulli($p$). $u_1$ and $u_2$ will then have $U(0,1)$ distributions with correlation $p$. This extends immediately to $k$-tuples of uniforms with compound symmetric variance matrix.

If you want pairs with negative correlation, use $(u_1, u_2) = I(w_1, 1-w_1) + (1-I)(w_2, w_3)$, and the correlation will be $-p$.

$\endgroup$
  • $\begingroup$ Can you add a short proof of why this works? $\endgroup$ – The Laconic Apr 28 '18 at 13:30
  • $\begingroup$ if your want to be computationally efficient, $u_1=w_1$ also produces the same correlation (both positive and negative cases) $\endgroup$ – Anvit Apr 23 at 12:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.