Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
dbf2a1f
WIP pulling the model code in
lotif Mar 23, 2026
ba2bbcc
Removing files that were not supposed to be submitted
lotif Mar 23, 2026
bdde267
Merge branch 'main' into marcelo/tabsyn
lotif Apr 6, 2026
42fbabe
WIP started testing
lotif Apr 8, 2026
1b63a7d
WIP progressed on testing
lotif Apr 9, 2026
2af4a09
Finished train test
lotif Apr 10, 2026
5eaebb5
Finished load and synthesize test
lotif Apr 10, 2026
492c106
Started fixing mypy errors
lotif Apr 10, 2026
3e86710
Continue fixing mypy errors
lotif Apr 13, 2026
bd41b3c
A bunch more mypy errors fixed
lotif Apr 14, 2026
cffe8f9
Fixed all errors 🎉
lotif Apr 16, 2026
92a7b7f
Merge branch 'main' into marcelo/tabsyn
lotif Apr 16, 2026
cbd05bc
Merge branch 'main' into marcelo/tabsyn
lotif Apr 24, 2026
990e278
Fixing unit tests
lotif Apr 24, 2026
101e167
Skipping integration tests that need models to be retrained
lotif Apr 24, 2026
7db80e3
adding repickled files
Apr 24, 2026
51811b7
Uncommenting tests
lotif Apr 24, 2026
498c21c
Adding tabsyn train code
lotif Apr 27, 2026
34686be
Using the DEVICE variable instead of doing the IF again
lotif Apr 27, 2026
db18a07
adding device so it runs in the cluster
lotif Apr 27, 2026
72b7351
Adding synthesize script
lotif Apr 28, 2026
bf3585f
Actually fixing synthesize
lotif Apr 28, 2026
22d298d
Adding evaluation script
lotif Apr 28, 2026
fc01bae
WIP beginning ensemble attack code
lotif Apr 28, 2026
c895320
Actually making the training config
lotif Apr 28, 2026
7ba95a2
Small vae save path fix
lotif Apr 28, 2026
b4e6007
Adding make challenge dataset
lotif Apr 29, 2026
067e3c9
adding sampling to training
lotif Apr 29, 2026
2dee575
Fixing the scripts and configs
lotif Apr 29, 2026
1cad880
Small code fix
lotif Apr 29, 2026
547b102
Updating file link
lotif Apr 29, 2026
c5008ae
Dropping all id columns, not only the main one
lotif Apr 29, 2026
04ea715
last fixes and scripts
lotif Apr 30, 2026
bb681cb
Fixing fine tuning and training data
lotif May 1, 2026
b0ea88b
Adding evaluation scripts
lotif May 4, 2026
b13acc6
Adding logs
lotif May 4, 2026
6ca19b5
Small fixes to evaluation script
lotif May 4, 2026
6aa3032
Addressing comments by coderabbit
lotif May 22, 2026
b00fc81
Merge branch 'main' into marcelo/tabsyn
lotif May 25, 2026
c75b529
Addressing comments by David
lotif May 26, 2026
7aef62a
CR by David
lotif Jun 2, 2026
26d3cf2
Merge branch 'marcelo/tabsyn' into marcelo/tabsyn-ensemble
lotif Jun 3, 2026
a31e1eb
Adding readme instructions
lotif Jun 3, 2026
d04cc1d
Better comments on is_numerical handling
lotif Jun 3, 2026
4b55ff5
Merge branch 'marcelo/tabsyn' into marcelo/tabsyn-ensemble
lotif Jun 3, 2026
7216f9d
Merge branch 'main' into marcelo/tabsyn
lotif Jun 3, 2026
84b0c32
Merge branch 'marcelo/tabsyn' into marcelo/tabsyn-ensemble
lotif Jun 3, 2026
76c5f83
Merge branch 'main' into marcelo/tabsyn-ensemble
lotif Jun 3, 2026
7664d3f
small fixes
lotif Jun 9, 2026
bed857c
Merge branch 'main' into marcelo/tabsyn-ensemble
lotif Jun 9, 2026
7082237
Small fix
lotif Jun 9, 2026
67b1f03
Bump actions/checkout from 6.0.3 to 7.0.0 (#147)
dependabot[bot] Jun 24, 2026
ad5f18a
Addressing CR comments by CodeRabbit. Will address the rest of the co…
lotif Jul 7, 2026
20ffe87
Merge branch 'main' into marcelo/tabsyn-ensemble
lotif Jul 7, 2026
31168ed
Fixing David's CR comments
lotif Jul 8, 2026
6f6acf5
Libraries Upgrade et al. (#150)
emersodb Jul 8, 2026
c5a44c0
WIP uploading expected data
lotif Jul 8, 2026
3cca1ec
More files to upload
lotif Jul 9, 2026
2e4de7c
messing with the seeds
lotif Jul 9, 2026
3f29f62
Uploading more data
lotif Jul 9, 2026
03ea35f
More assertion files to upload
lotif Jul 9, 2026
16127cf
Uploading assertion data and reverting tests changes + one additional…
lotif Jul 9, 2026
1bbc1b4
Uncommenting assetion I forgot
lotif Jul 9, 2026
cab3529
Revert "Uncommenting assetion I forgot"
lotif Jul 9, 2026
e57c324
Revert "Uploading assertion data and reverting tests changes + one ad…
lotif Jul 9, 2026
1bece17
Revert "More assertion files to upload"
lotif Jul 9, 2026
b841fda
Revert "Uploading more data"
lotif Jul 9, 2026
c874920
Revert "messing with the seeds"
lotif Jul 9, 2026
7a95b84
Revert "More files to upload"
lotif Jul 9, 2026
052d443
Revert "WIP uploading expected data"
lotif Jul 9, 2026
2d1bf75
Uploading new assertion data and modifying one test
lotif Jul 9, 2026
6da7c61
Revert "Uploading new assertion data and modifying one test"
lotif Jul 13, 2026
3371f1d
Reapply "WIP uploading expected data"
lotif Jul 13, 2026
d60eadb
Reapply "More files to upload"
lotif Jul 13, 2026
250b240
Reapply "messing with the seeds"
lotif Jul 13, 2026
f2f3c48
Reapply "Uploading more data"
lotif Jul 13, 2026
a326813
Reapply "More assertion files to upload"
lotif Jul 13, 2026
0c12dbd
Reapply "Uploading assertion data and reverting tests changes + one a…
lotif Jul 13, 2026
a3068da
Reapply "Uncommenting assetion I forgot"
lotif Jul 13, 2026
86f47da
Updated pillow v12.2.0 -> v12.3.0
lotif Jul 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/code_checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,17 @@ jobs:
run-code-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6.0.3
- uses: actions/checkout@v7.0.0
Comment thread
lotif marked this conversation as resolved.

- name: Install uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3
with:
# Install a specific version of uv.
version: "0.5.21"
enable-cache: true

- name: "Set up Python"
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1
with:
python-version-file: ".python-version"

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0

- name: Install uv
uses: astral-sh/setup-uv@v8.2.0
Comment thread
lotif marked this conversation as resolved.
Expand All @@ -51,7 +51,7 @@ jobs:
enable-cache: true

- name: Set up Python
uses: actions/setup-python@v6.2.0
uses: actions/setup-python@v6.3.0
with:
python-version-file: ".python-version"

Expand All @@ -77,7 +77,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0

- name: Configure Git Credentials
run: |
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/integration_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,17 @@ jobs:
integration-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6.0.3
- uses: actions/checkout@v7.0.0
Comment thread
lotif marked this conversation as resolved.

- name: Install uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3
with:
# Install a specific version of uv.
version: "0.5.21"
enable-cache: true

- name: "Set up Python"
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1
with:
python-version-file: ".python-version"

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ jobs:
run: |
sudo apt-get update
sudo apt-get install libcurl4-openssl-dev libssl-dev
- uses: actions/checkout@v6.0.3
- uses: actions/checkout@v7.0.0
Comment thread
lotif marked this conversation as resolved.

- name: Install uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3
with:
# Install a specific version of uv.
version: "0.5.21"
enable-cache: true

- name: "Set up Python"
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1
with:
python-version-file: ".python-version"

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,17 @@ jobs:
unit-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6.0.3
- uses: actions/checkout@v7.0.0
Comment thread
lotif marked this conversation as resolved.

- name: Install uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39
uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3
with:
# Install a specific version of uv.
version: "0.5.21"
enable-cache: true

- name: "Set up Python"
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1
with:
python-version-file: ".python-version"

Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ tests/integration/attacks/ensemble/assets/workspace
tests/integration/assets/tabsyn/processed_data
tests/integration/assets/tabsyn/results

# Emitted SynthEval analysis config file during metric creation. Unfortunately cannot be turned off...
SE_analysis_config.json

# Training Logs
*.err
*.out
Expand Down
2 changes: 1 addition & 1 deletion examples/gan/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ Kolmogorov-Smirnov (KS) test, Total Variation Distance (TVD), Correlation Matrix
and Mutual Information Difference.

To compute those metrics, you can run the command below. The name of the table should be
defined in the `dataset_meta.json` file, and the file for synthetic data should be under
defined in the `dataset_meta.json` file, and the data files should be under
`/data/{table_name}.csv` for the real data and `/results/{table_name}_synthetic.csv`
for the synthetic data.

Expand Down
6 changes: 1 addition & 5 deletions examples/gan/ensemble_attack/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,6 @@ python -m examples.gan.ensemble_attack.make_challenge_dataset

## 4. Training the attack model

> [!NOTE]
> In the [`config.yaml`](config.yaml) file, the attribute `ensemble_attack.shadow_training.model_name`
> is what determines this attack will be run with the CTGAN model.

To train the attack models, execute the following command:

```bash
Expand All @@ -81,7 +77,7 @@ To test the attack model against the target model and synthetic data produced on
[step 2](#2-generating-target-synthetic-data-to-be-tested), please run:

```bash
python -m examples.gan.ensemble_attack.test_attack_model
python -m examples.gan.ensemble_attack.run_test_attack_model
```

## 6. Compute the attack success
Expand Down
1 change: 0 additions & 1 deletion examples/gan/ensemble_attack/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ ensemble_attack:
run_metaclassifier_training: true

shadow_training:
model_name: ctgan
model_config: # Configurations specific for the CTGAN model
training:
epochs: 300
Expand Down
11 changes: 8 additions & 3 deletions examples/gan/ensemble_attack/make_challenge_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@ def make_challenge_dataset(config: DictConfig) -> None:
dataset_name = Path(config.training.data_path).stem
real_data = pd.read_csv(config.training.data_path)

random_seed = config.ensemble_attack.random_seed

training_data = pd.read_csv(Path(config.results_dir) / f"{dataset_name}_sampled.csv")
id_column = config.ensemble_attack.table_id_column_name
untrained_data = real_data[~real_data[id_column].isin(training_data[id_column])].sample(len(training_data))
untrained_data = real_data[~real_data[id_column].isin(training_data[id_column])]
sampled_untrained_data = untrained_data.sample(len(training_data), random_state=random_seed)

challenge_data = pd.concat([training_data, untrained_data])
challenge_data_labels = np.concatenate([np.ones(len(training_data)), np.zeros(len(untrained_data))])
challenge_data = pd.concat([training_data, sampled_untrained_data])
challenge_data_labels = np.concatenate([np.ones(len(training_data)), np.zeros(len(sampled_untrained_data))])

processed_attack_data_path = Path(config.ensemble_attack.data_paths.processed_attack_data_path)
processed_attack_data_path.mkdir(parents=True, exist_ok=True)
Expand All @@ -39,6 +42,8 @@ def make_challenge_dataset(config: DictConfig) -> None:
log(INFO, f"Saving challenge labels to {challenge_label_path}")
np.save(challenge_label_path, challenge_data_labels)

log(INFO, "Done!")


if __name__ == "__main__":
make_challenge_dataset()
15 changes: 12 additions & 3 deletions examples/gan/ensemble_attack/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import os
from pathlib import Path
from typing import Any

Expand Down Expand Up @@ -40,6 +41,14 @@ def make_training_config(config: DictConfig) -> dict[Any, Any]:
Returns:
The ensemble attack training config for the CTGAN model.
"""
base_data_dir = str
if "base_data_dir" in config:
base_data_dir = config.base_data_dir
elif "data_dir" in config:
base_data_dir = config.data_dir
else:
raise ValueError("Either base_data_dir or data_dir must be provided in the config.")

# Saving the model config from the config.yaml into a json file
# because that's what the ensemble attack code will be looking for
training_config_path = Path(config.ensemble_attack.shadow_training.training_json_config_paths.training_config_path)
Expand All @@ -48,10 +57,10 @@ def make_training_config(config: DictConfig) -> dict[Any, Any]:
training_config = OmegaConf.to_container(config.ensemble_attack.shadow_training.model_config, resolve=True)
assert isinstance(training_config, dict), "Training config must be a dictionary."
training_config["general"] = {
"test_data_dir": config.base_data_dir,
"test_data_dir": base_data_dir,
"sample_prefix": "ctgan",
"data_dir": config.base_data_dir,
"workspace_dir": str(Path(config.base_data_dir) / "shadow_workspace"),
"data_dir": base_data_dir,
"workspace_dir": os.path.join(base_data_dir, "shadow_workspace"),
"exp_name": "pre_trained_model",
}
json.dump(training_config, f)
Expand Down
3 changes: 1 addition & 2 deletions examples/midst_evaluation/run_evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def log_metrics(header: str, results: dict[str, float]) -> None:
"""
log(INFO, f"\n{header}\n{SEPARATOR}\n")
for metric_name, metric_value in results.items():
log(INFO, rf"Metric: {metric_name}\Score: {metric_value}")
log(INFO, rf"Metric: {metric_name}\tScore: {metric_value}")
log(INFO, f"{SEPARATOR}\n")


Expand Down Expand Up @@ -133,7 +133,6 @@ def should_syntheval_preprocess(cfg: DictConfig, for_privacy: bool) -> bool:
[
cfg.ks_tv.run,
cfg.ci_overlap.run,
cfg.ks_tv.run,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where did this guy go?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is repeated a couple of lines above this one, so it's an useless line.

cfg.correlation_diff.run,
cfg.mean_diff.run,
cfg.f1_score_diff.run,
Expand Down
96 changes: 96 additions & 0 deletions examples/tabsyn/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# TabSyn Single Table Example

This example will go over training a single-table [TabSyn](https://arxiv.org/abs/2310.09656)
model and synthesizing data afterwards.


## Downloading data

First, we need the data. Download it from this
[Google Drive link](https://drive.google.com/file/d/1HTgfgeL5GXc8uAGfeQirJrUynK7vFeyb/view?usp=drive_link),
extract the files and place them in a `/data` folder in within this folder
(`examples/tabsyn`).

> [!NOTE]
> If you wish to change the data folder, you can do so by editing the `base_data_dir` attribute
> of the [`config.yaml`](config.yaml) file.

Here is a description of the files that have been extracted:
- `trans.csv`: The training data. It consists of information about bank transactions and it
contains 20,000 data points.
- `trans_info.json`: Metadata about the `trans.csv` data, with information such as which columns are
numerical and which are categorical, what is the task type, etc.


## Kicking off training

To kick off training, simply run the command below from the project's root folder:

```bash
python -m examples.tabsyn.train
```

> [!NOTE]
> For all the commands in this file, you can specify a custom `config.yaml` file
> by adding the option `--config-path=/path-to-config`. It should point to the folder
> where the custom `config.yaml` file is located.

## Training results

The result files will be saved inside a `/results` folder within this folder
(`examples/tabsyn`).

> [!NOTE]
> If you wish to change the save folder, you can do so by editing the `results_dir` attribute
> of the [`config.yaml`](config.yaml) file.

In the `/results/trans` folder, there will be a file called `model.pt`,
Comment thread
emersodb marked this conversation as resolved.
which is a pytorch saved model.


## Synthesizing data

To synthesize some data with the trained model, run:

```bash
python -m examples.tabsyn.synthesize
```

If there is already a trained model in the `/results` folder, it will use that model.
Otherwise it will train one from scratch. At the end of the script, it will save the
synthesized data to `/results/trans/synthetic_data/trans_synthetic.csv`.
Comment thread
lotif marked this conversation as resolved.


## Evaluating the quality of the synthetic data

### Alpha Precision

To run a round of evaluation with [Alpha Precision](https://arxiv.org/abs/2301.07573)
metrics on a set of synthetic data, run the `evaluate.py` script:

```bash
python -m midst_toolkit.evaluation.quality.scripts.midst_alpha_precision_eval \
--synthetic_data_path examples/tabsyn/results/trans/synthetic_data/trans_synthetic.csv \
--real_data examples/tabsyn/data/trans_sampled.csv \
--meta_info_path examples/tabsyn/data/meta_info.json \
--save_directory examples/tabsyn/results/
```
Comment thread
lotif marked this conversation as resolved.

It will save the evaluation results under the `/results/model.txt` file.

### Additional Metrics

The calculation of additional metrics are set up in the `evaluate.py` file. They are the
Kolmogorov-Smirnov (KS) test, Total Variation Distance (TVD), Correlation Matrix Difference
and Mutual Information Difference.

To compute those metrics, you can run the command below. The data files should
be under `/data/{table_name}.csv` for the real data, `/data/{table_name}_sampled.csv`
for the sampled data used for training, and `/results/{table_name}_synthetic.csv`
for the synthetic data.
Comment thread
lotif marked this conversation as resolved.

```bash
python -m examples.tabsyn.evaluate
```

The results will be saved in the `/results/evaluation.json` file.
Loading
Loading