API reference¶
The names exported at the top level (from synthpriv import ...) are
re-exports of the objects documented below; the canonical documentation lives
with the defining module.
Pipeline¶
Orchestrator pipeline: train, sample, evaluate and report.
- class synthpriv.pipeline.EvaluationReport(data=<factory>)[source]¶
Bases:
objectContainer of the
evaluateresult.
- class synthpriv.pipeline.PrivacyPreservingSynthesizer(generator=None, generator_key=None, generator_kwargs=None, privacy_mechanism=None, privacy_metrics=None, utility_metrics=None, metric_options=None, random_state=0)[source]¶
Bases:
objectOrchestrate generator + privacy mechanism + metrics.
Examples
>>> from synthpriv import PrivacyPreservingSynthesizer >>> from synthpriv.privacy import NoPrivacy >>> synth = PrivacyPreservingSynthesizer( ... generator_key="ctgan", ... generator_kwargs={"epochs": 100}, ... privacy_mechanism=NoPrivacy(), ... utility_metrics=["ks_test", "correlation_mae", "ml_utility"], ... privacy_metrics=["nndr", "mia_auc"], ... ) >>> synth.fit(df) >>> synthetic = synth.sample(5000) >>> report = synth.evaluate(df, synthetic) >>> report.save("report.html")
- Parameters:
- generate(real_data, num_rows=1000, **kwargs)[source]¶
Shortcut: fit + sample.
- Parameters:
real_data (DataFrame)
num_rows (int)
- Return type:
DataFrame
- assert_dp(declared_epsilon=None, *, tolerance=0.05)[source]¶
Validate the synthesizer’s DP guarantee against the accountant epsilon.
declared_epsilondefaults to the configured mechanism’s. The result reconciles the epsilon measured by the generator with the accountant’s (if they differ, the accountant’s afterfitwins).- Parameters:
- Return type:
- evaluate(real_data, synthetic_data=None, num_rows=None, **sample_kwargs)[source]¶
Evaluate privacy and utility of the synthetic data vs the real one.
- Parameters:
real_data (DataFrame)
synthetic_data (DataFrame | None)
num_rows (int | None)
- Return type:
- save_model(path)[source]¶
Persist the trained synthesizer (generator + privacy + metrics).
Generates
path(the generator) andpath.meta(privacy config, measured epsilon and metrics).load_modelneeds no retraining.
Sweep¶
Epsilon vs utility sweep to explore the privacy/utility trade-off.
Trains dp-gan with several privacy budgets, measures the real epsilon
(RDP accountant) and evaluates the utility of each point. The result is a
table ordered by measured epsilon and an HTML report with the curves.
- class synthpriv.sweep.SweepResult(rows=<factory>, utility_metrics=<factory>, privacy_metrics=<factory>, generator='dp-gan')[source]¶
Bases:
objectResult of an epsilon-utility sweep.
Each row is a dict:
model,target_epsilon,measured_epsilon,util_<metric>,priv_<metric>andfit_seconds.- Parameters:
- synthpriv.sweep.run_epsilon_sweep(real_data, epsilons=(0.1, 0.5, 1.0, 2.0, 5.0, 50.0), delta=1e-05, generator_key='dp-gan', generator_kwargs=None, utility_metrics=None, privacy_metrics=None, metric_options=None, num_rows=None, random_state=0)[source]¶
Train a DP generator for each of
epsilonsand record utility + real epsilon.generator_keymust be DP-capable (dp-ganordp-copula). A very large epsilon (e.g. 50) is practically equivalent to “no DP”: it works as the architecture’s utility ceiling. The measured epsilon (RDP accountant fordp-gan, pure-DP composition fordp-copula) is the one plotted in the curve.- Parameters:
- Return type:
Benchmark¶
Utility benchmark of DP generators vs non-DP SDV generators.
Trains a DP generator (dp-gan with DP-SGD or dp-copula with pure DP)
with several budgets (measured epsilon) and
also trains reference generators without privacy (ctgan, tvae,
copula-gan, gaussian-copula) on the same dataset with the same
evaluation. Result: a table with the utility of each point and an HTML report
with the DP privacy/utility curve against the reference lines of each
baseline.
Interpretation: if the DP generator at epsilon ~ no-DP (50) gets close to the best baseline, the architecture is the limitation; the distance at low epsilon is the cost of privacy.
- class synthpriv.benchmark.BenchmarkResult(rows=<factory>, baselines=<factory>, utility_metrics=<factory>, privacy_metrics=<factory>, dp_generator='dp-gan')[source]¶
Bases:
objectResult of
run_benchmark.Each
rowis a dict with:model(DP generator name or baseline name),kind(“dp” | “baseline”),target_epsilonandmeasured_epsilon(DP points only),util_<metric>,priv_<metric>andfit_seconds.- Parameters:
- dataframe()[source]¶
Rows ordered: DP generator by measured epsilon, then the baselines.
- Return type:
DataFrame
- baseline_value(baseline, metric)[source]¶
Mean baseline value for a metric (single run or repeated).
- dp_value(metric, target_epsilon=None, generator=None)[source]¶
DP value at the most private point (or close to
target_epsilon).
- synthpriv.benchmark.run_benchmark(real_data, epsilons=(1.0, 2.0, 5.0, 10.0, 50.0), delta=1e-05, dp_generator='dp-gan', baselines=('gaussian-copula',), generator_kwargs=None, baseline_kwargs=None, utility_metrics=None, privacy_metrics=None, metric_options=None, num_rows=None, random_state=0)[source]¶
Benchmark a DP generator (at the given
epsilons) against non-DPbaselines.dp_generatormust be DP-capable (dp-ganordp-copula). Baselines are trained once (they do not depend on epsilon) with their default configuration; for deep generators e.g. passbaseline_kwargs={"ctgan": {"epochs": 300}}. Uses the same metrics on all points.
Report¶
Self-contained HTML report generation.
- synthpriv.report.render_html(data, path)[source]¶
Render
data(output ofEvaluationReport.data) to HTML.
Core¶
Base contracts for synthetic data generators.
All synthpriv generators implement BaseSynthesizer.
The minimal interface is fit + sample, so callers
(pipeline, CLI, REST) are agnostic to the concrete algorithm.
- class synthpriv.core.base.BaseSynthesizer(metadata=None, **kwargs)[source]¶
Bases:
ABCCommon interface for any synthetic data generator.
- Parameters:
metadata – Optional metadata (e.g. SDV
SingleTableMetadataor a dict). IfNone, the generator infers it infit.
- property model¶
Trained underlying model (implementation-specific).
- abstractmethod fit(data)[source]¶
Train the generator on the real data.
- Parameters:
data (DataFrame)
- Return type:
- abstractmethod sample(num_rows=1000, **kwargs)[source]¶
Generate
num_rowssynthetic records.- Parameters:
num_rows (int)
- Return type:
DataFrame
- fit_and_sample(data, num_rows=1000, **kwargs)[source]¶
Shortcut:
fit+samplein a single step.- Parameters:
data (DataFrame)
num_rows (int)
- Return type:
DataFrame
Generator registry.
Generators are registered with the @register_generator decorator and
instantiated by name (key). This lets the pipeline, the CLI or a REST API
resolve generators without importing each class directly.
- exception synthpriv.core.registry.GeneratorNotFoundError[source]¶
Bases:
KeyErrorA generator that is not registered was requested.
- class synthpriv.core.registry.GeneratorSpec(key, cls, description='', supports=('tabular',))[source]¶
Bases:
objectRegistry entry.
- synthpriv.core.registry.register_generator(key, description='', supports=('tabular',))[source]¶
Decorator to register a class as a generator under
key.
- synthpriv.core.registry.get_generator(key)[source]¶
Return the specification of a registered generator.
- Parameters:
key (str)
- Return type:
Generators¶
Tabular generators.
Thin wrappers over SDV single-table synthesizers. They keep the
BaseSynthesizer interface (fit/sample) and register in the registry.
- class synthpriv.generators.tabular.CTGANGenerator(metadata=None, epochs=300, batch_size=500, embedding_dim=128, generator_dim=(256, 256), discriminator_dim=(256, 256), **kwargs)[source]¶
Bases:
_SDVWrapperCTGAN: conditional generative adversarial network for tabular data.
- class synthpriv.generators.tabular.TVAEGenerator(metadata=None, epochs=300, batch_size=500, embedding_dim=128, **kwargs)[source]¶
Bases:
_SDVWrapperTVAE: variational autoencoder for mixed tabular data.
Differential privacy¶
Differential privacy (DP) mechanisms.
NoPrivacy gives no formal guarantee (empirical mitigation only).
DPSGD configures the DP budget: DP-SGD with Opacus (RDP accountant)
for the dp-gan generator, or the total pure-DP budget (delta 0,
Laplace sub-mechanisms) for the dp-copula generator.
Golden rule: if is_dp is True but available is False, the
pipeline refuses to proceed or warns clearly so that no guarantees are
claimed that the code does not yet deliver.
- class synthpriv.privacy.mechanisms.PrivacyMechanism(name='base', is_dp=False, available=True, notes='')[source]¶
Bases:
objectBase for every privacy mechanism.
- class synthpriv.privacy.mechanisms.NoPrivacy(name='no-privacy', is_dp=False, available=True, notes='No formal differential privacy guarantee. Re-identification risk must be assessed with the report metrics.')[source]¶
Bases:
PrivacyMechanismNo formal DP mechanism.
Privacy is only mitigated empirically (generator quality + risk metrics). Permanent check warning: it gives no formal guarantee at all.
- class synthpriv.privacy.mechanisms.DPSGD(name='dp-sgd', is_dp=True, available=True, notes="DP-SGD with Opacus's RDP accountant. The report epsilon is the real accumulated one after training, not the configured target. Requires the 'dp-gan' generator.", epsilon=1.0, delta=1e-05, noise_multiplier=None, max_grad_norm=1.0)[source]¶
Bases:
PrivacyMechanismTraining with DP-SGD (Opacus).
After
fit,used_noise_multiplierholds the applied noise and the RDP accountant returns the real accumulated epsilon (<= target when the sample size allows it). Uses thedp-gangenerator.
Privacy accountant.
In phase 2 the real epsilon is computed by Opacus (RDP) during fit of the
dp-gan generator and recorded here; the report shows that value, never a
configured target.
- class synthpriv.privacy.accountant.PrivacyAccountant(mechanism)[source]¶
Bases:
objectTranslates noise configuration into a real accumulated epsilon.
- Parameters:
mechanism (PrivacyMechanism)
- set_effective_epsilon(epsilon)[source]¶
Record the epsilon measured by the DP generator after
fit.- Parameters:
epsilon (float)
- Return type:
None
Formal assurance of the declared privacy.
assert_dp does not invent guarantees: it verifies the two operational facts
that make Opacus’s RDP bound valid and checks that the privacy claim does not
exceed what was accounted.
Step integrity: each
step()of the discriminator optimizer consumes DP budget. If more steps ran than the RDP accountant accounted, the guarantee is void andassert_dpfails. (Generator steps are only post-processing of the DP discriminator: they do not leak.)Budget not exceeded: the epsilon measured by the accountant must stay within
declared_epsilon * (1 + tolerance). The operational window is[measured_epsilon, declared_budget]: any claim above what was measured would be technically defensible, equal or below would be inflated.
If the mechanism is NoPrivacy or the generator provides no measured epsilon,
the result is fail with an explicit message: there is no formal guarantee to
validate.
- class synthpriv.privacy.assurance.DpAssurance(status='fail', declared_epsilon=None, measured_epsilon=None, delta=None, noise_multiplier=None, max_grad_norm=None, accounted_steps=None, actual_private_steps=None, steps_match=False, budget_respected=False, checks=<factory>, message='')[source]¶
Bases:
objectResult of
assert_dp: state of each check and the epsilon window.- Parameters:
- property window: tuple[float | None, float | None]¶
Operational window (measured_epsilon, declared_budget).
- synthpriv.privacy.assurance.assert_dp(generator, declared_epsilon=None, *, tolerance=0.05, delta=None)[source]¶
Validate the declared DP guarantee of a trained generator.
- Parameters:
generator (BaseSynthesizer) – Trained DP-capable generator (
dp-ganwith DP-SGD step counters_disc_steps_accounted/_disc_steps_actual, ordp-copulaand similar compositional pure-DP mechanisms without sequential steps — seecomponents/accounted_epsilon).declared_epsilon (float | None) – Claimed budget (defaults to the generator mechanism’s).
tolerance (float) – Relative margin allowed over the declared budget.
delta (float | None)
- Return type:
Split of the DP budget between training and marginals.
The dp-gan synthesizer consumes ecdf_epsilon on the marginals ECDFs and
epsilon on DP-SGD training; the total guarantee is
epsilon + ecdf_epsilon (additive and exact). This module helps split a total
budget into those two items coherently.
- class synthpriv.privacy.budget.BudgetSplit(total, margins_fraction, train, margins)[source]¶
Bases:
objectResult of the split:
trainandmarginsitems fordp-gan.total(final composed guarantee) =train + margins. Fordp-copulauseDPCopulaGeneratordirectly with its internal fractions (margins_fraction/corr_fraction), which split the total automatically.
- synthpriv.privacy.budget.split_budget(total_epsilon, margins_fraction=0.3)[source]¶
Divide
total_epsiloninto training and marginals fordp-gan.A low
margins_fraction(0.1-0.4) is usually enough for marginals with many rows; increase it on small datasets (Laplace histogram variance grows with less data) or when tails matter a lot and KS drops.- Parameters:
- Return type:
ECDF with a formal differential privacy guarantee (Laplace / histogram).
Mechanism: histogram with Laplace-noisy counts for each numeric column.
Sensitivity per bin = 1 (adding/removing a row moves each count by at most 1) and the bins partition the data disjointly: by parallel composition, the whole column consumes a single
epsilon(Laplace noise of scale1/epsilonper bin).Columns are mutually disjoint but not a partition of the same datum, so the total budget is split sequentially across columns: each column uses
total_epsilon / n_columns.The grid range is trimmed to the empirical 0.001/0.999 quantiles (with a margin), avoiding the publication of exact extremes; values outside that support are not emitted.
The quantile function (inverse of the noisy ECDF, smoothed monotonically and by linear interpolation) is post-processing of the DP output, so it consumes no extra budget. Emitting values from this inverse keeps the per-column DP guarantee; composition with the training DP-SGD gives the synthesizer’s total guarantee.
- class synthpriv.privacy.dpecdf.DPEcdf(epsilon=1.0, bins=200, q_low=0.001, q_high=0.999, bounds=None)[source]¶
Bases:
objectPrivate per-column ECDF based on a Laplace histogram.
- Parameters:
epsilon (float) – DP budget of this column (0 < epsilon <= total marginals budget / n_columns). The rest of the synthesizer must compose it with the training epsilon (
ecdf_epsilon + effective_epsilon).bins (int) – Number of equal-width intervals over the trimmed support.
q_low/q_high – Quantiles (0..1) defining the grid support when
boundsare not given; out-of-range values are aggregated at the edges via range clipping.bounds (tuple[float, float] | None) – Public support
(min, max)of the column. If provided, the grid is fixed and the mechanism is strictly pure DP (the guarantee does not depend on any prior data). IfNone, the support is derived from the empirical 0.001/0.999 quantiles of the data (with margin): practical, but the range itself reveals sample information — a warning is emitted and passing publicboundsis recommended when available.q_low (float)
q_high (float)
DP generators¶
Tabular GAN trained with DP-SGD (Opacus), class-conditioned.
Classic DP-GAN construction: only the discriminator sees the data and trains with DP-SGD (gradient clipping + noise). The generator is post-processing of the discriminator, so the result is DP with the accounted epsilon.
For utility the AC-GAN scheme is used: the generator receives a condition
vector (class of the most imbalanced column) and the discriminator has an
auxiliary head that must predict it. The condition is sampled balanced in the
generator step (CTGAN-style) so minority classes do not collapse to the
majority one; when sampling, the empirical frequency is used to respect the
marginal. Numerics use mode-specific normalization (ModeEncoder) to avoid
flattening modes.
The RDP accountant translates noise, epochs and sample size into the real
accumulated epsilon, exposed in accounted_epsilon after fit.
- class synthpriv.dp.gan.DPSGDGenerator(privacy=None, epochs=100, latent_dim=64, hidden_dim=256, layers=2, learning_rate=0.0002, batch_size=128, dropout=0.0, num_modes=3, clip_value=3.0, condition_column=None, aux_lambda=1.0, generator_steps=2, numeric='mode', rectify_marginals=False, ecdf_epsilon=None, ecdf_bins=200, ecdf_bounds=None, label_smoothing=0.0, random_state=0, **kwargs)[source]¶
Bases:
BaseSynthesizerTabular generator with a formal differential privacy guarantee.
- Parameters:
privacy (DPSGD | None) –
DPSGDmechanism with targetepsilon/delta. Ifnoise_multiplieris set, that noise is used; otherwise Opacus computes it to reach the budget from epochs/batch_size/n_samples.num_modes (int) – Gaussian Mixture modes per numeric column.
1= plain z-score. A low value (3-5) captures multimodality; raising it too much burdens the generator with extra dimensions.condition_column (str | None) – Categorical column conditioning generation.
Nonepicks the most imbalanced one (lowest entropy). The generator step samples the condition balanced (CTGAN-style) so minority classes are learned, and generation samples with the real empirical frequency.aux_lambda (float) – Weight of the auxiliary losses (discriminator classifier and direct consistency between the generated class and its condition).
generator_steps (int) – Generator steps per discriminator step (the DP budget only counts the discriminator).
ecdf_epsilon (float | None) – DP budget for the marginals ECDFs (only with
numeric="uniform"). Distributed equally across numeric columns (Laplace histogram, parallel composition by bins and sequential across columns). The synthesizer’s total guarantee is the sequential composition of this budget with the training one:total_epsilon = epsilon(accumulated) + ecdf_epsilon(the report exposes it inaccountant.ecdf_epsilon/total_epsilon).Noneuses the raw empirical ECDF (no formal guarantee on the marginal).epochs (int)
latent_dim (int)
hidden_dim (int)
layers (int)
learning_rate (float)
batch_size (int)
dropout (float)
clip_value (float)
numeric (str)
rectify_marginals (bool)
ecdf_bins (int)
label_smoothing (float)
random_state (int)
- fit(data, **kwargs)[source]¶
Train the generator on the real data.
- Parameters:
data (DataFrame)
- Return type:
- sample(num_rows=1000, **kwargs)[source]¶
Generate
num_rowssynthetic records.- Parameters:
num_rows (int)
- Return type:
DataFrame
- assert_dp(declared_epsilon=None, *, tolerance=0.05, delta=None)[source]¶
Validate that the declared DP guarantee is not exceeded (steps + budget).
- Parameters:
- Return type:
- save(path)[source]¶
Persist config + encoder + weights + DP accounting in one file.
The real accumulated epsilon and the applied noise are kept: when reloading, the declared DP guarantee is the same as when trained.
Gaussian copula with differential privacy (dp-copula).
Fully parametric, fast model that attacks the dp-gan weak spot: the
dependence structure. The guarantee is pure DP (delta 0) because all
sub-mechanisms are Laplace (no RDP Gaussian noise):
Marginals:
DPEcdfper numeric column (Laplace histogram, parallel composition by bins; budgetmargins_fraction * epsilonsplit sequentially across columns).Dependence (copula): over the real Gaussians
z = Phi^-1(rank)(deterministic transformation from n, with values bounded byB = Phi^-1((n-0.5)/n), a public quantity), the sample covariance is perturbed entry-wise with Laplace noise of scale(B^2 / n) / epsilon_entry. Sensitivity per entry <= B^2/n (removing a row changes one per-row term of the sum). As entries share the data, the composition is sequential across thed(d-1)/2correlations:epsilon_entry = corr_fraction * epsilon / n_entries. It is then projected to the correlation sphere (PSD + diagonal 1).Categoricals: Laplace frequencies (parallel composition across categories, sequential across columns; budget the rest of
epsilon).
Sampling is post-processing of these DP outputs: private Gaussian copula
N(0, R) -> u = Phi(z) -> DPEcdf.quantile(u) and private
multinomials. Dependence is the main gain over independent marginals, and its
cost is total: the budget is split between marginals, copula and categoricals
according to the configurable fractions.
- class synthpriv.dp.copula.DPCopulaGenerator(privacy=None, margins_fraction=0.4, corr_fraction=0.4, bins=200, bounds=None, random_state=0, **kwargs)[source]¶
Bases:
BaseSynthesizerDifferentially private Gaussian copula (parametric and fast).
- Parameters:
privacy (DPSGD | None) –
DPSGDmechanism with the totalepsilonbudget. For this generator DP is pure (delta 0): the mechanism’sdeltaonly applies to thedp-gan’s DP-SGD.margins_fraction (float) – Fraction of
epsilondedicated to the numeric marginals (split equally across columns).corr_fraction (float) – Fraction dedicated to the copula’s correlation matrix. With categorical columns, the rest goes to their frequencies.
bins/bounds – Grid and public support of the
DPEcdf``s (see ``DPEcdf).bins (int)
random_state (int)
- fit(real_data)[source]¶
Train the generator on the real data.
- Parameters:
real_data (DataFrame)
- Return type:
- sample(num_rows=1000, **kwargs)[source]¶
Generate
num_rowssynthetic records.- Parameters:
num_rows (int)
- Return type:
DataFrame
Tabular encoders toward a uniform numeric space (and their inverse).
TabularEncoder: z-score + one-hot (basic, stable).ModeEncoder: mode-specific normalization with Gaussian Mixture + imbalanced-class conditioning (CTGAN-style) for better utility.
- class synthpriv.dp.encoder.TabularEncoder[source]¶
Bases:
objectTransform a DataFrame to a continuous array and rebuild it.
The numeric block uses the first
num_dimscomponents; categorical columns are one-hot-encoded afterwards, their intervals exposed incategorical_spansas(start, end)lists.
- class synthpriv.dp.encoder.ModeEncoder(num_modes=5, clip_value=3.0, condition_column=None, numeric='mode', dp_ecdf_epsilon=None, ecdf_bins=200, ecdf_bounds=None)[source]¶
Bases:
objectHigher-utility tabular encoder, inspired by CTGAN.
Numerics: two normalization modes.
mode(mode-specific): each value is assigned to the most probable mode of a Gaussian Mixture (per column), normalized within the mode and encoded together with a mode one-hot. Captures multimodal distributions that the z-score flattens.num_modes=1degenerates to z-score.uniform(empirical-CDF/rank gaussianization): maps each value to its percentile rank and then to a standard normal value viaPhi^-1(per-column gaussianization). The inverse appliesPhiand the empirical quantile, so the marginal is reconstructed by construction if the generator emits standard normal values (easier marginal to learn, notanhsaturation).
Categoricals: one-hot. Additionally, the most imbalanced categorical column is chosen as
condition_column_(lowest entropy) for the generator’s AC-GAN conditioning; its one-hots are exposed incondition_vectors/sample_conditions.The output uses
blocks: each numeric block is[normalized value (+ mode one-hot in ``modemode)]`` and each categorical is its one-hot.- Parameters:
- rectify(X)[source]¶
Rectify continuous numeric vectors to uniform marginals.
For each
uniformblock it replaces the value with its percentile rank within the sample(rank-0.5)/npassed throughPhi^-1. As it is a monotone per-column transformation, the sample copula (rank correlations / dependence structure) is preserved untouched while each column’s marginal becomes exactly uniform: the inverse then returns the real empirical quantiles. Useful to correct the generator’s marginal bias without touching the learned joint structure. Applies touniformnumerics; the rest of the vector is not modified.
Metrics¶
Metric result model and threshold evaluation.
- class synthpriv.metrics.base.MetricResult(name, description='', value=None, threshold=None, direction='lower_is_better', status='reported', message='', details=<factory>)[source]¶
Bases:
objectResult of a single metric.
- synthpriv.metrics.base.evaluate_status(value, threshold, direction)[source]¶
Decide PASSED/FAILED/REPORTED status by comparing against a threshold.
Metric registry and orchestration functions.
- synthpriv.metrics.core.register_metric(fn, name=None)[source]¶
Register a metric function under
name(sys.modules[fn.__module__].__name__).- Parameters:
fn (Callable[[...], MetricResult])
name (str | None)
- synthpriv.metrics.core.evaluate_metrics(real, synth, metric_names, metric_options=None)[source]¶
Run a list of metrics over (real, synth).
- Return type:
Utility metrics: how close the synthetic data is to the real one.
- synthpriv.metrics.utility.ks_test(real, synth, significance=0.05)[source]¶
Kolmogorov-Smirnov test per numeric column.
Null hypothesis: the marginal distributions match.
p >= significanceimplies equality cannot be rejected -> the column is useful.- Parameters:
real (DataFrame)
synth (DataFrame)
significance (float)
- Return type:
- synthpriv.metrics.utility.correlation_mae(real, synth, max_mae=0.05)[source]¶
Mean absolute error between Pearson correlation matrices.
- Parameters:
real (DataFrame)
synth (DataFrame)
max_mae (float)
- Return type:
- synthpriv.metrics.utility.ml_utility(real, synth, target=None, model=None, test_size=0.3, min_score=0.6)[source]¶
Train-on-Synthetic-Test-on-Real (TSTR) performance.
Trains a model on the synthetic data and evaluates it on the real one (TSTR); also trains and evaluates on real data (TRTS) as the maximum reachable reference.
valueis the TSTR metric.- Parameters:
- Return type:
Privacy metrics: re-identification and inference risk.
- synthpriv.metrics.privacy.nndr(real, synth, threshold=0.8, sample=2000)[source]¶
Nearest Neighbor Distance Ratio.
For each synthetic row
i: ratio = d(nearest real) / d(nearest synthetic excluding itself). Ratios << 1 imply near-duplicates of real records among the synthetic ones (re-identification risk). Values >= 1 indicate the synthetic points are not stuck to the real ones.- Parameters:
- Return type:
- synthpriv.metrics.privacy.mia_auc(real, synth, threshold=0.7, folds=5)[source]¶
Membership inference attack.
Trains a classifier to distinguish real from synthetic rows (cross-validation). AUC ~0.5 = indistinguishable (good); high AUC = the synthetic rows are distinguishable and an attacker could infer membership.
- Parameters:
- Return type:
- synthpriv.metrics.privacy.anonymeter_discovery(real, synth, n_attacks=5, threshold=0.1)[source]¶
Univariate discovery ratio: % of real rows “recovered” in the synthetic ones.
- Parameters:
- Return type:
- synthpriv.metrics.privacy.anonymeter_inference(real, synth, n_attacks=3, threshold=0.1)[source]¶
Sensitive-attribute inference attack from auxiliary attributes.
- Parameters:
- Return type:
Utilities¶
Shared utilities (logging, validation).
- synthpriv.utils.get_logger(name='synthpriv')[source]¶
synthpriv logger (child of the
synthprivroot).
Command-line interface¶
synthpriv command-line interface.
- Usage:
synthpriv generate –data real.csv -m ctgan –rows 5000 -o synthetic.csv synthpriv evaluate –real real.csv –synthetic synthetic.csv -o report.html