Logo Craft Homelab Docs Контакты Telegram
Synthetic Data для ML — генерация данных для обучения
Wed Jan 28 2026

Synthetic Data для ML

Проблема нехватки данных — одна из фундаментальных преград в современном ML. Этикетки стоят дорого, время сблика ограничено, а некоторые данные просто невозможно получить этичным путем. Synthetic Data — не просто модный термин, а практический подход к расширению обучающих выборок, который помогает преодолеть эти ограничения. Но как отличить качественно сгенерированные данные от мусора, способного испортить вашу модель?

Почему мы вообще говорим о синтетических данных?

В реальных проектах ML мы сталкиваемся с несколькими фундаментальными проблемами:

  1. Классовый дисбаланс: когда один класс представлен значительно меньше других
  2. Редкие события: когда нам нужно научить модель распознавать что-то, что происходит редко (например, мошеннические транзакции)
  3. Этические и юридические ограничения: когда данные содержат личную информацию или конфиденциальные данные
  4. Физические ограничения: когда получение данных требует дорогостоящего оборудования или специальных условий

Синтетические данные помогают решить эти проблемы, создавая новые образцы, которые статистически соответствуют исходным данным. Но здесь кроется главная ловушка: корреляции между признаками в сгенерированных данных могут отличаться от реальных, что приводит к переобучению модели на артефактах, а не на реальных паттернах.

Основные подходы к генерации

Статистические методы

Самый простой подход — основанный на статистических свойствах исходных данных. Для числовых признаков мы можем анализировать распределение (нормальное, равномерное, экспоненциальное и т.д.) и генерировать новые значения, принадлежащие тому же распределению. Для категориальных данных мы можем использовать частоты появления категорий.

Преимущества:

  • Высокая скорость генерации
  • Низкие вычислительные затраты
  • Простой в реализации

Недостатки:

  • Учитывает только одномерные распределения, игнорируя корреляции между признаками
  • Не может моделировать сложные зависимости
  • Риск генерации “выбросов”, которые статистически возможны, но маловероятны в реальном мире

На основе правил

Этот подход предполагает создание правил, которым должны следовать синтетические данные. Например, для генерации адресов мы можем создать правила: страна -> почтовый индекс -> город -> улица. Или для медицинских данных: возраст -> пол -> группа риска.

Преимущества:

  • Сохранение логических связей между признаками
  • Контроль над качеством генерируемых данных
  • Возможность генерации редких, но логически корректных комбинаций

Недостатки:

  • Требует глубокого понимания предметной области для создания правил
  • Трудно масштабировать на большое количество признаков
  • Правила могут быть неполными или противоречивыми

Генеративные модели

Это наиболее мощный и сложный подход, который использует нейронные сети для моделирования распределения исходных данных.

GANs (Generative Adversarial Networks): Состоят из двух сетей: генератора и дискриминатора. Генератор создает синтетические данные, а дискриминатор пытается отличить их от реальных. Обе сети обучаются одновременно в конкурентной манере.

VAEs (Variational Autoencoders): Кодируют исходные данные в латентное пространство, а затем декодируют из этого пространства новые данные. Обучение направлено на то, чтобы латентное пространство было компактным и непрерывным.

Diffusion Models: Постепенно добавляют шум к данным, а затем учатся его убирать. Этот подход показал выдающиеся результаты в генерации изображений и текста.

Преимущества:

  • Учет сложных нелинейных зависимостей между признаками
  • Возможность генерации разнообразных и реалистичных данных
  • Адаптивность к различным типам данных

Недостатки:

  • Высокие вычислительные затраты на обучение
  • Сложность настройки гиперпараметров
  • Риск “модального коллапса” (особенно в GANs) — когда модель генерирует ограниченный набор данных

Data Augmentation

Специальный случай синтетических данных, который чаще используется в компьютерном зрении и обработке естественного языка. Методы включают:

  • Геометрические трансформации (повороты, отражения, масштабирование)
  • Изменение яркости, контрастности, насыщенности
  • Добавление шума
  • Перевод текста и обратно (для NLP)
  • Back-translation (для NLP)

Преимущества:

  • Простота реализации
  • Низкие вычислительные затраты
  • Сохранение семантики данных

Недостатки:

  • Ограниченный набор применимых методов для разных типов данных
  • Риск генерации бессмысленных данных при агрессивных преобразованиях

Практические реализации кода

Пример 1: Статистическая генерация для табличных данных

import numpy as np
import pandas as pd
from sklearn.ensemble import IsolationForest

def generate_synthetic_statistical(data, n_samples=1000):
    """
    Генерирует синтетические данные на основе статистических свойств исходных данных.
    
    Args:
        data: Исходный DataFrame
        n_samples: Количество синтетических образцов
        
    Returns:
        DataFrame с синтетическими данными
    """
    synthetic_data = pd.DataFrame()
    
    for column in data.columns:
        # Определяем тип данных столбца
        if data[column].dtype in ['int64', 'float64']:
            # Для числовых данных используем нормальное распределение
            mean = data[column].mean()
            std = data[column].std()
            synthetic_data[column] = np.random.normal(mean, std, n_samples)
        else:
            # Для категориальных данных используем частоты
            categories = data[column].value_counts(normalize=True)
            synthetic_data[column] = np.random.choice(categories.index, size=n_samples, p=categories.values)
    
    # Используем Isolation Forest для удаления аномалий
    clf = IsolationForest(contamination=0.05, random_state=42)
    outlier_labels = clf.fit_predict(synthetic_data)
    synthetic_data = synthetic_data[outlier_labels == 1]
    
    return synthetic_data

