Synthetic Multivariate Data Generator using Gaussian Copulas
Project description
SymPG — Synthetic Multivariate Data Generator
SymPG generates simulated datasets with arbitrary marginal distributions and a user-specified correlation structure, using the Gaussian copula approach. This was originally developed for DNA-methylation (CpG) data simulation.
How it works
- Draw correlated standard-normal samples using the target correlation matrix (Cholesky decomposition).
- Map each column to [0,1] via the normal CDF (probability integral transform).
- Apply the inverse CDF of the desired marginal distribution to each column.
This preserves the rank correlation structure while allowing any marginal shape.
Installation
pip install -e . # from source
# or once published:
pip install sympg
Quick start
import sympg
# 1. Define marginal distributions for each variable
# distributions = [
# "normal", # standard normal
# {"name": "beta", "a": 2, "b": 5}, # beta(2,5) → bounded [0,1]
# {"name": "gamma", "a": 3}, # gamma(shape=3)
# ]
distributions=["normal", "beta",
dict(name='gamma3', type='gamma', a=3)]
# distributions = ["normal", "beta", "gamma"]
# 2. Define one or more correlation scenarios
# Length = n_vars*(n_vars-1)/2 (upper triangle, row-major)
correlations = [0.1, 0.5, 0.9]
# 3. Generate ALL combinations → one long-format DataFrame
result = sympg.simulate_grid(
distributions=distributions,
correlations=correlations,
n_obs=500,
random_state=42,
)
result["data"] # (500, 9) wide DataFrame
result["corr_matrix"] # observed 9×9 Spearman matrix
result["metadata"] # column_name, dist_label, block_corr, var_index
Multiple distribution sets
Pass a list of lists to sweep both distribution types and correlation levels:
dist_sets = [
["normal", {"name": "beta", "a": 0.5, "b": 0.5}], # set A
["normal", {"name": "gamma_norm", "a": 2}], # set B
]
df = sympg.simulate_grid(
distributions=dist_sets, # 2 sets × 3 corr scenarios = 6 datasets
correlations=correlations,
n_obs=500,
var_names=["phenotype", "CpG1"],
random_state=0,
)
print(df["sim_dist_set"].unique()) # [0, 1]
print(df["sim_corr_set"].unique()) # [0, 1, 2]
print(df.shape) # (3000, 5)
Single dataset
single = sympg.simulate(
distributions=["normal", {"name": "beta", "a": 2, "b": 5}],
correlations=[0.7], # one pair → one value
n_obs=1000,
var_names=["x", "y"],
random_state=1,
)
Output columns
| Column | Description |
|---|---|
sim_dist_set |
Index of the distribution set (0-based) |
sim_corr_set |
Index of the correlation scenario (0-based) |
sim_obs_id |
Within-dataset observation index (0-based) |
| var columns | Simulated variable values |
Built-in distributions
| Key | Scipy basis | Key parameters |
|---|---|---|
normal |
scipy.stats.norm |
loc, scale |
beta |
scipy.stats.beta |
a, b |
gamma |
scipy.stats.gamma |
a, scale |
gamma_norm |
scipy.stats.gamma (min–max normalised) |
a, scale |
lognormal |
scipy.stats.lognorm |
s, scale |
uniform |
scipy.stats.uniform |
low, high |
truncnorm |
scipy.stats.truncnorm |
a, b, loc, scale |
Custom callables are also accepted: f(uniform_samples: np.ndarray) -> np.ndarray.
Diagnostics helpers
# Observed correlation summary across all scenarios
corr_summary = sympg.summarise_correlations(df, var_names=["phenotype", "CpG1", "CpG2"])
# Human-readable scenario metadata table
meta = sympg.get_scenario_metadata(dist_sets, correlations, var_names=["phenotype", "CpG1", "CpG2"])
Saving results
df.to_csv("simulated_grid.csv", index=False)
Correlation input format
For n variables you need n*(n-1)/2 values, filling the upper triangle
row-by-row. For 4 variables (phenotype, CpG1, CpG2, CpG3):
Position 0 → (phenotype, CpG1)
Position 1 → (phenotype, CpG2)
Position 2 → (phenotype, CpG3)
Position 3 → (CpG1, CpG2)
Position 4 → (CpG1, CpG3)
Position 5 → (CpG2, CpG3)
So correlations = [[0.8, 0.0, 0.4, 0.2, 0.1, 0.0]] replicates the
original notebook example.
If the matrix is not positive-definite, SymPG applies Higham's nearest-PD
algorithm automatically (disable with repair_pd=False).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sympg-0.1.0.tar.gz.
File metadata
- Download URL: sympg-0.1.0.tar.gz
- Upload date:
- Size: 15.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8bf82dbc2287344b19fd18658f3faa770456d12356b23c91ea7e4ab65c0ec386
|
|
| MD5 |
1ff5b9947f3c11e5e67542fd146f3d3c
|
|
| BLAKE2b-256 |
da1b3864903a50db940c1bf1c8a9733782bebd2a50296feb9019c0fc401b85cc
|
File details
Details for the file sympg-0.1.0-py3-none-any.whl.
File metadata
- Download URL: sympg-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3832e2b71246bf9ec1a6fe173cd5c76271cf4dd31d8ac0188dd80d033230b2cc
|
|
| MD5 |
c02370757210a430f27fd5bd7e2933bb
|
|
| BLAKE2b-256 |
6c8b8b72d37444de2d2c2fc597416f3f36b5a24295a829357218e9551e391ac2
|