← Back to list

Can AI Generate Fake Data Good Enough to Train Real Models?

A practical guide to CTGAN — what it is, how it works, and five benchmarks that tell you whether your synthetic data is actually good.

Adarsh Nayak · 2026-07-06 09:20 · 8 claps · 9.1 min read
#ctgan #synthetic-data #artificial-intelligence #data-science #analytics
Open on Medium ↗
Wiki topics: EVAL · Evaluation & Benchmarks ML · Machine Learning AI · AI · General GRW · Growth & Analytics 🔬 · Science · General

Can AI Generate Fake Data Good Enough to Train Real Models?

A practical guide to CTGAN — what it is, how it works, and five benchmarks that tell you whether your synthetic data is actually good.

The Problem With Not Having Enough Data

Every ML team eventually hits the same wall. The model needs more training data, but collecting it is expensive, slow, or legally restricted. Privacy regulations block sharing patient records. Fraud labels are scarce by design. Class imbalance makes the model blind to the rare event you actually care about.

Synthetic data is one answer to this. Generate rows that look like real data, carry the same statistical patterns, and train your model on those instead. But the question nobody always answers clearly is: how do you know the synthetic data is actually good?

This article runs CTGAN on a real 45,000-row dataset, measures five concrete benchmarks, and shows the charts. You will see exactly how good the synthetic data is — and where it falls short.

What Is CTGAN?

CTGAN — Conditional Tabular Generative Adversarial Network — is a deep learning model purpose-built for generating synthetic tabular data. It was introduced by Xu et al. (NeurIPS 2019) and is today one of the most widely used open-source tools for this task.

Unlike image GANs that generate pixel grids, CTGAN must handle two fundamentally different types of columns in the same table:

· Continuous columns: age, salary, hours-per-week — values on a continuous scale, often with multiple peaks (modes)

· Discrete columns: city, occupation, income bracket — a finite set of categories, often heavily imbalanced

Most tabular generators fail on one or both of these. CTGAN was specifically designed to handle both correctly.

Table 1 (Xu et al., NeurIPS 2019) — number of datasets where each model outperforms the Bayesian network baseline. CTGAN wins on 7/8 vs CLBN and 8/8 vs PrivBN.

Table 1 (Xu et al., NeurIPS 2019) — number of datasets where each model outperforms the Bayesian network baseline. CTGAN wins on 7/8 vs CLBN and 8/8 vs PrivBN.

How CTGAN Works — The Architecture

At its core, CTGAN is a GAN with two neural networks that compete during training:

· Generator: produces fake rows from noise and a condition vector.

· Critic (Discriminator): scores whether a row looks real or fake under the same condition.

The training loop runs until the generator can fool the critic consistently.

Figure 1: CTGAN model (Xu et al., NeurIPS 2019). A condition vector (built from log-frequency sampling of a discrete column) is concatenated with random noise z and fed to Generator G. The Critic C compares real vs. generated rows under the same condition, driving the adversarial training loop.

Figure 1: CTGAN model (Xu et al., NeurIPS 2019). A condition vector (built from log-frequency sampling of a discrete column) is concatenated with random noise z and fed to Generator G. The Critic C compares real vs. generated rows under the same condition, driving the adversarial training loop.

Step 1 — Classify and Preprocess Columns

Before any training begins, every column is classified as continuous or discrete. Continuous columns go through a process called Mode-specific Normalisation (VGM). For each column, CTGAN fits a Gaussian mixture model to discover the natural clusters (modes) in the data. Every value is then encoded as two components:

· alpha — the normalised distance from the cluster mean (a number near 0)

· beta — a one-hot vector indicating which cluster the value belongs to

This encoding solves a real problem: a column like capital-gain has a massive spike at zero and a long tail of non-zero values. Standard normalisation would collapse all the zero values together. VGM treats them as their own cluster.

Discrete columns are simply one-hot encoded.

