Synthetic Data Generation Cheat Sheet
Practical techniques and libraries for generating synthetic tabular, text, and image data for ML training and privacy-safe testing.
Tabular Synthesis with SDV
Fit a generative model on real data and sample synthetic rows.
from sdv.metadata import SingleTableMetadatafrom sdv.single_table import CTGANSynthesizerimport pandas as pdreal_data = pd.read_csv("customers.csv")metadata = SingleTableMetadata()metadata.detect_from_dataframe(real_data)metadata.update_column("email", sdtype="email")metadata.update_column("signup_date", sdtype="datetime")synthesizer = CTGANSynthesizer(metadata, epochs=300, verbose=True)synthesizer.fit(real_data)synthetic_data = synthesizer.sample(num_rows=10_000)synthesizer.save("customer_synth.pkl")
Fake Records with Faker
Generate realistic fake PII-free records for seeding dev/test databases.
from faker import Fakerfake = Faker("en_US")Faker.seed(42) # reproducible outputrows = [{ "name": fake.name(), "email": fake.unique.email(), "address": fake.address(), "company": fake.company(), "ssn": fake.ssn(), # synthetic, not a real SSN "created_at": fake.date_time_this_decade().isoformat(),} for _ in range(1000)]
LLM-Generated Text Data
Use a structured-output prompt to mint labeled synthetic training examples.
from anthropic import Anthropicclient = Anthropic()resp = client.messages.create( model="claude-sonnet-4-5", max_tokens=1024, messages=[{ "role": "user", "content": ( "Generate 5 synthetic customer support tickets as JSON array " "with fields {text, category, priority}. Categories: billing, " "bug, feature_request. Vary tone and length." ), }],)print(resp.content[0].text)
Differential Privacy Noise
Add calibrated Laplace noise so aggregate synthetic stats can't leak individual records.
import numpy as npdef laplace_mechanism(true_value, sensitivity, epsilon): scale = sensitivity / epsilon noise = np.random.laplace(0, scale) return true_value + noise# Example: releasing a noisy count with epsilon=1.0 privacy budgettrue_count = 4821noisy_count = laplace_mechanism(true_count, sensitivity=1, epsilon=1.0)
Synthetic Data Tooling Landscape
Where to reach for each modality.
- SDV (Synthetic Data Vault)- open-source Python suite for tabular/relational/time-series GANs and copulas
- Gretel.ai- managed platform with differential-privacy guarantees and PII detection
- Mostly AI- enterprise tabular synthesizer with statistical fidelity reports
- Faker / mimesis- lightweight fake-data generators for dev seeding, not statistically representative
- Unity Perception / NVIDIA Omniverse Replicator- synthetic image/video for computer vision with ground-truth labels
- dbldatagen (Databricks)- Spark-native large-scale synthetic dataframe generation
- CTGAN / TVAE- deep generative models underlying most tabular synthesizers
Fidelity Report with SDMetrics
Quantify how well synthetic data preserves the statistical properties of the source before trusting it downstream.
from sdmetrics.reports.single_table import QualityReportreport = QualityReport()report.generate(real_data, synthetic_data, metadata.to_dict())print(report.get_score()) # overall 0-1 fidelity scorecolumn_scores = report.get_details(property_name="Column Shapes")pair_scores = report.get_details(property_name="Column Pair Trends")# flag any column whose shape diverges too much from the real distributionweak_columns = column_scores[column_scores["Score"] < 0.8]
Conditional Sampling for Class Balance
Force a synthesizer to over-sample a rare class instead of reproducing the original imbalance.
from sdv.sampling import Condition# real data is 95% 'no_churn' / 5% 'churn' -- rebalance the synthetic setfraud_condition = Condition( num_rows=5000, column_values={"churn": "churn"},)normal_condition = Condition( num_rows=5000, column_values={"churn": "no_churn"},)balanced_synthetic = synthesizer.sample_from_conditions( conditions=[fraud_condition, normal_condition])
Membership Inference Privacy Check
Sanity-check that a synthesizer isn't just memorizing and replaying rows from the training set.
import numpy as npfrom scipy.spatial.distance import cdistdef nearest_neighbor_distance_ratio(real_df, synth_df, numeric_cols): real = real_df[numeric_cols].to_numpy() synth = synth_df[numeric_cols].to_numpy() dists = cdist(synth, real) nearest = np.sort(dists, axis=1)[:, :2] ratio = nearest[:, 0] / (nearest[:, 1] + 1e-9) return ratio# ratios near 0 mean a synthetic row is suspiciously close to exactly one# real row -- a signal of potential memorization/leakageratios = nearest_neighbor_distance_ratio(real_data, synthetic_data, ["age", "income"])flagged = (ratios < 0.05).sum()
Synthetic Time-Series with DoppelGANger
Generate multivariate sequences (e.g. sensor readings) that preserve temporal correlations, not just marginal distributions.
from sdv.sequential import PARSynthesizerfrom sdv.metadata import SingleTableMetadatametadata = SingleTableMetadata()metadata.detect_from_dataframe(sensor_df)metadata.set_sequence_key("device_id")metadata.set_sequence_index("timestamp")synthesizer = PARSynthesizer(metadata, epochs=128, verbose=True)synthesizer.fit(sensor_df)synthetic_sequences = synthesizer.sample(num_sequences=200)
Common Synthetic Data Failure Modes
What to check for before shipping a synthesizer's output to training or QA.
- Mode collapse- GAN-based synthesizers converge to generating only a narrow subset of the real distribution's variety
- Referential integrity breaks- foreign keys across synthesized tables no longer match up after independent per-table sampling
- Outlier erasure- rare-but-legitimate extreme values get smoothed away, hurting downstream anomaly detection models
- Correlation loss- marginal per-column distributions look correct but joint relationships between columns are wrong
- Privacy leakage via near-duplicates- synthetic rows that are near-identical to real training rows still count as a re-identification risk
- Label leakage in LLM-generated data- an LLM prompted to generate 'diverse' examples often repeats near-identical phrasing patterns across the batch
Always run a fidelity check (SDV's `evaluate_quality` or a simple KS-test per column) before trusting synthetic data downstream — a synthesizer that overfits mode collapse will silently degrade your model's calibration.