Неочевидные моменты:

  1. Мы используем IsolationForest для удаления аномалий, поскольку статистические методы могут генерировать выбросы
  2. Для категориальных данных мы учитываем не только уникальные значения, но и их частоту
  3. Мы сохраняем типы данных столбцов, что важно для дальнейшего использования

Пример 2: Data Augmentation для изображений

import torch
import torchvision.transforms as transforms
from PIL import Image
import numpy as np
import random

class AdvancedAugmentation:
    def __init__(self, p=0.5):
        """
        p: вероятность применения каждой трансформации
        """
        self.p = p
        
    def __call__(self, img):
        img = transforms.ToTensor()(img)
        
        # Случайно выбираем набор трансформаций
        if random.random() < self.p:
            img = transforms.RandomHorizontalFlip(p=1)(img)
        
        if random.random() < self.p:
            img = transforms.RandomRotation(degrees=15)(img)
            
        if random.random() < self.p:
            # Случайное изменение яркости и контрастности
            brightness_factor = random.uniform(0.8, 1.2)
            contrast_factor = random.uniform(0.8, 1.2)
            img = transforms.ColorJitter(
                brightness=brightness_factor,
                contrast=contrast_factor
            )(img)
            
        if random.random() < self.p:
            # Добавление гауссовского шума
            mean = 0
            std = 0.05
            noise = torch.randn(img.size()) * std + mean
            img = torch.clamp(img + noise, 0, 1)
            
        if random.random() < self.p:
            # Случайное обрезание
            img = transforms.RandomCrop(size=(int(img.shape[1]*0.9), int(img.shape[2]*0.9)))(img)
            
        return transforms.ToPILImage()(img)

# Использование
transform = transforms.Compose([
    transforms.Resize((224, 224)),
    AdvancedAugmentation(p=0.7),
    transforms.ToTensor()
])

# Применение к изображению
image = Image.open("example.jpg")
augmented_image = transform(image)

Неочевидные моменты:

  1. Каждая трансформация применяется независимо с заданной вероятностью, что позволяет создавать разнообразные комбинации
  2. Использование torch.clamp для сохранения значений пикселей в диапазоне [0, 1]
  3. Разные степени применения трансформаций (например, обрезание до 90% от исходного размера)

Узкие места и как их избежать

  1. Проблема смещения (Bias Amplification) Синтетические данные могут усиливать существующие смещения в исходных данных. Например, если в исходных данных представлено больше людей определенной расы, модель будет хуже работать с другими расами, даже при добавлении синтетических данных.

    Решение: Используйте стратифицированную генерацию, где для каждой группы данных генерируется одинаковое количество синтетических примеров.

  2. Распределение сдвига (Distribution Shift) Синтетические данные могут не соответствовать реальному распределению, особенно в хвостах распределения.

    Решение: Применяйте методы оценки качества генерации, такие как FID (Fréchet Inception Distance) для изображений или статистические тесты для табличных данных.

  3. Корреляции между признаками Простые методы генерации часто не учитывают корреляции между признаками, что приводит к нереалистичным данным.

    Решение: Используйте более сложные модели, такие как GANs или VAEs, которые лучше моделируют сложные зависимости.

  4. “Модальный коллапс” в GANs Модели GANs могут начать генерировать ограниченный набор образцов, игнорируя разнообразие исходных данных.

    Решение: Используйте архитектуры, устойчивые к модальному коллапсу, такие как Wasserstein GAN или StyleGAN.

  5. Высокие вычислительные затраты Обучение генеративных моделей требует значительных вычислительных ресурсов.

    Решение: Используйте методы передачи обучения (transfer learning) или предварительно обученные модели для Fine-tuning.

  6. Оценка качества Трудно объективно оценить качество сгенерированных данных.

    Решение: Используйте комбинацию метрик (статистические, визуальные, оценка производительности модели) и экспертную оценку.

Когда использовать синтетические данные, а когда — нет

Используйте синтетические данные, когда:

  1. У вас есть классовый дисбаланс, и вам нужно увеличить количество примеров для редких классов
  2. Вы работаете с конфиденциальными данными и не можете использовать реальные данные для обучения
  3. Вам нужно протестировать модель на редких или экстремальных сценариях, которые сложно встретить в реальных данных
  4. У вас ограниченное количество данных, но есть возможность их расширить с помощью синтетических примеров

Избегайте синтетических данных, когда:

  1. У вас уже достаточно качественных размеченных данных
  2. Проблема сильно зависит от сложных, трудно моделируемых зависимостей между признаками
  3. У вас нет ресурсов на обучение и настройку генеративных моделей
  4. Критически важно, чтобы модель работала с данными, которых нет в обучающей выборке (например, в системах безопасности)

Заключение

Синтетические данные — это мощный инструмент в арсенале ML-инженера, но не серебряная пуля. Они помогают решить проблему недостатка данных, но требуют тщательной настройки и проверки. Ключ к успеху — понимание ограничений каждого метода и их применимости к вашей конкретной задаче. Начинайте с простых методов (статистические, на основе правил) и переходите к сложным (GANs, VAEs) только при необходимости. Всегда проверяйте качество сгенерированных данных и их влияние на производительность вашей модели.

Помните: плохие синтетические данные могут быть хуже, чем их отсутствие. Всегда сравнивайте производительность модели, обученной на реальных данных, и с добавлением синтетических. Если производительность не улучшается или ухудшается, возможно, вам стоит пересмотреть подход к генерации или отказаться от синтетических данных в пользу других методов (например, активного обучения или поиска данных в других источниках).

Синтетические данные — не замена реальным данным, а дополнение к ним. Используйте их мудро, и они помогут построить более robust и надежные модели.