Figure 2: Mode-specific normalization (Xu et al., NeurIPS 2019). Left: VGM fits a Gaussian mixture to a continuous column. Middle: the probability density ρ of each mode is computed for every value. Right: the value is normalised relative to the sampled mode, producing a scalar α and a one-hot mode indicator β.

Figure 2: Mode-specific normalization (Xu et al., NeurIPS 2019). Left: VGM fits a Gaussian mixture to a continuous column. Middle: the probability density ρ of each mode is computed for every value. Right: the value is normalised relative to the sampled mode, producing a scalar α and a one-hot mode indicator β.

Step 2 — The Conditional Vector

The most important innovation in CTGAN is conditional generation. During training, the generator is not just told ‘make a realistic row’. It is told ‘make a realistic row where Occupation = Tech-support’.

This is done via a condition vector. At each training step, one discrete column is chosen randomly, and one category within that column is sampled using log-frequency weighting — rare categories get more turns. The resulting condition vector looks like:

cond = [0, 0, 1, 0, 0] # means: Occupation = Tech-support

The generator receives this condition concatenated with random noise:

h0 = z ⊕ cond # z = random noise, ⊕ = concatenate

Formal definition of the conditional generator G(z, cond) from the paper. Two residual hidden layers (256 units each, BatchNorm + ReLU) are followed by output heads: tanh for continuous scalars α̂ᵢ, Gumbel-softmax for mode indicators β̂ᵢ and discrete values d̂ᵢ.

Formal definition of the conditional generator G(z, cond) from the paper. Two residual hidden layers (256 units each, BatchNorm + ReLU) are followed by output heads: tanh for continuous scalars α̂ᵢ, Gumbel-softmax for mode indicators β̂ᵢ and discrete values d̂ᵢ.

Step 3 — Training-by-Sampling (Handling Imbalance)

This is CTGAN’s solution to imbalanced categories. Instead of training on whatever rows come up naturally — which would mean rare categories are almost never seen — CTGAN deliberately oversamples rare categories using this loop:

  1. Pick one discrete column at random.

  2. Sample a category using log-frequency weighting (rare = more often).

  3. Build the condition vector cond for that category.

  4. Sample matching real rows from the dataset.

  5. Generate fake rows using the same condition.

  6. Critic compares real conditional rows vs fake conditional rows.

  7. Update both networks based on the comparison result.

Step 4 — Generating Synthetic Rows

Once training is complete, generating new rows is a single line:

synthetic_df = ctgan.sample(45000) # returns a normal pandas DataFrame

The generator samples fresh random noise, picks conditions, produces encoded vectors, and the inverse-transform step converts everything back to the original column types and value ranges.

The Experiment — UCI Adult Income Dataset

To produce real, verifiable results, CTGAN was trained on the UCI Adult Income dataset downloaded from OpenML. The dataset contains census information for 48,842 people. After dropping rows with missing values, 45,222 rows remained.

This dataset was chosen for three reasons: it has a genuine mix of continuous and categorical columns, the target class (income) is imbalanced at 76/24, and it is small enough to train on a laptop CPU in a single session.

One preprocessing mistake we made: the dataset includes a fnlwgt column — a census sampling weight used by statisticians to scale survey responses to the full US population. It carries no meaningful pattern for income prediction and should have been dropped before training. We kept it, which wasted some model capacity on a meaningless variable. If you replicate this experiment, drop fnlwgt in your cleaning step.

Figure 3: Evaluation framework (Xu et al., NeurIPS 2019). Left: simulated-data pipeline using a re-parameterised oracle S′ to measure likelihood fitness. Right: real-data pipeline (Train on Synthetic, Test on Real) measuring accuracy, F1, and R².

Figure 3: Evaluation framework (Xu et al., NeurIPS 2019). Left: simulated-data pipeline using a re-parameterised oracle S′ to measure likelihood fitness. Right: real-data pipeline (Train on Synthetic, Test on Real) measuring accuracy, F1, and R².

