# Generate synthetic multi-dimensional data given its correlation and distribution

I am trying to create a synthetic dataset with 3 columns. I know the correlation between each pair of columns. How do I go about it? A search revealed this Copula distribution example, but it creates 2D data.

I am trying to create a, say, 200 rows with 3 columns, that somewhat looks like:

91.9449  94.6969  92.127
87.0049  89.4548  88.0767
82.5728  87.1846  78.6421
91.7373  95.0214  90.4396
81.3041  91.7888  86.5789


d1 = NormalDistribution[66, 9.28];
d2 = NormalDistribution[98.66, 5.76];
d3 = NormalDistribution[68.71, 9.57];
{"Multinormal", 1/3},
{d1, d2, d3}]


I know that each column has a correlation of around 0.4 with the other.

• Have you seen MultinormalDistribution? It directly takes a covariance matrix as input. Commented Jun 11, 2020 at 17:52
• @MarcoB I just noticed that after you mention it. I am trying to understand the syntax. It seems to only take 2 means but I need 3 means (one for each column)? I wonder if I am comprehending this right. Commented Jun 11, 2020 at 17:59
• It takes however many means you want, just in a list. Try RandomVariate[MultinormalDistribution[{1, 2, 3}, IdentityMatrix[3]], 3] just to see how it might work. In this example I impose zero correlation between variables, each with a mean of 1, 2, or 3, respectively. Commented Jun 11, 2020 at 18:02
• @MarcoB Thank you dear sir/madam. You are more than welcome to provide this as an answer if you wish and if you think this is not a trivial question. Commented Jun 11, 2020 at 18:24

You can use MultinormalDistribution:

means = {1, 10, 50};
covariance = {
{1, 0.1, 0.9},
{0.1, 1, 0.2},
{0.9, 0.2, 1}
};

dist = MultinormalDistribution[means, covariance];


You can then get points from the distribution as follows:

pts = RandomVariate[dist, 250];



Here are pairwise scatter plots to show the relationships between variables:

Grid@
Table[
ListPlot[pts[[All, {i, j}]], Axes -> False, Frame -> True],
{i, 3}, {j, 3}
]


• very nice, thank you! From a pedagogic perspective, your answer defines many learning objectives to a student (such as myself) of statistical distributions. It is greatly appreciated. Commented Jun 12, 2020 at 11:57
ClearAll["Global*"]

Format[σ[i_]] := Subscript[σ, i];
Format[ρ[i_, j_]] := Subscript[ρ, StringJoin[ToString /@ {i, j}]];


d1 = NormalDistribution[66.0625, 9.284389244512372];
d2 = NormalDistribution[98.66843971631205, 5.7644614465554795];
d3 = NormalDistribution[68.71808510638297, 9.570687048927134];


The mean vector is

μ = First /@ {d1, d2, d3};

ρ[i_, i_] := 1;
ρ[i_, j_] /; j < i := ρ[j, i];


The covariance matrix is

coVar[n_] := Array[ ρ[#1, #2]*σ[#1]*σ[#2] &, {n, n}];


(Σ = coVar[3]) // MatrixForm


For your distributions and with the correlation coefficients all being 0.4 the covariance matrix is

(Σv = Σ /.
Thread[{ρ[1, 2], ρ[1, 3], ρ[2, 3]} -> 0.4] /.
Thread[{σ[1], σ[2], σ[3]} -> Last /@ {d1, d2, d3}]) //
MatrixForm


jointD = MultinormalDistribution[μ, Σv];


You generate data with RandomVariate

SeedRandom[1234];
(data = RandomVariate[jointD, 10]) // MatrixForm
`