CTGAN:基于 GAN 的表格数据条件生成模型

FreeGuideOnline 最新 2026-06-27

bash pip install sdv


如果你只需要 CTGAN 而不需要 SDV 的其他功能,也可以单独安装:

```bash
pip install ctgan

建议在 Python 3.8 及以上版本中使用。安装成功后,可通过以下代码验证:

import ctgan
print(ctgan.__version__)

快速上手:生成你的第一份合成表格

准备示例数据

我们使用 SDV 自带的 demo 数据集快速体验。你也可以换成自己的 pandas DataFrame。

from sdv.datasets.demo import download_demo

# 下载示例数据(包含连续列、离散列和多模态列)
real_data, metadata = download_demo(
    modality='tabular',
    dataset_name='adult'   # 人口普查收入数据
)
print(real_data.head())

三步生成合成数据

  1. 创建 CTGAN 实例
  2. 训练(拟合真实数据)
  3. 采样生成合成数据
from ctgan import CTGAN

# 初始化模型
ctgan = CTGAN(epochs=100, batch_size=500, verbose=True)

# 训练
ctgan.fit(real_data)

# 生成与真实数据相同行数的合成数据
synthetic_data = ctgan.sample(real_data.shape[0])
print(synthetic_data.head())

评估合成数据的质量

SDV 提供了自动评估工具,可以对比列分布、列间相关性以及整体统计相似性。

from sdv.evaluation.single_table import evaluate_quality

quality_report = evaluate_quality(real_data, synthetic_data, metadata)
print(quality_report.get_score())            # 总分
print(quality_report.get_properties_info())  # 各维度得分

通常经过 100~300 个 epoch 的训练,CTGAN 即可达到 80% 以上的统计保真度。

深入调参与优化

CTGAN 的训练稳定性高度依赖超参数设置。以下给出可调参数及其直观解释。

关键超参数一览

参数 默认值 说明
epochs 300 训练轮数,数据量大时可适当减少
batch_size 500 每批样本数,会影响梯度噪声
embedding_dim 128 噪声嵌入维度,越大生成器越强
generator_dim (256,256) 生成器隐藏层的神经单元数
discriminator_dim (256,256) 判别器隐藏层的神经单元数
discriminator_steps 1 每训练1次生成器,判别器训练N次
log_frequency True 是否对高度偏斜的类别采样做对数补偿
verbose True 是否打印训练损失

根据数据特点调整策略

  • 离散列特别多:增大 embedding_dimgenerator_dim;开启 log_frequency=True
  • 连续列分布复杂:确保 mode_normalization 正常工作(默认开启);必要时可通过 SDV 的 metadata 手动指定列的类型。
  • 多数类淹没少数类:增加 discriminator_steps(例如设为3~5),并设置 pac 参数为一个较小的值(如1)来控制梯度惩罚的样本数。
  • 数据量很小(<1000行):减小 batch_size 至 100 左右,适当延长 epochs,并考虑添加正则化(如降低学习率,SDV 内部已包含 AdamW)。

自定义元数据以提升效果

当数据集中某些列的类型自动推断不准确时,可通过 SDV 的元数据系统进行修正。例如,将实际表示类别的数值列强制设为分类列:

from sdv.metadata import SingleTableMetadata

metadata = SingleTableMetadata()
metadata.detect_from_dataframe(real_data)
metadata.update_column(
    column_name='relationship',
    sdtype='categorical'
)
# 然后将 metadata 传递给 CTGAN 的 fit 方法
ctgan = CTGAN(epochs=100)
ctgan.fit(real_data, metadata=metadata)

正确的 sdtype 设置(numerical / categorical / boolean / datetime)能让 CTGAN 的模式归一化和条件生成发挥最佳效果。

处理类别不平衡

CTGAN 的条件向量机制天然适合处理不平衡数据。但你也可以通过以下技巧强化:

  1. 分层采样生成:在调用 sample 时,通过 condition_columncondition_value 指定需要生成的类别。

    # 只生成收入 >50K 的样本
    synthetic_high = ctgan.sample(1000, condition_column='income', condition_value='>50K')
    
  2. 过采样少数类:生成大量少数类样本并与真实数据合并,用于训练下游分类器。

  3. 使用 CTGAN 的条件训练权重:训练时保持默认的 log_frequency 开启,它已经在损失中加大了对低频类别的惩罚。

保存与加载模型

训练完成后可以持久化模型,方便后续复用或部署。

# 保存模型
ctgan.save('ctgan_adult.pkl')

# 加载模型
from ctgan import CTGAN
loaded_ctgan = CTGAN.load('ctgan_adult.pkl')