Five Benchmarks — Measuring Whether the Synthetic Data Is Good

Synthetic data is only useful if it passes real tests. Five benchmarks were run in order from basic statistical similarity through to privacy analysis.

Benchmark 1 — KS Test (Continuous Column Similarity)

The two-sample Kolmogorov-Smirnov test measures whether two samples come from the same distribution. A statistic of 0 means identical; 1 means completely different. The Wasserstein distance measures the average ‘shift’ needed to move one distribution onto the other — lower is better.

Three of the four continuous columns passed comfortably. The exception is capital-gain (KS = 0.6376), which failed its 0.20 target. This is not a training error or a data quality problem — it is a structural ceiling of CTGAN’s architecture.

CTGAN preprocesses continuous columns using Variational Gaussian Mixture modelling (VGM), which fits Gaussian clusters to the data. A column where 91.6% of values are exactly zero is a point mass, not a Gaussian — and VGM cannot represent it. As a result, the trained model generated only 3.3% zeros (vs 91.6% in reality), and the synthetic non-zero values averaged 1,256 against a real mean of 13,142.

What we should have done: split capital-gain into two columns before training — a binary flag has_capital_gain (0/1, treated as discrete) and a log-transformed amount column for non-zero rows only. CTGAN handles each part correctly in isolation. This is a preprocessing decision, not a model limitation.

Benchmark 2 — TVD (Categorical Column Similarity)

Total Variation Distance (TVD) measures how different two frequency distributions are for a categorical column. A TVD of 0 is a perfect match. Anything below 0.10 is considered Excellent.

The sex, workclass, and race columns all scored Excellent. However, the income column result requires a closer look.

The income TVD of 0.0558 passes the Excellent threshold, but the underlying class proportions drifted: the real data has 75.2% ≤ 50K and 24.8% >50K, while the synthetic data shifted to 80.8% ≤ 50K and 19.2% >50K. CTGAN underrepresented the minority class (>50K) by 5.6 percentage points. This is a real quality gap that TVD alone understates. It also explains why the TSTR F1 score dropped from 0.6719 to 0.5662 in Benchmark 4 — the classifier trained on synthetic data saw proportionally fewer high-income examples.

Benchmark 3 — Correlation Structure (Frobenius Norm)

This benchmark checks whether CTGAN preserved the relationships between columns — not just the marginal distributions. Every column in both datasets is label-encoded, a full correlation matrix is computed for each, and then the Frobenius norm of the difference is calculated.

Frobenius difference = 0.5518 (target: below 2.0)

A Frobenius difference of 0.55 is below the 2.0 threshold. The side-by-side heatmaps (Chart C in the benchmark report) show the same broad correlation structure in both datasets — the same hot and cold regions appear in the same positions.

Benchmark 4 — ML Utility: TSTR vs TRTR

This is the most important benchmark. It answers the question that practitioners actually care about: if I train a model on synthetic data instead of real data, how much accuracy do I lose?

Two Random Forest classifiers (100 trees each) were trained and both tested on the same held-out 20% real test set:

· TRTR (ceiling): Random Forest trained on 80% of real data → accuracy 0.8510

· TSTR: Random Forest trained on 100% of synthetic data → accuracy 0.8255

Utility ratio = TSTR / TRTR = 0.8255 / 0.8510 = 0.970

A utility ratio of 0.970 is above 0.90, which is the Excellent threshold. A model trained entirely on synthetic data retains most of the predictive power of a model trained on real data. This makes the synthetic dataset genuinely useful as a training substitute.

Benchmark 5 — Privacy: Distance to Closest Record (DCR)

Synthetic data that is too similar to real rows is a privacy risk. DCR checks whether CTGAN memorised individual real records. For 1,000 sampled synthetic rows, the nearest real neighbour is found in normalised feature space.

