sdgym 0.16.1.dev0__tar.gz → 0.16.2.dev0__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.
- {sdgym-0.16.1.dev0/sdgym.egg-info → sdgym-0.16.2.dev0}/PKG-INFO +4 -5
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/pyproject.toml +4 -5
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/__init__.py +1 -1
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/_benchmark/credentials_utils.py +1 -1
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/_dataset_utils.py +8 -8
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/benchmark.py +18 -31
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/datasets.py +20 -11
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/synthesizers/base.py +2 -3
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/synthesizers/column.py +9 -7
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/synthesizers/data_designer.py +7 -5
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/synthesizers/realtabformer.py +5 -2
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/synthesizers/sdv.py +1 -1
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/synthesizers/tabddpm.py +5 -2
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/synthesizers/uniform.py +14 -10
- sdgym-0.16.2.dev0/sdgym/synthesizers/utils.py +84 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/utils.py +17 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0/sdgym.egg-info}/PKG-INFO +4 -5
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym.egg-info/requires.txt +3 -4
- sdgym-0.16.1.dev0/sdgym/synthesizers/utils.py +0 -37
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/LICENSE +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/README.md +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/_benchmark/__init__.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/_benchmark/benchmark.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/_benchmark_launcher/__init__.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/_benchmark_launcher/_instance_manager.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/_benchmark_launcher/_storage_manager.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/_benchmark_launcher/_validation.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/_benchmark_launcher/benchmark_base.yaml +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/_benchmark_launcher/benchmark_config.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/_benchmark_launcher/benchmark_launcher.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/_benchmark_launcher/script.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/_benchmark_launcher/utils.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/cli/__init__.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/cli/__main__.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/cli/collect.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/cli/summary.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/cli/utils.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/dataset_explorer.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/errors.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/metrics.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/progress.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/result_explorer/__init__.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/result_explorer/result_explorer.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/result_explorer/result_handler.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/result_writer.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/run_benchmark/__init__.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/run_benchmark/run_benchmark.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/run_benchmark/upload_benchmark_results.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/run_benchmark/utils.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/s3.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/synthesizer_descriptions.yaml +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/synthesizers/__init__.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/synthesizers/clavaddpm.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/synthesizers/generate.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym/synthesizers/identity.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym.egg-info/SOURCES.txt +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym.egg-info/dependency_links.txt +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym.egg-info/entry_points.txt +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/sdgym.egg-info/top_level.txt +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/setup.cfg +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/tests/test_scripts.py +0 -0
- {sdgym-0.16.1.dev0 → sdgym-0.16.2.dev0}/tests/test_tasks.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sdgym
|
|
3
|
-
Version: 0.16.
|
|
3
|
+
Version: 0.16.2.dev0
|
|
4
4
|
Summary: Benchmark tabular synthetic data generators using a variety of datasets
|
|
5
5
|
Author-email: "DataCebo, Inc." <info@sdv.dev>
|
|
6
6
|
License-Expression: BUSL-1.1
|
|
@@ -63,10 +63,9 @@ Requires-Dist: torch>=2.6.0; python_version >= "3.13" and python_version < "3.14
|
|
|
63
63
|
Requires-Dist: torch>=2.9.0; python_version >= "3.14"
|
|
64
64
|
Requires-Dist: tqdm>=4.66.3
|
|
65
65
|
Requires-Dist: XlsxWriter>=1.2.8
|
|
66
|
-
Requires-Dist:
|
|
67
|
-
Requires-Dist: rdt<2
|
|
68
|
-
Requires-Dist:
|
|
69
|
-
Requires-Dist: sdv<2,>=1.37.0
|
|
66
|
+
Requires-Dist: sdmetrics>=0.32.0
|
|
67
|
+
Requires-Dist: rdt<3,>=2.0.0
|
|
68
|
+
Requires-Dist: sdv<3,>=2.0.0
|
|
70
69
|
Provides-Extra: dask
|
|
71
70
|
Requires-Dist: dask; extra == "dask"
|
|
72
71
|
Requires-Dist: distributed; extra == "dask"
|
|
@@ -61,10 +61,9 @@ dependencies = [
|
|
|
61
61
|
"torch>=2.9.0;python_version>='3.14'",
|
|
62
62
|
'tqdm>=4.66.3',
|
|
63
63
|
'XlsxWriter>=1.2.8',
|
|
64
|
-
"
|
|
65
|
-
"rdt>=
|
|
66
|
-
"
|
|
67
|
-
"sdv>=1.37.0,<2",
|
|
64
|
+
"sdmetrics>=0.32.0",
|
|
65
|
+
"rdt>=2.0.0,<3",
|
|
66
|
+
"sdv>=2.0.0,<3",
|
|
68
67
|
]
|
|
69
68
|
|
|
70
69
|
[project.urls]
|
|
@@ -177,7 +176,7 @@ namespaces = false
|
|
|
177
176
|
version = {attr = 'sdgym.__version__'}
|
|
178
177
|
|
|
179
178
|
[tool.bumpversion]
|
|
180
|
-
current_version = "0.16.
|
|
179
|
+
current_version = "0.16.2.dev0"
|
|
181
180
|
parse = '(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\.(?P<release>[a-z]+)(?P<candidate>\d+))?'
|
|
182
181
|
serialize = [
|
|
183
182
|
'{major}.{minor}.{patch}.{release}{candidate}',
|
|
@@ -13,5 +13,5 @@ def sdv_install_cmd(credentials):
|
|
|
13
13
|
pip install sdv-installer
|
|
14
14
|
|
|
15
15
|
python -c "from sdv_installer.installation.installer import install_packages; \\
|
|
16
|
-
install_packages(username='{username}', license_key='{license_key}'
|
|
16
|
+
install_packages(username='{username}', license_key='{license_key}')"
|
|
17
17
|
""")
|
|
@@ -8,7 +8,7 @@ from zipfile import ZipFile
|
|
|
8
8
|
import numpy as np
|
|
9
9
|
import pandas as pd
|
|
10
10
|
from sdv.metadata import Metadata
|
|
11
|
-
from sdv.utils import
|
|
11
|
+
from sdv.utils import get_random_subset
|
|
12
12
|
|
|
13
13
|
LOGGER = logging.getLogger(__name__)
|
|
14
14
|
|
|
@@ -77,7 +77,7 @@ def _get_multi_table_dataset_subset(data, metadata_dict):
|
|
|
77
77
|
data[table_name] = data[table_name][list(table.columns)]
|
|
78
78
|
|
|
79
79
|
# Subsample the data mantaining the referential integrity
|
|
80
|
-
data =
|
|
80
|
+
data = get_random_subset(
|
|
81
81
|
data=data,
|
|
82
82
|
metadata=metadata,
|
|
83
83
|
main_table_name=largest_table_name,
|
|
@@ -122,9 +122,12 @@ def _get_dataset_subset(data, metadata_dict, modality):
|
|
|
122
122
|
filtered = _filter_columns(columns=columns, mandatory_columns=mandatory_columns)
|
|
123
123
|
|
|
124
124
|
table_info['columns'] = filtered
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
125
|
+
is_dict = isinstance(data, dict)
|
|
126
|
+
table_data = data[table_name] if is_dict else data
|
|
127
|
+
table_data = table_data[list(filtered)]
|
|
128
|
+
max_rows = min(MAX_NUM_ROWS, len(table_data))
|
|
129
|
+
table_data = table_data.sample(max_rows)
|
|
130
|
+
data = {table_name: table_data} if is_dict else table_data
|
|
128
131
|
|
|
129
132
|
return data, metadata_dict
|
|
130
133
|
|
|
@@ -137,9 +140,6 @@ def _read_zipped_data(zip_file_path, modality):
|
|
|
137
140
|
key = Path(file_name).stem
|
|
138
141
|
data[key] = _read_csv_from_zip(zf, csv_file_name=file_name)
|
|
139
142
|
|
|
140
|
-
if modality != 'multi_table':
|
|
141
|
-
data = next(iter(data.values()))
|
|
142
|
-
|
|
143
143
|
return data
|
|
144
144
|
|
|
145
145
|
|
|
@@ -25,18 +25,7 @@ import pandas as pd
|
|
|
25
25
|
import tqdm
|
|
26
26
|
import yaml
|
|
27
27
|
from botocore.config import Config
|
|
28
|
-
from sdmetrics.reports
|
|
29
|
-
DiagnosticReport as MultiTableDiagnosticReport,
|
|
30
|
-
)
|
|
31
|
-
from sdmetrics.reports.multi_table import (
|
|
32
|
-
QualityReport as MultiTableQualityReport,
|
|
33
|
-
)
|
|
34
|
-
from sdmetrics.reports.single_table import (
|
|
35
|
-
DiagnosticReport as SingleTableDiagnosticReport,
|
|
36
|
-
)
|
|
37
|
-
from sdmetrics.reports.single_table import (
|
|
38
|
-
QualityReport as SingleTableQualityReport,
|
|
39
|
-
)
|
|
28
|
+
from sdmetrics.reports import DiagnosticReport, QualityReport
|
|
40
29
|
from sdmetrics.single_table import DCRBaselineProtection
|
|
41
30
|
|
|
42
31
|
from sdgym.datasets import (
|
|
@@ -60,6 +49,7 @@ from sdgym.s3 import (
|
|
|
60
49
|
from sdgym.synthesizers import MultiTableUniformSynthesizer, UniformSynthesizer
|
|
61
50
|
from sdgym.synthesizers.base import BaselineSynthesizer
|
|
62
51
|
from sdgym.utils import (
|
|
52
|
+
_get_single_table_dataframe,
|
|
63
53
|
calculate_score_time,
|
|
64
54
|
convert_metadata_to_sdmetrics,
|
|
65
55
|
format_exception,
|
|
@@ -515,7 +505,8 @@ def _synthesize(
|
|
|
515
505
|
if modality == 'multi_table':
|
|
516
506
|
synthetic_data = sample_from_synthesizer(fitted_synthesizer, 1.0)
|
|
517
507
|
else:
|
|
518
|
-
|
|
508
|
+
num_rows = len(_get_single_table_dataframe(data))
|
|
509
|
+
synthetic_data = sample_from_synthesizer(fitted_synthesizer, n_samples=num_rows)
|
|
519
510
|
|
|
520
511
|
sample_end = get_utc_now()
|
|
521
512
|
sample_time = sample_end - train_end
|
|
@@ -530,9 +521,9 @@ def _synthesize(
|
|
|
530
521
|
result_writer.write_zipped_dataframes(
|
|
531
522
|
synthetic_data, synthesizer_path['synthetic_data']
|
|
532
523
|
)
|
|
533
|
-
|
|
534
524
|
else:
|
|
535
|
-
|
|
525
|
+
synthetic_table = _get_single_table_dataframe(synthetic_data)
|
|
526
|
+
result_writer.write_dataframe(synthetic_table, synthesizer_path['synthetic_data'])
|
|
536
527
|
|
|
537
528
|
return synthetic_data, train_time, sample_time, synthesizer_size, peak_memory
|
|
538
529
|
|
|
@@ -579,8 +570,12 @@ def _compute_scores(
|
|
|
579
570
|
metrics = metrics or []
|
|
580
571
|
if modality == 'single_table':
|
|
581
572
|
sdmetrics_metadata = convert_metadata_to_sdmetrics(metadata)
|
|
573
|
+
sdmetrics_real_data = _get_single_table_dataframe(real_data)
|
|
574
|
+
sdmetrics_synthetic_data = _get_single_table_dataframe(synthetic_data)
|
|
582
575
|
else:
|
|
583
576
|
sdmetrics_metadata = metadata
|
|
577
|
+
sdmetrics_real_data = real_data
|
|
578
|
+
sdmetrics_synthetic_data = synthetic_data
|
|
584
579
|
|
|
585
580
|
if len(metrics) > 0:
|
|
586
581
|
metrics, metric_kwargs = get_metrics(metrics, modality=modality)
|
|
@@ -600,7 +595,7 @@ def _compute_scores(
|
|
|
600
595
|
start = get_utc_now()
|
|
601
596
|
try:
|
|
602
597
|
LOGGER.info('Computing %s on dataset %s', metric_name, dataset_name)
|
|
603
|
-
metric_args = (
|
|
598
|
+
metric_args = (sdmetrics_real_data, sdmetrics_synthetic_data, sdmetrics_metadata)
|
|
604
599
|
score = metric.compute(*metric_args, **metric_kwargs.get(metric_name, {}))
|
|
605
600
|
normalized_score = metric.normalize(score)
|
|
606
601
|
except Exception:
|
|
@@ -620,23 +615,15 @@ def _compute_scores(
|
|
|
620
615
|
|
|
621
616
|
if compute_diagnostic_score:
|
|
622
617
|
start = get_utc_now()
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
else:
|
|
626
|
-
diagnostic_report = MultiTableDiagnosticReport()
|
|
627
|
-
|
|
628
|
-
diagnostic_report.generate(real_data, synthetic_data, sdmetrics_metadata, verbose=False)
|
|
618
|
+
diagnostic_report = DiagnosticReport()
|
|
619
|
+
diagnostic_report.generate(real_data, synthetic_data, metadata, verbose=False)
|
|
629
620
|
output['diagnostic_score_time'] = calculate_score_time(start)
|
|
630
621
|
output['diagnostic_score'] = diagnostic_report.get_score()
|
|
631
622
|
|
|
632
623
|
if compute_quality_score:
|
|
633
624
|
start = get_utc_now()
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
else:
|
|
637
|
-
quality_report = MultiTableQualityReport()
|
|
638
|
-
|
|
639
|
-
quality_report.generate(real_data, synthetic_data, sdmetrics_metadata, verbose=False)
|
|
625
|
+
quality_report = QualityReport()
|
|
626
|
+
quality_report.generate(real_data, synthetic_data, metadata, verbose=False)
|
|
640
627
|
output['quality_score_time'] = calculate_score_time(start)
|
|
641
628
|
output['quality_score'] = quality_report.get_score()
|
|
642
629
|
if synthesizer_path is not None and result_writer is not None:
|
|
@@ -644,7 +631,7 @@ def _compute_scores(
|
|
|
644
631
|
|
|
645
632
|
if compute_privacy_score:
|
|
646
633
|
start = get_utc_now()
|
|
647
|
-
num_rows = len(
|
|
634
|
+
num_rows = len(sdmetrics_synthetic_data)
|
|
648
635
|
# parameters were determined by running experiments with all datasets
|
|
649
636
|
# and tweaking num_rows_subsample and num_iterations until
|
|
650
637
|
# absolute difference from real score was close (while keeping runtime low)
|
|
@@ -652,8 +639,8 @@ def _compute_scores(
|
|
|
652
639
|
num_rows_subsample = math.floor(num_rows * 0.60)
|
|
653
640
|
num_iterations = 2
|
|
654
641
|
score = DCRBaselineProtection.compute_breakdown(
|
|
655
|
-
real_data=
|
|
656
|
-
synthetic_data=
|
|
642
|
+
real_data=sdmetrics_real_data,
|
|
643
|
+
synthetic_data=sdmetrics_synthetic_data,
|
|
657
644
|
table_name=dataset_name,
|
|
658
645
|
metadata=sdmetrics_metadata,
|
|
659
646
|
num_rows_subsample=num_rows_subsample,
|
|
@@ -12,12 +12,13 @@ import pandas as pd
|
|
|
12
12
|
from sdv.datasets.demo import (
|
|
13
13
|
_find_data_zip_key,
|
|
14
14
|
_get_data_from_bucket,
|
|
15
|
-
|
|
15
|
+
_get_first_v2_metadata_bytes,
|
|
16
16
|
_get_metadata,
|
|
17
17
|
_list_objects,
|
|
18
18
|
_load_data_from_zip,
|
|
19
19
|
download_demo,
|
|
20
20
|
)
|
|
21
|
+
from sdv.metadata import Metadata
|
|
21
22
|
|
|
22
23
|
from sdgym._dataset_utils import (
|
|
23
24
|
_get_dataset_subset,
|
|
@@ -178,24 +179,35 @@ def get_data_and_metadata_from_path(dataset_path, modality):
|
|
|
178
179
|
interpret and load the dataset (e.g., ``'single_table'``, ``'multi_table'``).
|
|
179
180
|
|
|
180
181
|
Returns:
|
|
181
|
-
tuple[
|
|
182
|
+
tuple[dict | None, dict | None]:
|
|
182
183
|
A tuple containing:
|
|
183
|
-
- The loaded dataset as a
|
|
184
|
-
``pandas.DataFrame
|
|
185
|
-
|
|
184
|
+
- The loaded dataset as a dictionary mapping table name to
|
|
185
|
+
``pandas.DataFrame``.
|
|
186
|
+
- The dataset metadata as a dictionary.
|
|
186
187
|
"""
|
|
187
188
|
metadata_dict = None
|
|
188
189
|
data = None
|
|
189
190
|
for file_name in dataset_path.iterdir():
|
|
190
191
|
is_metadata = 'metadata' in file_name.stem and file_name.suffix == '.json'
|
|
191
|
-
if (is_metadata and metadata_dict is None) or file_name.name == '
|
|
192
|
+
if (is_metadata and metadata_dict is None) or file_name.name == 'metadata_v2.json':
|
|
192
193
|
metadata_dict = _read_metadata_json(file_name)
|
|
193
194
|
elif 'data' in file_name.stem and file_name.suffix == '.zip':
|
|
194
195
|
data = _read_zipped_data(zip_file_path=(file_name), modality=modality)
|
|
195
196
|
|
|
197
|
+
if modality == 'single_table' and data is not None:
|
|
198
|
+
data = _set_single_table_as_dict(data, metadata_dict)
|
|
199
|
+
|
|
196
200
|
return data, metadata_dict
|
|
197
201
|
|
|
198
202
|
|
|
203
|
+
def _set_single_table_as_dict(data, metadata_dict):
|
|
204
|
+
if isinstance(data, dict):
|
|
205
|
+
return data
|
|
206
|
+
|
|
207
|
+
table_name = Metadata.load_from_dict(metadata_dict)._get_single_table_name()
|
|
208
|
+
return {table_name: data}
|
|
209
|
+
|
|
210
|
+
|
|
199
211
|
def _genereate_dataset_info(s3_client, bucket_name, contents):
|
|
200
212
|
"""Generate summarized dataset information from S3 bucket.
|
|
201
213
|
|
|
@@ -302,13 +314,10 @@ def _load_private_sdv_demo_dataset(modality, dataset_name, bucket, s3_client=Non
|
|
|
302
314
|
contents = _list_objects(dataset_prefix, bucket=bucket_name, client=s3_client)
|
|
303
315
|
data_key = _find_data_zip_key(contents, dataset_prefix, bucket_name)
|
|
304
316
|
data_bytes = io.BytesIO(_get_data_from_bucket(data_key, bucket=bucket_name, client=s3_client))
|
|
305
|
-
metadata_bytes =
|
|
317
|
+
metadata_bytes = _get_first_v2_metadata_bytes(
|
|
306
318
|
contents, dataset_prefix, bucket=bucket_name, client=s3_client
|
|
307
319
|
)
|
|
308
320
|
data = _load_data_from_zip(data_bytes, bucket_name, dataset_name)
|
|
309
|
-
if modality != 'multi_table':
|
|
310
|
-
data = data.popitem()[1]
|
|
311
|
-
|
|
312
321
|
metadata = _get_metadata(metadata_bytes, dataset_name)
|
|
313
322
|
return data, metadata.to_dict()
|
|
314
323
|
|
|
@@ -378,7 +387,7 @@ def load_dataset(
|
|
|
378
387
|
columns. Defauts to ``False``.
|
|
379
388
|
|
|
380
389
|
Returns:
|
|
381
|
-
pd.DataFrame
|
|
390
|
+
tuple (dict[str, pd.DataFrame], dict):
|
|
382
391
|
The data and medatata for a dataset.
|
|
383
392
|
"""
|
|
384
393
|
s3_client = get_s3_client(
|
|
@@ -129,9 +129,8 @@ class BaselineSynthesizer(abc.ABC):
|
|
|
129
129
|
The number of samples to create.
|
|
130
130
|
|
|
131
131
|
Returns:
|
|
132
|
-
pandas.DataFrame
|
|
133
|
-
The sampled data
|
|
134
|
-
should be a dict mapping table name to DataFrame.
|
|
132
|
+
dict[str, pandas.DataFrame]:
|
|
133
|
+
The sampled data mapping table name to DataFrame.
|
|
135
134
|
"""
|
|
136
135
|
return self._sample_from_synthesizer(synthesizer, n_samples)
|
|
137
136
|
|
|
@@ -8,6 +8,7 @@ from sdv.metadata import Metadata
|
|
|
8
8
|
from sklearn.mixture import GaussianMixture
|
|
9
9
|
|
|
10
10
|
from sdgym.synthesizers.base import BaselineSynthesizer
|
|
11
|
+
from sdgym.synthesizers.utils import _get_single_table_name_and_dataframe
|
|
11
12
|
|
|
12
13
|
LOGGER = logging.getLogger(__name__)
|
|
13
14
|
|
|
@@ -22,12 +23,12 @@ class ColumnSynthesizer(BaselineSynthesizer):
|
|
|
22
23
|
_MODALITY_FLAG = 'single_table'
|
|
23
24
|
|
|
24
25
|
def _fit(self, data, metadata):
|
|
26
|
+
table_name, table_data = _get_single_table_name_and_dataframe(data, metadata)
|
|
25
27
|
hyper_transformer = HyperTransformer()
|
|
26
|
-
hyper_transformer.detect_initial_config(
|
|
28
|
+
hyper_transformer.detect_initial_config(table_data)
|
|
27
29
|
supported_sdtypes = hyper_transformer._get_supported_sdtypes()
|
|
28
30
|
config = {}
|
|
29
31
|
if isinstance(metadata, Metadata):
|
|
30
|
-
table_name = metadata._get_single_table_name()
|
|
31
32
|
columns = metadata.tables[table_name].columns
|
|
32
33
|
else:
|
|
33
34
|
columns = metadata.columns
|
|
@@ -48,14 +49,14 @@ class ColumnSynthesizer(BaselineSynthesizer):
|
|
|
48
49
|
|
|
49
50
|
# This is done to match the behavior of the synthesizer for SDGym <= 0.6.0
|
|
50
51
|
columns_to_remove = [
|
|
51
|
-
column_name for column_name, data in
|
|
52
|
+
column_name for column_name, data in table_data.items() if data.dtype.kind in {'O', 'i'}
|
|
52
53
|
]
|
|
53
54
|
hyper_transformer.remove_transformers(columns_to_remove)
|
|
54
55
|
|
|
55
|
-
hyper_transformer.fit(
|
|
56
|
-
transformed = hyper_transformer.transform(
|
|
56
|
+
hyper_transformer.fit(table_data)
|
|
57
|
+
transformed = hyper_transformer.transform(table_data)
|
|
57
58
|
|
|
58
|
-
self.length = len(
|
|
59
|
+
self.length = len(table_data)
|
|
59
60
|
gm_models = {}
|
|
60
61
|
for name, column in transformed.items():
|
|
61
62
|
kind = column.dtype.kind
|
|
@@ -68,6 +69,7 @@ class ColumnSynthesizer(BaselineSynthesizer):
|
|
|
68
69
|
self.hyper_transformer = hyper_transformer
|
|
69
70
|
self.transformed_data = transformed
|
|
70
71
|
self.gm_models = gm_models
|
|
72
|
+
self._table_name = table_name
|
|
71
73
|
|
|
72
74
|
def _sample_from_synthesizer(self, synthesizer, n_samples):
|
|
73
75
|
hyper_transformer = synthesizer.hyper_transformer
|
|
@@ -84,4 +86,4 @@ class ColumnSynthesizer(BaselineSynthesizer):
|
|
|
84
86
|
|
|
85
87
|
sampled[name] = values
|
|
86
88
|
|
|
87
|
-
return hyper_transformer.reverse_transform(sampled)
|
|
89
|
+
return {synthesizer._table_name: hyper_transformer.reverse_transform(sampled)}
|
|
@@ -306,14 +306,16 @@ class DataDesignerSynthesizer(BaselineSynthesizer):
|
|
|
306
306
|
_MODALITY_FLAG = 'single_table'
|
|
307
307
|
|
|
308
308
|
def _fit(self, data, metadata):
|
|
309
|
-
table_name = metadata._get_single_table_name()
|
|
310
309
|
metadata.validate()
|
|
311
|
-
metadata.validate_data(
|
|
310
|
+
metadata.validate_data(data)
|
|
312
311
|
|
|
312
|
+
table_name = metadata._get_single_table_name()
|
|
313
|
+
table_data = data[table_name]
|
|
313
314
|
model_kwargs = self._MODEL_KWARGS.copy() if self._MODEL_KWARGS else {}
|
|
314
315
|
self._artifact_path = model_kwargs.pop('artifact_path', None)
|
|
315
316
|
self._cleanup_artifacts = model_kwargs.pop('cleanup_artifacts', True)
|
|
316
|
-
self._config_builder = create_data_designer_config(
|
|
317
|
+
self._config_builder = create_data_designer_config(table_data, metadata, **model_kwargs)
|
|
318
|
+
self._table_name = table_name
|
|
317
319
|
|
|
318
320
|
def _sample_from_synthesizer(self, synthesizer, n_sample):
|
|
319
321
|
"""Sample synthetic data with specified sample count."""
|
|
@@ -332,12 +334,12 @@ class DataDesignerSynthesizer(BaselineSynthesizer):
|
|
|
332
334
|
artifact_path = Path(synthesizer._artifact_path)
|
|
333
335
|
|
|
334
336
|
# A unique name keeps concurrent or repeated sample calls from sharing a folder.
|
|
335
|
-
dataset_name = f'dataset-{uuid.uuid4().hex}'
|
|
337
|
+
dataset_name = f'dataset-{synthesizer._table_name}-{uuid.uuid4().hex}'
|
|
336
338
|
try:
|
|
337
339
|
output = DataDesigner(artifact_path=artifact_path).create(
|
|
338
340
|
synthesizer._config_builder, num_records=n_sample, dataset_name=dataset_name
|
|
339
341
|
)
|
|
340
|
-
return output.load_dataset()
|
|
342
|
+
return {synthesizer._table_name: output.load_dataset()}
|
|
341
343
|
finally:
|
|
342
344
|
if synthesizer._cleanup_artifacts:
|
|
343
345
|
to_remove = artifact_path if is_temporary else artifact_path / dataset_name
|
|
@@ -8,6 +8,7 @@ from functools import partialmethod
|
|
|
8
8
|
import tqdm
|
|
9
9
|
|
|
10
10
|
from sdgym.synthesizers.base import BaselineSynthesizer
|
|
11
|
+
from sdgym.synthesizers.utils import _get_single_table_name_and_dataframe
|
|
11
12
|
|
|
12
13
|
REMOVED_TRAINING_ARGS = ('overwrite_output_dir',)
|
|
13
14
|
|
|
@@ -49,14 +50,16 @@ class RealTabFormerSynthesizer(BaselineSynthesizer):
|
|
|
49
50
|
" dependencies by running pip install sdgym['realtabformer'] "
|
|
50
51
|
) from exception
|
|
51
52
|
|
|
53
|
+
table_name, table_data = _get_single_table_name_and_dataframe(data, metadata)
|
|
52
54
|
with prevent_tqdm_output():
|
|
53
55
|
model_kwargs = self._MODEL_KWARGS.copy() if self._MODEL_KWARGS else {}
|
|
54
56
|
model = REaLTabFormer(model_type='tabular', **model_kwargs)
|
|
55
57
|
_remove_unsupported_training_args(model)
|
|
56
|
-
model.fit(
|
|
58
|
+
model.fit(table_data)
|
|
57
59
|
|
|
58
60
|
self._internal_synthesizer = model
|
|
61
|
+
self._table_name = table_name
|
|
59
62
|
|
|
60
63
|
def _sample_from_synthesizer(self, synthesizer, n_sample):
|
|
61
64
|
"""Sample synthetic data with specified sample count."""
|
|
62
|
-
return synthesizer._internal_synthesizer.sample(n_sample)
|
|
65
|
+
return {synthesizer._table_name: synthesizer._internal_synthesizer.sample(n_sample)}
|
|
@@ -50,7 +50,7 @@ def _fit(self, data, metadata):
|
|
|
50
50
|
def _sample_from_synthesizer(self, synthesizer, sample_arg):
|
|
51
51
|
LOGGER.info('Sampling %s', self.__class__.__name__)
|
|
52
52
|
if self._MODALITY_FLAG == 'multi_table':
|
|
53
|
-
return synthesizer._internal_synthesizer.
|
|
53
|
+
return synthesizer._internal_synthesizer.sample_scale(scale=sample_arg)
|
|
54
54
|
|
|
55
55
|
return synthesizer._internal_synthesizer.sample(num_rows=sample_arg)
|
|
56
56
|
|
|
@@ -23,6 +23,7 @@ from sklearn.preprocessing import OrdinalEncoder, QuantileTransformer
|
|
|
23
23
|
from torch import Tensor
|
|
24
24
|
|
|
25
25
|
from sdgym.synthesizers.base import BaselineSynthesizer
|
|
26
|
+
from sdgym.synthesizers.utils import _get_single_table_name_and_dataframe
|
|
26
27
|
|
|
27
28
|
CAT_MISSING_VALUE = '__nan__'
|
|
28
29
|
|
|
@@ -1196,12 +1197,14 @@ class TabDDPMSynthesizer(BaselineSynthesizer):
|
|
|
1196
1197
|
_MODALITY_FLAG = 'single_table'
|
|
1197
1198
|
|
|
1198
1199
|
def _fit(self, data, metadata):
|
|
1200
|
+
table_name, table_data = _get_single_table_name_and_dataframe(data, metadata)
|
|
1199
1201
|
model_kwargs = self._MODEL_KWARGS.copy() if self._MODEL_KWARGS else {}
|
|
1200
1202
|
model = TabDDPM(metadata, **model_kwargs)
|
|
1201
|
-
model.fit(
|
|
1203
|
+
model.fit(table_data)
|
|
1202
1204
|
|
|
1203
1205
|
self._internal_synthesizer = model
|
|
1206
|
+
self._table_name = table_name
|
|
1204
1207
|
|
|
1205
1208
|
def _sample_from_synthesizer(self, synthesizer, n_sample):
|
|
1206
1209
|
"""Sample synthetic data with specified sample count."""
|
|
1207
|
-
return synthesizer._internal_synthesizer.sample(n_sample)
|
|
1210
|
+
return {synthesizer._table_name: synthesizer._internal_synthesizer.sample(n_sample)}
|
|
@@ -8,6 +8,7 @@ import pandas as pd
|
|
|
8
8
|
from rdt.hyper_transformer import HyperTransformer
|
|
9
9
|
|
|
10
10
|
from sdgym.synthesizers.base import BaselineSynthesizer, MultiTableBaselineSynthesizer
|
|
11
|
+
from sdgym.synthesizers.utils import _get_single_table_name_and_dataframe
|
|
11
12
|
|
|
12
13
|
LOGGER = logging.getLogger(__name__)
|
|
13
14
|
|
|
@@ -21,22 +22,24 @@ class UniformSynthesizer(BaselineSynthesizer):
|
|
|
21
22
|
super().__init__()
|
|
22
23
|
self.hyper_transformer = None
|
|
23
24
|
self.transformed_data = None
|
|
25
|
+
self._table_name = None
|
|
24
26
|
|
|
25
27
|
def _fit(self, data, metadata):
|
|
26
28
|
"""Fit the synthesizer to the data.
|
|
27
29
|
|
|
28
30
|
Args:
|
|
29
|
-
data (pd.DataFrame):
|
|
31
|
+
data (dict[str, pd.DataFrame]):
|
|
30
32
|
The data to fit the synthesizer to.
|
|
31
33
|
metadata (sdv.metadata.Metadata):
|
|
32
34
|
The metadata describing the data.
|
|
33
35
|
"""
|
|
36
|
+
table_name, table_data = _get_single_table_name_and_dataframe(data, metadata)
|
|
34
37
|
hyper_transformer = HyperTransformer()
|
|
35
|
-
hyper_transformer.detect_initial_config(
|
|
38
|
+
hyper_transformer.detect_initial_config(table_data)
|
|
36
39
|
supported_sdtypes = hyper_transformer._get_supported_sdtypes()
|
|
37
40
|
config = {}
|
|
38
|
-
|
|
39
|
-
for column_name, column in
|
|
41
|
+
table_metadata = next(iter(metadata.tables.values()))
|
|
42
|
+
for column_name, column in table_metadata.columns.items():
|
|
40
43
|
sdtype = column['sdtype']
|
|
41
44
|
if sdtype in supported_sdtypes:
|
|
42
45
|
config[column_name] = sdtype
|
|
@@ -59,15 +62,16 @@ class UniformSynthesizer(BaselineSynthesizer):
|
|
|
59
62
|
# This is done to match the behavior of the synthesizer for SDGym <= 0.6.0
|
|
60
63
|
columns_to_remove = [
|
|
61
64
|
column_name
|
|
62
|
-
for column_name, column_data in
|
|
65
|
+
for column_name, column_data in table_data.items()
|
|
63
66
|
if column_data.dtype.kind in {'O', 'i', 'b'}
|
|
64
67
|
]
|
|
65
68
|
hyper_transformer.remove_transformers(columns_to_remove)
|
|
66
69
|
|
|
67
|
-
hyper_transformer.fit(
|
|
68
|
-
transformed = hyper_transformer.transform(
|
|
70
|
+
hyper_transformer.fit(table_data)
|
|
71
|
+
transformed = hyper_transformer.transform(table_data)
|
|
69
72
|
self.hyper_transformer = hyper_transformer
|
|
70
73
|
self.transformed_data = transformed
|
|
74
|
+
self._table_name = table_name
|
|
71
75
|
|
|
72
76
|
def _sample_from_synthesizer(self, synthesizer, n_samples):
|
|
73
77
|
hyper_transformer = synthesizer.hyper_transformer
|
|
@@ -85,7 +89,7 @@ class UniformSynthesizer(BaselineSynthesizer):
|
|
|
85
89
|
values = np.random.uniform(column.min(), column.max(), size=n_samples)
|
|
86
90
|
sampled[name] = values
|
|
87
91
|
|
|
88
|
-
return hyper_transformer.reverse_transform(sampled)
|
|
92
|
+
return {synthesizer._table_name: hyper_transformer.reverse_transform(sampled)}
|
|
89
93
|
|
|
90
94
|
|
|
91
95
|
class MultiTableUniformSynthesizer(MultiTableBaselineSynthesizer):
|
|
@@ -112,7 +116,7 @@ class MultiTableUniformSynthesizer(MultiTableBaselineSynthesizer):
|
|
|
112
116
|
for table_name, table_data in data.items():
|
|
113
117
|
table_metadata = metadata.get_table_metadata(table_name)
|
|
114
118
|
synthesizer = UniformSynthesizer()
|
|
115
|
-
synthesizer._fit(table_data, table_metadata)
|
|
119
|
+
synthesizer._fit({table_name: table_data}, table_metadata)
|
|
116
120
|
self.num_rows_per_table[table_name] = len(table_data)
|
|
117
121
|
self.table_synthesizers[table_name] = synthesizer
|
|
118
122
|
|
|
@@ -135,6 +139,6 @@ class MultiTableUniformSynthesizer(MultiTableBaselineSynthesizer):
|
|
|
135
139
|
sampled_table = UniformSynthesizer().sample_from_synthesizer(
|
|
136
140
|
table_synthesizer, n_samples=n_samples
|
|
137
141
|
)
|
|
138
|
-
sampled_data[table_name] = sampled_table
|
|
142
|
+
sampled_data[table_name] = sampled_table[table_name]
|
|
139
143
|
|
|
140
144
|
return sampled_data
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"""Utility functions for synthesizers in SDGym."""
|
|
2
|
+
|
|
3
|
+
from sdv.metadata import Metadata
|
|
4
|
+
|
|
5
|
+
from sdgym.synthesizers.base import BaselineSynthesizer
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_available_single_table_synthesizers():
|
|
9
|
+
"""List all available single-table synthesizers in SDGym.
|
|
10
|
+
|
|
11
|
+
Returns:
|
|
12
|
+
list:
|
|
13
|
+
A sorted list of available single-table synthesizer names.
|
|
14
|
+
"""
|
|
15
|
+
return sorted(BaselineSynthesizer._get_supported_synthesizers('single_table'))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def get_available_multi_table_synthesizers():
|
|
19
|
+
"""List all available multi-table synthesizers in SDGym.
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
list:
|
|
23
|
+
A sorted list of available multi-table synthesizer names.
|
|
24
|
+
"""
|
|
25
|
+
return sorted(BaselineSynthesizer._get_supported_synthesizers('multi_table'))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _get_supported_synthesizers():
|
|
29
|
+
"""Get SDGym supported synthesizers.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
list:
|
|
33
|
+
A list of available SDGym supported synthesizer names.
|
|
34
|
+
"""
|
|
35
|
+
synthesizers = []
|
|
36
|
+
for modality in ['single_table', 'multi_table']:
|
|
37
|
+
synthesizers.extend(BaselineSynthesizer._get_supported_synthesizers(modality))
|
|
38
|
+
|
|
39
|
+
return sorted(synthesizers)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _get_single_table_name(data, metadata):
|
|
43
|
+
"""Get the table name from metadata or data.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
data (dict[str, pd.DataFrame]):
|
|
47
|
+
Dictionary mapping the name to the dataframe. Expected to
|
|
48
|
+
be a dictionary of one dataframe.
|
|
49
|
+
metadata (sdv.Metadata):
|
|
50
|
+
The metadata.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
str:
|
|
54
|
+
The name of the table.
|
|
55
|
+
"""
|
|
56
|
+
if isinstance(metadata, Metadata):
|
|
57
|
+
table_name = metadata._get_single_table_name()
|
|
58
|
+
else:
|
|
59
|
+
if len(data) != 1:
|
|
60
|
+
raise ValueError(
|
|
61
|
+
"The data contains more than one table. Could not determine 'table name'."
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
table_name = next(iter(data))
|
|
65
|
+
|
|
66
|
+
return table_name
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _get_single_table_name_and_dataframe(data, metadata):
|
|
70
|
+
"""Get the table name and its dataframe from single table data.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
data (dict[str, pd.DataFrame]):
|
|
74
|
+
Dictionary mapping the name to the dataframe. Expected to
|
|
75
|
+
be a dictionary of one dataframe.
|
|
76
|
+
metadata (sdv.Metadata):
|
|
77
|
+
The metadata.
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
tuple[str, pd.DataFrame]:
|
|
81
|
+
The name of the table and its dataframe.
|
|
82
|
+
"""
|
|
83
|
+
table_name = _get_single_table_name(data, metadata)
|
|
84
|
+
return table_name, data[table_name]
|
|
@@ -209,3 +209,20 @@ def _set_column_width(writer, df, sheet_name):
|
|
|
209
209
|
def _is_list_of_type(values, type_to_check=str):
|
|
210
210
|
"""Checks that 'values' is a list and all elements are of type 'type_to_check'."""
|
|
211
211
|
return isinstance(values, list) and all(isinstance(value, type_to_check) for value in values)
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def _get_single_table_dataframe(data):
|
|
215
|
+
"""Get the only table from a dictionary of one dataframe."""
|
|
216
|
+
if not isinstance(data, dict) or not all(
|
|
217
|
+
isinstance(table, pd.DataFrame) for table in data.values()
|
|
218
|
+
):
|
|
219
|
+
raise ValueError(
|
|
220
|
+
'The data must be a dictionary mapping a single table name to a dataframe.'
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
if len(data) != 1:
|
|
224
|
+
raise ValueError(
|
|
225
|
+
f'The data must contain exactly one table, but {len(data)} tables were found.'
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
return next(iter(data.values()))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sdgym
|
|
3
|
-
Version: 0.16.
|
|
3
|
+
Version: 0.16.2.dev0
|
|
4
4
|
Summary: Benchmark tabular synthetic data generators using a variety of datasets
|
|
5
5
|
Author-email: "DataCebo, Inc." <info@sdv.dev>
|
|
6
6
|
License-Expression: BUSL-1.1
|
|
@@ -63,10 +63,9 @@ Requires-Dist: torch>=2.6.0; python_version >= "3.13" and python_version < "3.14
|
|
|
63
63
|
Requires-Dist: torch>=2.9.0; python_version >= "3.14"
|
|
64
64
|
Requires-Dist: tqdm>=4.66.3
|
|
65
65
|
Requires-Dist: XlsxWriter>=1.2.8
|
|
66
|
-
Requires-Dist:
|
|
67
|
-
Requires-Dist: rdt<2
|
|
68
|
-
Requires-Dist:
|
|
69
|
-
Requires-Dist: sdv<2,>=1.37.0
|
|
66
|
+
Requires-Dist: sdmetrics>=0.32.0
|
|
67
|
+
Requires-Dist: rdt<3,>=2.0.0
|
|
68
|
+
Requires-Dist: sdv<3,>=2.0.0
|
|
70
69
|
Provides-Extra: dask
|
|
71
70
|
Requires-Dist: dask; extra == "dask"
|
|
72
71
|
Requires-Dist: distributed; extra == "dask"
|
|
@@ -10,8 +10,9 @@ psutil>=7.0.0
|
|
|
10
10
|
tabulate<0.9,>=0.8.3
|
|
11
11
|
tqdm>=4.66.3
|
|
12
12
|
XlsxWriter>=1.2.8
|
|
13
|
-
sdmetrics>=0.
|
|
14
|
-
|
|
13
|
+
sdmetrics>=0.32.0
|
|
14
|
+
rdt<3,>=2.0.0
|
|
15
|
+
sdv<3,>=2.0.0
|
|
15
16
|
|
|
16
17
|
[:python_version < "3.10"]
|
|
17
18
|
numpy>=1.22.2
|
|
@@ -24,7 +25,6 @@ torch>=1.13.0
|
|
|
24
25
|
|
|
25
26
|
[:python_version < "3.14"]
|
|
26
27
|
cloudpickle>=2.1.0
|
|
27
|
-
rdt<2,>=1.18.2
|
|
28
28
|
|
|
29
29
|
[:python_version >= "3.10" and python_version < "3.11"]
|
|
30
30
|
scikit-learn>=1.1.0
|
|
@@ -59,7 +59,6 @@ pandas<3,>=2.3.3
|
|
|
59
59
|
scikit-learn>=1.8.0
|
|
60
60
|
scipy>=1.16.1
|
|
61
61
|
torch>=2.9.0
|
|
62
|
-
rdt<2,>=1.20.0
|
|
63
62
|
|
|
64
63
|
[all]
|
|
65
64
|
sdgym[dask,dev,test]
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
"""Utility functions for synthesizers in SDGym."""
|
|
2
|
-
|
|
3
|
-
from sdgym.synthesizers.base import BaselineSynthesizer
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def get_available_single_table_synthesizers():
|
|
7
|
-
"""List all available single-table synthesizers in SDGym.
|
|
8
|
-
|
|
9
|
-
Returns:
|
|
10
|
-
list:
|
|
11
|
-
A sorted list of available single-table synthesizer names.
|
|
12
|
-
"""
|
|
13
|
-
return sorted(BaselineSynthesizer._get_supported_synthesizers('single_table'))
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def get_available_multi_table_synthesizers():
|
|
17
|
-
"""List all available multi-table synthesizers in SDGym.
|
|
18
|
-
|
|
19
|
-
Returns:
|
|
20
|
-
list:
|
|
21
|
-
A sorted list of available multi-table synthesizer names.
|
|
22
|
-
"""
|
|
23
|
-
return sorted(BaselineSynthesizer._get_supported_synthesizers('multi_table'))
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def _get_supported_synthesizers():
|
|
27
|
-
"""Get SDGym supported synthesizers.
|
|
28
|
-
|
|
29
|
-
Returns:
|
|
30
|
-
list:
|
|
31
|
-
A list of available SDGym supported synthesizer names.
|
|
32
|
-
"""
|
|
33
|
-
synthesizers = []
|
|
34
|
-
for modality in ['single_table', 'multi_table']:
|
|
35
|
-
synthesizers.extend(BaselineSynthesizer._get_supported_synthesizers(modality))
|
|
36
|
-
|
|
37
|
-
return sorted(synthesizers)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|