catgen 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- catgen-0.1.0/LICENSE +21 -0
- catgen-0.1.0/PKG-INFO +293 -0
- catgen-0.1.0/README.md +254 -0
- catgen-0.1.0/pyproject.toml +77 -0
- catgen-0.1.0/setup.cfg +4 -0
- catgen-0.1.0/src/catgen/__init__.py +64 -0
- catgen-0.1.0/src/catgen/datasets/__init__.py +80 -0
- catgen-0.1.0/src/catgen/datasets/biomedical.py +161 -0
- catgen-0.1.0/src/catgen/datasets/boolean_concepts.py +309 -0
- catgen-0.1.0/src/catgen/datasets/geometric.py +246 -0
- catgen-0.1.0/src/catgen/datasets/multiplexer.py +68 -0
- catgen-0.1.0/src/catgen/datasets/snp_generators.py +186 -0
- catgen-0.1.0/src/catgen/datasets/structured.py +150 -0
- catgen-0.1.0/src/catgen/simulation/__init__.py +15 -0
- catgen-0.1.0/src/catgen/simulation/snp.py +563 -0
- catgen-0.1.0/src/catgen.egg-info/PKG-INFO +293 -0
- catgen-0.1.0/src/catgen.egg-info/SOURCES.txt +20 -0
- catgen-0.1.0/src/catgen.egg-info/dependency_links.txt +1 -0
- catgen-0.1.0/src/catgen.egg-info/requires.txt +10 -0
- catgen-0.1.0/src/catgen.egg-info/top_level.txt +1 -0
- catgen-0.1.0/tests/test_dataset_generators.py +388 -0
- catgen-0.1.0/tests/test_simulation.py +317 -0
catgen-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 catgen contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
catgen-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: catgen
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Categorical data generator for ML benchmarks: SNP genetics, k-multiplexer, DNF concepts, epistasis, geometric boundaries, and more
|
|
5
|
+
Author: catgen contributors
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Italbytz/pypi-catgen
|
|
8
|
+
Project-URL: Documentation, https://github.com/Italbytz/pypi-catgen#readme
|
|
9
|
+
Project-URL: Source, https://github.com/Italbytz/pypi-catgen
|
|
10
|
+
Project-URL: Changelog, https://github.com/Italbytz/pypi-catgen/releases
|
|
11
|
+
Project-URL: Bug Tracker, https://github.com/Italbytz/pypi-catgen/issues
|
|
12
|
+
Keywords: SNP,genetics,simulation,categorical data,Hardy-Weinberg,logistic regression,high-dimensional data,scrime,multiplexer,boolean concepts,benchmark datasets,epistasis,DNF,machine learning,synthetic data
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
24
|
+
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
25
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
26
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
27
|
+
Requires-Python: >=3.10
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Requires-Dist: numpy>=1.23
|
|
31
|
+
Provides-Extra: biomedical
|
|
32
|
+
Requires-Dist: scikit-learn>=1.2; extra == "biomedical"
|
|
33
|
+
Provides-Extra: dev
|
|
34
|
+
Requires-Dist: build>=1.2; extra == "dev"
|
|
35
|
+
Requires-Dist: pytest>=7.4; extra == "dev"
|
|
36
|
+
Requires-Dist: scikit-learn>=1.2; extra == "dev"
|
|
37
|
+
Requires-Dist: twine>=6.1; extra == "dev"
|
|
38
|
+
Dynamic: license-file
|
|
39
|
+
|
|
40
|
+
# catgen
|
|
41
|
+
|
|
42
|
+
**catgen** is a Python library for generating synthetic datasets for machine learning benchmarks. It provides a consistent `(X, y)` interface across a wide range of dataset types: boolean concepts, geometric boundaries, SNP genetics, multiplexer functions, epistasis models, and more.
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install catgen
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Quick Start
|
|
51
|
+
|
|
52
|
+
All generators return `(X, y)` NumPy tuples and accept a `random_state` parameter:
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from catgen import (
|
|
56
|
+
generate_xor_parity_dataset,
|
|
57
|
+
generate_checkerboard_dataset,
|
|
58
|
+
generate_multiplexer_dataset,
|
|
59
|
+
generate_snp_glm_dataset,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
X, y = generate_xor_parity_dataset(n_samples=500, n_bits=6, random_state=0)
|
|
63
|
+
X, y = generate_checkerboard_dataset(n_samples=500, random_state=0)
|
|
64
|
+
X, y = generate_multiplexer_dataset(n_address_bits=3, random_state=0)
|
|
65
|
+
X, y = generate_snp_glm_dataset(n_obs=500, n_snp=20, random_state=0)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Dataset Generators
|
|
69
|
+
|
|
70
|
+
### Boolean Concepts
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from catgen import (
|
|
74
|
+
generate_xor_parity_dataset,
|
|
75
|
+
generate_dnf_concept_dataset,
|
|
76
|
+
generate_monk1_dataset,
|
|
77
|
+
generate_monk3_dataset,
|
|
78
|
+
generate_overlapping_rules_dataset,
|
|
79
|
+
generate_modular_sum_dataset,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# XOR / k-bit parity
|
|
83
|
+
X, y = generate_xor_parity_dataset(n_samples=1000, n_bits=6, random_state=0)
|
|
84
|
+
|
|
85
|
+
# Disjunctive normal form
|
|
86
|
+
X, y = generate_dnf_concept_dataset(n_samples=1000, random_state=0)
|
|
87
|
+
|
|
88
|
+
# MONK benchmarks
|
|
89
|
+
X, y = generate_monk1_dataset()
|
|
90
|
+
X, y = generate_monk3_dataset()
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Geometric Boundaries
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
from catgen import (
|
|
97
|
+
generate_checkerboard_dataset,
|
|
98
|
+
generate_circle_boundary_dataset,
|
|
99
|
+
generate_diagonal_boundary_dataset,
|
|
100
|
+
generate_spiral_dataset,
|
|
101
|
+
generate_concentric_rings_dataset,
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
X, y = generate_checkerboard_dataset(n_samples=1000, random_state=0)
|
|
105
|
+
X, y = generate_spiral_dataset(n_samples=1000, random_state=0)
|
|
106
|
+
X, y = generate_concentric_rings_dataset(n_samples=1000, random_state=0)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### k-Multiplexer
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
from catgen import generate_multiplexer_dataset
|
|
113
|
+
|
|
114
|
+
# 2 address bits + 4 data bits = 6 features, 64 instances (full enumeration)
|
|
115
|
+
X, y = generate_multiplexer_dataset(n_address_bits=2)
|
|
116
|
+
|
|
117
|
+
# 3 address bits + 8 data bits = 11 features, 2048 instances
|
|
118
|
+
X, y = generate_multiplexer_dataset(n_address_bits=3)
|
|
119
|
+
|
|
120
|
+
# 4 address bits: 2^20 instances – cap with max_samples
|
|
121
|
+
X, y = generate_multiplexer_dataset(n_address_bits=4, max_samples=10_000, random_state=0)
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Biomedical / High-Dimensional
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
from catgen import (
|
|
128
|
+
generate_epistasis_dataset,
|
|
129
|
+
generate_highdim_lowsample_dataset,
|
|
130
|
+
generate_imbalanced_dataset,
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
# Gene-gene interaction (epistasis) simulation
|
|
134
|
+
X, y = generate_epistasis_dataset(n_samples=1000, n_snps=20, random_state=0)
|
|
135
|
+
|
|
136
|
+
# High-dimensional, low-sample-size scenario
|
|
137
|
+
X, y = generate_highdim_lowsample_dataset(n_samples=50, n_features=500, random_state=0)
|
|
138
|
+
|
|
139
|
+
# Class-imbalanced binary classification
|
|
140
|
+
X, y = generate_imbalanced_dataset(n_samples=1000, imbalance_ratio=0.1, random_state=0)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Structured Concepts
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
from catgen import (
|
|
147
|
+
generate_deep_tree_dataset,
|
|
148
|
+
generate_sequential_threshold_dataset,
|
|
149
|
+
generate_hierarchical_interaction_dataset,
|
|
150
|
+
generate_boolean_concept_dataset,
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
X, y = generate_deep_tree_dataset(n_samples=1000, random_state=0)
|
|
154
|
+
X, y = generate_sequential_threshold_dataset(n_samples=1000, random_state=0)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## SNP Genetics Simulation
|
|
158
|
+
|
|
159
|
+
The SNP functions are a Python port of the R package [scrime](https://cran.r-project.org/package=scrime) (Schwender, 2007).
|
|
160
|
+
|
|
161
|
+
### High-level interface (X, y)
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from catgen import generate_snp_glm_dataset, generate_snp_glm_with_covariates_dataset
|
|
165
|
+
|
|
166
|
+
# Returns (X, y) like all other generators
|
|
167
|
+
X, y = generate_snp_glm_dataset(n_obs=1000, n_snp=50, random_state=42)
|
|
168
|
+
print(X.shape) # (1000, 50)
|
|
169
|
+
print(y.shape) # (1000,)
|
|
170
|
+
|
|
171
|
+
# With continuous covariates: X has shape (n_obs, n_snp + n_covariates)
|
|
172
|
+
X, y = generate_snp_glm_with_covariates_dataset(
|
|
173
|
+
n_obs=1000, n_snp=50, n_covariates=3, random_state=42
|
|
174
|
+
)
|
|
175
|
+
print(X.shape) # (1000, 53)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Low-level interface (full metadata)
|
|
179
|
+
|
|
180
|
+
Use `simulate_snp_glm` when you need genotype details, MAF arrays, or
|
|
181
|
+
interaction descriptions beyond the `(X, y)` tuple:
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
from catgen import simulate_snp_glm
|
|
185
|
+
|
|
186
|
+
sim = simulate_snp_glm(n_obs=1000, n_snp=50, random_state=42)
|
|
187
|
+
|
|
188
|
+
print(sim.x.shape) # (1000, 50) – genotype matrix, coded 0/1/2
|
|
189
|
+
print(sim.y.shape) # (1000,) – binary response
|
|
190
|
+
print(sim.ia) # interaction descriptions
|
|
191
|
+
print(sim.maf) # per-SNP minor allele frequencies
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Custom interactions and per-SNP minor allele frequencies:
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
list_ia = [[-2, 1], [3]] # (SNP4 != 2) & (SNP3 == 1) and (SNP5 == 3)
|
|
198
|
+
list_snp = [[4, 3], [5]]
|
|
199
|
+
|
|
200
|
+
sim = simulate_snp_glm(
|
|
201
|
+
n_obs=600,
|
|
202
|
+
n_snp=25,
|
|
203
|
+
list_ia=list_ia,
|
|
204
|
+
list_snp=list_snp,
|
|
205
|
+
maf=(0.1, 0.4), # random MAFs drawn from Uniform(0.1, 0.4)
|
|
206
|
+
random_state=0,
|
|
207
|
+
)
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
With continuous covariates:
|
|
211
|
+
|
|
212
|
+
```python
|
|
213
|
+
from catgen import simulate_snp_glm_with_covariates
|
|
214
|
+
|
|
215
|
+
sim = simulate_snp_glm_with_covariates(
|
|
216
|
+
n_obs=2000,
|
|
217
|
+
n_snp=50,
|
|
218
|
+
list_ia=[-1, -1, [-1, -1]],
|
|
219
|
+
list_snp=[1, 2, [1, 4]],
|
|
220
|
+
covariate_mean=[20.0, 20.0],
|
|
221
|
+
covariate_cov=[[10.0, 5.0], [5.0, 10.0]],
|
|
222
|
+
covariate_beta=[0.2, 0.0],
|
|
223
|
+
covariate_interaction_ia=[-1],
|
|
224
|
+
covariate_interaction_snp=[2],
|
|
225
|
+
covariate_interaction_index=[2],
|
|
226
|
+
covariate_interaction_beta=[0.8],
|
|
227
|
+
random_state=1,
|
|
228
|
+
)
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Genotype coding
|
|
232
|
+
|
|
233
|
+
`catgen` uses **0/1/2** coding (numpy convention):
|
|
234
|
+
|
|
235
|
+
| Code | Genotype |
|
|
236
|
+
|------|----------|
|
|
237
|
+
| 0 | Homozygous reference (AA) |
|
|
238
|
+
| 1 | Heterozygous (Aa) |
|
|
239
|
+
| 2 | Homozygous variant (aa) |
|
|
240
|
+
|
|
241
|
+
The `list_ia` parameter uses scrime's **1/2/3** convention to stay compatible
|
|
242
|
+
with the original R API.
|
|
243
|
+
|
|
244
|
+
### SNP simulation parameters
|
|
245
|
+
|
|
246
|
+
`simulate_snp_glm` parameters:
|
|
247
|
+
|
|
248
|
+
| Parameter | Description |
|
|
249
|
+
|-----------|-------------|
|
|
250
|
+
| `n_obs` | Number of observations. |
|
|
251
|
+
| `n_snp` | Number of SNPs to simulate. |
|
|
252
|
+
| `list_ia` | Term specification in scrime coding: scalar (main effect) or list (interaction). 1=AA, 2=Aa, 3=aa, negative = NOT. |
|
|
253
|
+
| `list_snp` | 1-based SNP indices for each term in `list_ia`. |
|
|
254
|
+
| `beta0` | Logistic model intercept (default: −0.5). |
|
|
255
|
+
| `beta` | Regression coefficient(s) per interaction term (default: 1.5). |
|
|
256
|
+
| `maf` | Minor allele frequency: scalar, `(min, max)` range tuple, or per-SNP array. |
|
|
257
|
+
| `sample_y` | Sample y from Bernoulli(prob) if `True`; threshold by `p_cutoff` if `False`. |
|
|
258
|
+
| `p_cutoff` | Probability cutoff when `sample_y=False`. |
|
|
259
|
+
| `random_state` | Integer seed for reproducibility. |
|
|
260
|
+
|
|
261
|
+
`SimSNPGlm` return fields:
|
|
262
|
+
|
|
263
|
+
| Field | Description |
|
|
264
|
+
|-------|-------------|
|
|
265
|
+
| `x` | `(n_obs, n_snp)` int8 genotype matrix, coded 0/1/2. |
|
|
266
|
+
| `y` | `(n_obs,)` int8 binary response array. |
|
|
267
|
+
| `beta0` | Intercept used. |
|
|
268
|
+
| `beta` | Coefficient array. |
|
|
269
|
+
| `ia` | List of interaction description strings. |
|
|
270
|
+
| `maf` | `(n_snp,)` array of minor allele frequencies. |
|
|
271
|
+
| `prob` | `(n_obs,)` predicted case probabilities. |
|
|
272
|
+
|
|
273
|
+
## Background
|
|
274
|
+
|
|
275
|
+
The SNP simulation model follows Nunkesser et al. (2007) and Schwender (2007).
|
|
276
|
+
Each SNP is simulated independently under Hardy-Weinberg equilibrium. The binary
|
|
277
|
+
response is generated from the logistic model:
|
|
278
|
+
|
|
279
|
+
$$\text{logit}(P(Y=1)) = \beta_0 + \beta_1 L_1 + \beta_2 L_2 + \ldots$$
|
|
280
|
+
|
|
281
|
+
where each $L_k$ is a Boolean interaction term.
|
|
282
|
+
|
|
283
|
+
## References
|
|
284
|
+
|
|
285
|
+
- Schwender, H. (2007). *Statistical Analysis of Genotype and Gene Expression Data.*
|
|
286
|
+
Dissertation, Department of Statistics, University of Dortmund.
|
|
287
|
+
- Nunkesser, R., Bernholt, T., Schwender, H., Ickstadt, K. and Wegener, I. (2007).
|
|
288
|
+
Detecting High-Order Interactions of Single Nucleotide Polymorphisms Using Genetic
|
|
289
|
+
Programming. *Bioinformatics*, 23, 3280–3288.
|
|
290
|
+
|
|
291
|
+
## License
|
|
292
|
+
|
|
293
|
+
MIT
|
catgen-0.1.0/README.md
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# catgen
|
|
2
|
+
|
|
3
|
+
**catgen** is a Python library for generating synthetic datasets for machine learning benchmarks. It provides a consistent `(X, y)` interface across a wide range of dataset types: boolean concepts, geometric boundaries, SNP genetics, multiplexer functions, epistasis models, and more.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install catgen
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
All generators return `(X, y)` NumPy tuples and accept a `random_state` parameter:
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
from catgen import (
|
|
17
|
+
generate_xor_parity_dataset,
|
|
18
|
+
generate_checkerboard_dataset,
|
|
19
|
+
generate_multiplexer_dataset,
|
|
20
|
+
generate_snp_glm_dataset,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
X, y = generate_xor_parity_dataset(n_samples=500, n_bits=6, random_state=0)
|
|
24
|
+
X, y = generate_checkerboard_dataset(n_samples=500, random_state=0)
|
|
25
|
+
X, y = generate_multiplexer_dataset(n_address_bits=3, random_state=0)
|
|
26
|
+
X, y = generate_snp_glm_dataset(n_obs=500, n_snp=20, random_state=0)
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Dataset Generators
|
|
30
|
+
|
|
31
|
+
### Boolean Concepts
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
from catgen import (
|
|
35
|
+
generate_xor_parity_dataset,
|
|
36
|
+
generate_dnf_concept_dataset,
|
|
37
|
+
generate_monk1_dataset,
|
|
38
|
+
generate_monk3_dataset,
|
|
39
|
+
generate_overlapping_rules_dataset,
|
|
40
|
+
generate_modular_sum_dataset,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
# XOR / k-bit parity
|
|
44
|
+
X, y = generate_xor_parity_dataset(n_samples=1000, n_bits=6, random_state=0)
|
|
45
|
+
|
|
46
|
+
# Disjunctive normal form
|
|
47
|
+
X, y = generate_dnf_concept_dataset(n_samples=1000, random_state=0)
|
|
48
|
+
|
|
49
|
+
# MONK benchmarks
|
|
50
|
+
X, y = generate_monk1_dataset()
|
|
51
|
+
X, y = generate_monk3_dataset()
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Geometric Boundaries
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from catgen import (
|
|
58
|
+
generate_checkerboard_dataset,
|
|
59
|
+
generate_circle_boundary_dataset,
|
|
60
|
+
generate_diagonal_boundary_dataset,
|
|
61
|
+
generate_spiral_dataset,
|
|
62
|
+
generate_concentric_rings_dataset,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
X, y = generate_checkerboard_dataset(n_samples=1000, random_state=0)
|
|
66
|
+
X, y = generate_spiral_dataset(n_samples=1000, random_state=0)
|
|
67
|
+
X, y = generate_concentric_rings_dataset(n_samples=1000, random_state=0)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### k-Multiplexer
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from catgen import generate_multiplexer_dataset
|
|
74
|
+
|
|
75
|
+
# 2 address bits + 4 data bits = 6 features, 64 instances (full enumeration)
|
|
76
|
+
X, y = generate_multiplexer_dataset(n_address_bits=2)
|
|
77
|
+
|
|
78
|
+
# 3 address bits + 8 data bits = 11 features, 2048 instances
|
|
79
|
+
X, y = generate_multiplexer_dataset(n_address_bits=3)
|
|
80
|
+
|
|
81
|
+
# 4 address bits: 2^20 instances – cap with max_samples
|
|
82
|
+
X, y = generate_multiplexer_dataset(n_address_bits=4, max_samples=10_000, random_state=0)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Biomedical / High-Dimensional
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
from catgen import (
|
|
89
|
+
generate_epistasis_dataset,
|
|
90
|
+
generate_highdim_lowsample_dataset,
|
|
91
|
+
generate_imbalanced_dataset,
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
# Gene-gene interaction (epistasis) simulation
|
|
95
|
+
X, y = generate_epistasis_dataset(n_samples=1000, n_snps=20, random_state=0)
|
|
96
|
+
|
|
97
|
+
# High-dimensional, low-sample-size scenario
|
|
98
|
+
X, y = generate_highdim_lowsample_dataset(n_samples=50, n_features=500, random_state=0)
|
|
99
|
+
|
|
100
|
+
# Class-imbalanced binary classification
|
|
101
|
+
X, y = generate_imbalanced_dataset(n_samples=1000, imbalance_ratio=0.1, random_state=0)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Structured Concepts
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
from catgen import (
|
|
108
|
+
generate_deep_tree_dataset,
|
|
109
|
+
generate_sequential_threshold_dataset,
|
|
110
|
+
generate_hierarchical_interaction_dataset,
|
|
111
|
+
generate_boolean_concept_dataset,
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
X, y = generate_deep_tree_dataset(n_samples=1000, random_state=0)
|
|
115
|
+
X, y = generate_sequential_threshold_dataset(n_samples=1000, random_state=0)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## SNP Genetics Simulation
|
|
119
|
+
|
|
120
|
+
The SNP functions are a Python port of the R package [scrime](https://cran.r-project.org/package=scrime) (Schwender, 2007).
|
|
121
|
+
|
|
122
|
+
### High-level interface (X, y)
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from catgen import generate_snp_glm_dataset, generate_snp_glm_with_covariates_dataset
|
|
126
|
+
|
|
127
|
+
# Returns (X, y) like all other generators
|
|
128
|
+
X, y = generate_snp_glm_dataset(n_obs=1000, n_snp=50, random_state=42)
|
|
129
|
+
print(X.shape) # (1000, 50)
|
|
130
|
+
print(y.shape) # (1000,)
|
|
131
|
+
|
|
132
|
+
# With continuous covariates: X has shape (n_obs, n_snp + n_covariates)
|
|
133
|
+
X, y = generate_snp_glm_with_covariates_dataset(
|
|
134
|
+
n_obs=1000, n_snp=50, n_covariates=3, random_state=42
|
|
135
|
+
)
|
|
136
|
+
print(X.shape) # (1000, 53)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Low-level interface (full metadata)
|
|
140
|
+
|
|
141
|
+
Use `simulate_snp_glm` when you need genotype details, MAF arrays, or
|
|
142
|
+
interaction descriptions beyond the `(X, y)` tuple:
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
from catgen import simulate_snp_glm
|
|
146
|
+
|
|
147
|
+
sim = simulate_snp_glm(n_obs=1000, n_snp=50, random_state=42)
|
|
148
|
+
|
|
149
|
+
print(sim.x.shape) # (1000, 50) – genotype matrix, coded 0/1/2
|
|
150
|
+
print(sim.y.shape) # (1000,) – binary response
|
|
151
|
+
print(sim.ia) # interaction descriptions
|
|
152
|
+
print(sim.maf) # per-SNP minor allele frequencies
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Custom interactions and per-SNP minor allele frequencies:
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
list_ia = [[-2, 1], [3]] # (SNP4 != 2) & (SNP3 == 1) and (SNP5 == 3)
|
|
159
|
+
list_snp = [[4, 3], [5]]
|
|
160
|
+
|
|
161
|
+
sim = simulate_snp_glm(
|
|
162
|
+
n_obs=600,
|
|
163
|
+
n_snp=25,
|
|
164
|
+
list_ia=list_ia,
|
|
165
|
+
list_snp=list_snp,
|
|
166
|
+
maf=(0.1, 0.4), # random MAFs drawn from Uniform(0.1, 0.4)
|
|
167
|
+
random_state=0,
|
|
168
|
+
)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
With continuous covariates:
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
from catgen import simulate_snp_glm_with_covariates
|
|
175
|
+
|
|
176
|
+
sim = simulate_snp_glm_with_covariates(
|
|
177
|
+
n_obs=2000,
|
|
178
|
+
n_snp=50,
|
|
179
|
+
list_ia=[-1, -1, [-1, -1]],
|
|
180
|
+
list_snp=[1, 2, [1, 4]],
|
|
181
|
+
covariate_mean=[20.0, 20.0],
|
|
182
|
+
covariate_cov=[[10.0, 5.0], [5.0, 10.0]],
|
|
183
|
+
covariate_beta=[0.2, 0.0],
|
|
184
|
+
covariate_interaction_ia=[-1],
|
|
185
|
+
covariate_interaction_snp=[2],
|
|
186
|
+
covariate_interaction_index=[2],
|
|
187
|
+
covariate_interaction_beta=[0.8],
|
|
188
|
+
random_state=1,
|
|
189
|
+
)
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Genotype coding
|
|
193
|
+
|
|
194
|
+
`catgen` uses **0/1/2** coding (numpy convention):
|
|
195
|
+
|
|
196
|
+
| Code | Genotype |
|
|
197
|
+
|------|----------|
|
|
198
|
+
| 0 | Homozygous reference (AA) |
|
|
199
|
+
| 1 | Heterozygous (Aa) |
|
|
200
|
+
| 2 | Homozygous variant (aa) |
|
|
201
|
+
|
|
202
|
+
The `list_ia` parameter uses scrime's **1/2/3** convention to stay compatible
|
|
203
|
+
with the original R API.
|
|
204
|
+
|
|
205
|
+
### SNP simulation parameters
|
|
206
|
+
|
|
207
|
+
`simulate_snp_glm` parameters:
|
|
208
|
+
|
|
209
|
+
| Parameter | Description |
|
|
210
|
+
|-----------|-------------|
|
|
211
|
+
| `n_obs` | Number of observations. |
|
|
212
|
+
| `n_snp` | Number of SNPs to simulate. |
|
|
213
|
+
| `list_ia` | Term specification in scrime coding: scalar (main effect) or list (interaction). 1=AA, 2=Aa, 3=aa, negative = NOT. |
|
|
214
|
+
| `list_snp` | 1-based SNP indices for each term in `list_ia`. |
|
|
215
|
+
| `beta0` | Logistic model intercept (default: −0.5). |
|
|
216
|
+
| `beta` | Regression coefficient(s) per interaction term (default: 1.5). |
|
|
217
|
+
| `maf` | Minor allele frequency: scalar, `(min, max)` range tuple, or per-SNP array. |
|
|
218
|
+
| `sample_y` | Sample y from Bernoulli(prob) if `True`; threshold by `p_cutoff` if `False`. |
|
|
219
|
+
| `p_cutoff` | Probability cutoff when `sample_y=False`. |
|
|
220
|
+
| `random_state` | Integer seed for reproducibility. |
|
|
221
|
+
|
|
222
|
+
`SimSNPGlm` return fields:
|
|
223
|
+
|
|
224
|
+
| Field | Description |
|
|
225
|
+
|-------|-------------|
|
|
226
|
+
| `x` | `(n_obs, n_snp)` int8 genotype matrix, coded 0/1/2. |
|
|
227
|
+
| `y` | `(n_obs,)` int8 binary response array. |
|
|
228
|
+
| `beta0` | Intercept used. |
|
|
229
|
+
| `beta` | Coefficient array. |
|
|
230
|
+
| `ia` | List of interaction description strings. |
|
|
231
|
+
| `maf` | `(n_snp,)` array of minor allele frequencies. |
|
|
232
|
+
| `prob` | `(n_obs,)` predicted case probabilities. |
|
|
233
|
+
|
|
234
|
+
## Background
|
|
235
|
+
|
|
236
|
+
The SNP simulation model follows Nunkesser et al. (2007) and Schwender (2007).
|
|
237
|
+
Each SNP is simulated independently under Hardy-Weinberg equilibrium. The binary
|
|
238
|
+
response is generated from the logistic model:
|
|
239
|
+
|
|
240
|
+
$$\text{logit}(P(Y=1)) = \beta_0 + \beta_1 L_1 + \beta_2 L_2 + \ldots$$
|
|
241
|
+
|
|
242
|
+
where each $L_k$ is a Boolean interaction term.
|
|
243
|
+
|
|
244
|
+
## References
|
|
245
|
+
|
|
246
|
+
- Schwender, H. (2007). *Statistical Analysis of Genotype and Gene Expression Data.*
|
|
247
|
+
Dissertation, Department of Statistics, University of Dortmund.
|
|
248
|
+
- Nunkesser, R., Bernholt, T., Schwender, H., Ickstadt, K. and Wegener, I. (2007).
|
|
249
|
+
Detecting High-Order Interactions of Single Nucleotide Polymorphisms Using Genetic
|
|
250
|
+
Programming. *Bioinformatics*, 23, 3280–3288.
|
|
251
|
+
|
|
252
|
+
## License
|
|
253
|
+
|
|
254
|
+
MIT
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=69", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "catgen"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Categorical data generator for ML benchmarks: SNP genetics, k-multiplexer, DNF concepts, epistasis, geometric boundaries, and more"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "catgen contributors" }
|
|
14
|
+
]
|
|
15
|
+
keywords = [
|
|
16
|
+
"SNP",
|
|
17
|
+
"genetics",
|
|
18
|
+
"simulation",
|
|
19
|
+
"categorical data",
|
|
20
|
+
"Hardy-Weinberg",
|
|
21
|
+
"logistic regression",
|
|
22
|
+
"high-dimensional data",
|
|
23
|
+
"scrime",
|
|
24
|
+
"multiplexer",
|
|
25
|
+
"boolean concepts",
|
|
26
|
+
"benchmark datasets",
|
|
27
|
+
"epistasis",
|
|
28
|
+
"DNF",
|
|
29
|
+
"machine learning",
|
|
30
|
+
"synthetic data",
|
|
31
|
+
]
|
|
32
|
+
classifiers = [
|
|
33
|
+
"Development Status :: 3 - Alpha",
|
|
34
|
+
"Intended Audience :: Science/Research",
|
|
35
|
+
"Intended Audience :: Developers",
|
|
36
|
+
"Operating System :: OS Independent",
|
|
37
|
+
"Programming Language :: Python :: 3",
|
|
38
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
39
|
+
"Programming Language :: Python :: 3.10",
|
|
40
|
+
"Programming Language :: Python :: 3.11",
|
|
41
|
+
"Programming Language :: Python :: 3.12",
|
|
42
|
+
"Programming Language :: Python :: 3.13",
|
|
43
|
+
"Programming Language :: Python :: 3.14",
|
|
44
|
+
"Topic :: Scientific/Engineering :: Bio-Informatics",
|
|
45
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
46
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
47
|
+
]
|
|
48
|
+
dependencies = [
|
|
49
|
+
"numpy>=1.23",
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
[project.urls]
|
|
53
|
+
Homepage = "https://github.com/Italbytz/pypi-catgen"
|
|
54
|
+
Documentation = "https://github.com/Italbytz/pypi-catgen#readme"
|
|
55
|
+
Source = "https://github.com/Italbytz/pypi-catgen"
|
|
56
|
+
Changelog = "https://github.com/Italbytz/pypi-catgen/releases"
|
|
57
|
+
"Bug Tracker" = "https://github.com/Italbytz/pypi-catgen/issues"
|
|
58
|
+
|
|
59
|
+
[project.optional-dependencies]
|
|
60
|
+
biomedical = [
|
|
61
|
+
"scikit-learn>=1.2",
|
|
62
|
+
]
|
|
63
|
+
dev = [
|
|
64
|
+
"build>=1.2",
|
|
65
|
+
"pytest>=7.4",
|
|
66
|
+
"scikit-learn>=1.2",
|
|
67
|
+
"twine>=6.1",
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
[tool.setuptools]
|
|
71
|
+
package-dir = {"" = "src"}
|
|
72
|
+
|
|
73
|
+
[tool.setuptools.packages.find]
|
|
74
|
+
where = ["src"]
|
|
75
|
+
|
|
76
|
+
[tool.pytest.ini_options]
|
|
77
|
+
testpaths = ["tests"]
|
catgen-0.1.0/setup.cfg
ADDED