· Mean distance: 0.1808 (target: above 0.10)

· % of rows with distance < 0.05: 17.2% (target: below 5%)

The mean DCR of 0.1808 passes the 0.10 floor, confirming there is no wholesale memorisation. However, 17.2% of synthetic rows sit within 0.05 of a real row, above the 5% warning threshold. This is a genuine proximity finding, not a data artefact.

We verified this by re-running DCR without the capital-gain column entirely. The near-zero percentage barely changed (17.2% → 18.1%), confirming the zero-spike is not the cause. In a normalised 15-feature space with 45,000 training rows, CTGAN is generating rows that are geometrically close to real records across multiple columns.

What this means in practice: the synthetic data does not directly copy real rows, but it is not far from them either. For a public research dataset like Adult Income this is acceptable. For a dataset containing genuinely sensitive personal data, you would want a mean DCR above 0.25 and near-zero percentage below 2% before releasing the synthetic output.

Results at a Glance

Table 2 (Xu et al., NeurIPS 2019) — benchmark results across Gaussian-mixture simulated data, Bayesian-network simulated data, and 8 real datasets. Bold = best deep learning method. CTGAN achieves -3.40 Lₜₑₛₜ on GM Sim. and 0.469 avg. F1 on real classification tasks.

Table 2 (Xu et al., NeurIPS 2019) — benchmark results across Gaussian-mixture simulated data, Bayesian-network simulated data, and 8 real datasets. Bold = best deep learning method. CTGAN achieves -3.40 Lₜₑₛₜ on GM Sim. and 0.469 avg. F1 on real classification tasks.

Where CTGAN Falls Short

CTGAN is one of the best open-source tools for tabular synthesis, but it has real limitations that practitioners should know before deploying it.

· Training instability. GAN training involves two networks competing. If one becomes too strong too fast, the training collapses. Monitor the generator and discriminator loss during training.

· Very rare categories. Even with training-by-sampling, categories with fewer than ~50 real examples may be poorly represented in the synthetic output.

· Business logic violations. CTGAN learns statistical correlations, not domain rules. It may produce rows where a 17-year-old has 40 years of work experience. Post-generation validation is essential.

· Mode collapse. Like all GANs, CTGAN can sometimes generate too many similar rows and miss parts of the real distribution. The TVD and Frobenius benchmarks help detect this.

· Compute cost. Training 300 epochs on this 45k-row dataset took 39 minutes on a CPU. For larger datasets or faster iteration, a CUDA-enabled GPU cuts this to 2–4 minutes. GPU is not required, but it changes the development loop significantly.

Open-Source Tools to Try

Final Takeaway

CTGAN works. Trained on 45,000 rows of real census data for 300 epochs, it produced synthetic data that:

· reproduced all four continuous distributions (max KS stat: 0.6376)

· matched all categorical frequencies (max TVD: 0.1283)

· preserved the correlation structure (Frobenius diff: 0.5518)

· retained 97.0% of the original model’s predictive accuracy (utility ratio: 0.970)

· raised a DCR proximity flag (17.2% of rows within 0.05 of a real row). Mean DCR 0.1808 passes the floor but proximity is real — verified to persist even after removing capital-gain from the distance calculation

That said, synthetic data is not a replacement for real data — it is a supplement. Always validate the output before using it in a production pipeline. The five benchmarks above are a reasonable minimum bar.


메타데이터
post_id
fefb9f79c344
slug
can-ai-generate-fake-data-good-enough-to-train-real-models-fefb9f79c344
url
https://medium.com/@adrshn2401/can-ai-generate-fake-data-good-enough-to-train-real-models-fefb9f79c344
canonical_url
https://medium.com/@adrshn2401/can-ai-generate-fake-data-good-enough-to-train-real-models-fefb9f79c344
author_url
https://medium.com/@adrshn2401
status
ok
fetched_at
2026-07-08 21:20:17