3
$\begingroup$

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

How do I go about this? The best I have so far is:

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

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

$\endgroup$
5
  • $\begingroup$ Have you seen MultinormalDistribution? It directly takes a covariance matrix as input. $\endgroup$
    – MarcoB
    Commented Jun 11, 2020 at 17:52
  • $\begingroup$ @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. $\endgroup$
    – dearN
    Commented Jun 11, 2020 at 17:59
  • 1
    $\begingroup$ 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. $\endgroup$
    – MarcoB
    Commented Jun 11, 2020 at 18:02
  • $\begingroup$ @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. $\endgroup$
    – dearN
    Commented Jun 11, 2020 at 18:24
  • 1
    $\begingroup$ Glad it helped. I've added an answer. $\endgroup$
    – MarcoB
    Commented Jun 11, 2020 at 19:36

2 Answers 2

2
$\begingroup$

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}
 ]

pairwise scatter plots

$\endgroup$
1
  • $\begingroup$ 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. $\endgroup$
    – dearN
    Commented Jun 12, 2020 at 11:57
1
$\begingroup$
ClearAll["Global`*"]

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

Your marginal distributions are

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}];

For your example,

(Σ = coVar[3]) // MatrixForm

enter image description here

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

enter image description here

jointD = MultinormalDistribution[μ, Σv];

You generate data with RandomVariate

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

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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