Обучение модели генерации табличных данных (Tabular ML)
Генерация табличных данных — задача обучения модели, которая синтезирует новые строки, статистически неотличимые от обучающего датасета. Применения: augmentation для несбалансированных датасетов, синтетические данные для privacy, тестовые данные.
CTGAN: обучение и настройка
from sdv.single_table import CTGANSynthesizer
from sdv.metadata import SingleTableMetadata
from sdv.evaluation.single_table import evaluate_quality, run_diagnostic
import pandas as pd
def train_tabular_generator(df: pd.DataFrame,
target_column: str = None) -> CTGANSynthesizer:
metadata = SingleTableMetadata()
metadata.detect_from_dataframe(df)
# Тонкая настройка типов
if target_column:
# Бинарный таргет — всегда categorical
metadata.update_column(target_column, sdtype='categorical')
synthesizer = CTGANSynthesizer(
metadata,
epochs=500,
batch_size=500,
generator_dim=(256, 256, 256), # Глубже для сложных данных
discriminator_dim=(256, 256, 256),
pac=10, # Packing для стабилизации обучения
log_frequency=True,
verbose=True
)
synthesizer.fit(df)
return synthesizer
def evaluate_generator(real_df: pd.DataFrame,
synthetic_df: pd.DataFrame,
metadata: SingleTableMetadata) -> dict:
quality_report = evaluate_quality(real_df, synthetic_df, metadata)
diagnostic = run_diagnostic(real_df, synthetic_df, metadata)
return {
'quality_score': quality_report.get_score(),
'column_shapes': quality_report.get_details('Column Shapes'),
'column_pair_trends': quality_report.get_details('Column Pair Trends'),
'diagnostic': diagnostic.get_results()
}
SMOTE для несбалансированных классов
from imblearn.over_sampling import SMOTE, ADASYN, BorderlineSMOTE
from imblearn.combine import SMOTETomek
def balance_dataset(X: pd.DataFrame, y: pd.Series,
method: str = 'smote') -> tuple:
methods = {
'smote': SMOTE(sampling_strategy='auto', random_state=42),
'adasyn': ADASYN(sampling_strategy='auto', random_state=42),
'borderline': BorderlineSMOTE(random_state=42),
'smote_tomek': SMOTETomek(random_state=42) # SMOTE + очистка Tomek Links
}
resampler = methods[method]
X_res, y_res = resampler.fit_resample(X, y)
print(f"Original distribution: {y.value_counts().to_dict()}")
print(f"Resampled distribution: {pd.Series(y_res).value_counts().to_dict()}")
return X_res, y_res
TableDiffusion: диффузионные модели для таблиц
Новейший подход для сложных многомодальных табличных данных:
# TabDDPM — SOTA для табличной генерации
from tab_ddpm import TabDDPM
model = TabDDPM(
num_numerical=10, # Количество числовых признаков
num_categorical=5, # Количество категориальных
d_layers=[256, 256, 256],
dropout=0.0,
rtdl_params={},
)
model.fit(X_train, num_epochs=1000, batch_size=256)
synthetic = model.sample(n=len(X_train))
ML Utility тест (TSTR)
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import roc_auc_score
def tstr_evaluation(real_train: pd.DataFrame, synthetic_train: pd.DataFrame,
real_test: pd.DataFrame, target: str) -> dict:
"""Train on Synthetic, Test on Real"""
X_real = real_train.drop(columns=[target])
X_synth = synthetic_train.drop(columns=[target])
X_test = real_test.drop(columns=[target])
# Модель на реальных данных
clf_real = GradientBoostingClassifier(random_state=42)
clf_real.fit(X_real, real_train[target])
auc_real = roc_auc_score(real_test[target], clf_real.predict_proba(X_test)[:, 1])
# Модель на синтетических данных
clf_synth = GradientBoostingClassifier(random_state=42)
clf_synth.fit(X_synth, synthetic_train[target])
auc_synth = roc_auc_score(real_test[target], clf_synth.predict_proba(X_test)[:, 1])
utility_gap = (auc_real - auc_synth) / auc_real
print(f"AUC Real: {auc_real:.4f}, AUC Synthetic: {auc_synth:.4f}")
print(f"ML Utility Gap: {utility_gap:.2%} (target: < 5%)")
return {'auc_real': auc_real, 'auc_synthetic': auc_synth, 'utility_gap': utility_gap}
Для большинства задач CTGAN с 300-500 эпохами обучения даёт ML utility gap < 5% при высоком качестве исходных данных. TabDDPM показывает лучшие результаты на сложных датасетах с высокой размерностью.







