Author
Keywords
covariance matrices, Matlab, R, random numbers, random variables
Review Status
Reviewed; revised 2009-02-12.
Overview
The tutorial describes a method to generate uniformly distributed random variates that exhibit a prespecified linear correlation.
The Problem
Assume one wants to create a vector $U$ of random variates where each element is distributed uniformly over the interval $[0,1]$, and the elements of $U$ are linearly correlated as specified in a matrix $\Sigma$.
Solution
Assume a multivariate random variable $X$ is defined as
(1)where $F$ is some distribution function2 and $U\! \sim \! \mathcal{U}[0,1]$. A well-known fact (sometimes used for generating random variates with non-uniform disitributions) is that $X$ will be a random variable with distribution $F$. Reversing this expression, one can create uniformly distributed variates from variates following other distributions by inserting the latter into their respective distribution function. Such transformations, however, will typically affect the dependence between the original variables.
Bravais-Pearson (or linear) correlation is not necessarily invariant to transformations (only to certain linear ones), thus if the original non-uniform variates $X$ have been linearly correlated, there is no guaranty that this linear correlation will be preserved after the transformation. However, other measures of dependence are more ‘robust’ to transformations of the variables. One of those measures is Spearman correlation (also called rank correlation, or fractile correlation) which is invariant to any strictly increasing transformation. Hence, as long as $F$ is strictly monotonically increasing, Spearman correlation will be preserved. A useful result relating Bravais-Pearson and Spearman correlation is that if $X\! \sim \! F$ and $Y\! \sim \! G$ (where $G$ is another distribution function), then
(2)Here $\rho^B$ is the Bravais-Pearson correlation, the $\rho^S$ is the Spearman correlation. So the linear correlation between the uniforms obtained from transforming the original variates equals the Spearman correlation between the original variates. (For details, see [2].) So what is needed are random variables (following some distribution) for which we can easily generate realisations with a given Spearman correlation.
Assume $F$ is the normal distribution function. Thus, let the multivariate random variable $Z$ be distributed as
(3)Assume further that the marginals of $Z$ are standardised, that is $\Sigma$ is also the Bravais-Pearson correlation matrix of $Z$. (See here for how to create linearly correlated normal variates.)
For the normal distribution, the exact relationship between Spearman correlation and Bravais-Pearson correlation is known (see [4]) and given by
(4)Equations (2) and (4) suggest a simple way to obtain a desired Bravais-Pearson correlation for uniforms: Set up the desired Bravais-Pearson correlation matrix $\Sigma$ (these are actually Spearman correlations for the normals, but will be Bravais-Pearson correlations for the uniforms). Then, find the linear correlation matrix $\Sigma^{\mathrm{adj}}$ corresponding to the Spearman matrix $\Sigma$ (i.e., adjust $\Sigma$ according to Equation (4)). Create normal variates with the adjusted correlations $\Sigma^{\mathrm{adj}}$, and transform these normals into uniforms.
Summarised in pseudocode:
(The computations in step 2 need to be done elementwise on $\Sigma$.)
In fact, even without the adjustment (step 2), the method works very well for the case normal-to-uniform, since the maximum absolute difference between $\rho^B$ and $\rho^S$ after the transformation is less than 0.02. For a more detailed discussion, see for instance [1].
A Matlab implementation
The sample code creates 1,000 realisations of four correlated random variates, where the first two variates have a normal distribution and the other two are uniformly distributed.
% generate normals, check correlations
X = randn(1000,4);
corrcoef(X)
% desired correlation
M =[1.0 0.7 0.6 0.6;
0.7 1.0 0.6 0.6;
0.6 0.6 1.0 0.8;
0.6 0.6 0.8 1.0];
% adjust correlations for uniforms
for i = 1:4
for j = max(3,i):4
if i ~= j
M(i, j) = 2 * sin(pi * M(i, j) / 6);
M(j, i) = 2 * sin(pi * M(j, i) / 6);
end
end
end
% induce correlation, check correlations
C = chol(M);
Y = X * C;
corrcoef(Y)
% create uniforms, check correlations
Y(:,3:4) = normcdf(Y(:,3:4));
corrcoef(Y)
% plot results (marginals)
for i=1:4
subplot(2,2,i);
hist(Y(:,i))
title(['Y ', int2str(i)])
end
An R implementation
The sample code creates 1,000 realisations of four correlated random variates, where the first two variates have a normal distribution and the other two are uniformly distributed.
# generate normals, check correlations
X <- array(rnorm(4000), dim = c(1000, 4))
cor(X)
# desired correlation
M <- c(1.0, 0.7, 0.6, 0.6, 0.7, 1.0, 0.6, 0.6, 0.6, 0.6, 1.0, 0.8, 0.6, 0.6, 0.8, 1.0)
dim(M) <- c(4, 4)
# adjust correlations for uniforms
for (i in 1:4){
for (j in max(i, 3):4){
if (i != j){
M[i, j] <- 2 * sin(pi * M[i, j] / 6)
M[j, i] <- 2 * sin(pi * M[j, i] / 6)
}
}
}
# induce correlation, check correlations
C <- chol(M)
Y <- X %*% C
cor(Y)
# create uniforms, check correlations
Y[, 3:4] <- pnorm(Y[, 3:4])
cor(Y)
# plot results (marginals)
par(mfrow = c(2, 2))
for (i in 1:4){
hist(Y[, i], main = paste("Y", i), xlab = "")
}
Internal Links
Concepts |
Generating correlated normal variates |
Tutorials |
Tips |
Related Articles |
External links
References |
1. Dias, C.T.d.S., A. Samaranayaka and B. Manly (2008). On the use of correlated beta random variables with animal population modelling. Ecological Modelling 215, 293-300.
2. Embrechts, P., F. Lindskog and A. J. McNeil (2001). Modelling Dependence with Copulas and Applications to Risk Management, in: S. T. Rachev (ed). Handbook of Heavy Tailed Distributions in Finance. Elsevier.
3. Gilli, M., D. Maringer and E. Schumann. (2011). Numerical Methods and Optimization in Finance. Elsevier.
4. Hotelling, H. and M.R. Pabst (1936). Rank Correlation and Tests of Significance Involving No Assumption of Normality. Annals of Mathematical Statistics 7, 29-43.
|
Weblinks |
E. Schumann. 'Creating rank-correlated triangular variates' |