В процессе решения задачи при работе с данными нередко возникает ситуация, когда получение реальных данных сложно, к примеру, если речь идет о конфиденциальной информации, либо сбор данных занимает большое количество времени, либо просто необходимо протестировать проект с данными, которые соответствуют определенным критериям. Для решения ситуации мы можем искусственно сгенерировать данные с помощью языка программирования.
Библиотек для генерации данных большое количество, однако хорошего, понятного, быстрореализуемого описания очень мало. Пересмотрев множество примеров и статей, была найдена англоязычная статья, в которой рассмотрены три самых интересных, в плане функциональности и простоты использования, способа генерации синтетических данных с помощью пакетов Python. Рассмотрим подробнее эти библиотеки.
1. Faker
Faker - это пакет Python, разработанный для упрощения генерации синтетических данных. Данный пакет прост и интуитивно понятен в использовании. Установим пакет и попробуем:
pip install Faker
Чтобы использовать пакет Faker для генерации данных, необходимо инициализировать класс. Дополнительно укажем параметр локализованной области для экземпляра ru_RU, чтобы данные сгенерировались на русском языке (параметр по умолчанию en_US).
После инициализации сгенерируем 5 имен:
for _ in range(5):
print(fake.name())
Вениамин Давыдович Котов
Марфа Геннадиевна Никонова
Кириллов Севастьян Аксёнович
Анжела Юрьевна Романова
Зимина Наталья Анатольевна
Когда мы используем атрибут .name из класса Faker, результатом является имя, фамилия и отчество человека. Синтетические данные генерируются случайным образом каждый раз при запуске атрибута. С помощью пакета можно также сгенерировать адрес, работу, кредитный рейтинг и многое другое. С полным списком можно ознакомиться в документации.
2. SDV
SDV или Synthetic Data Vault - это пакет Python для генерации синтетических данных на основе предоставленного набора данных. Сгенерированные данные будут иметь те же свойства формата и статистику, что и предоставленный набор данных. SDV генерирует данные, применяя математические методы и модели машинного обучения. С помощью SVD можно обработать данные, даже если они содержат несколько типов данных и отсутствующие значения.
Для начала установим пакет.
pip install sdv
Для примера возьмем датасет Stroke Prediction Dataset от Kaggle с данными для прогнозирования инсульта.
import pandas as pd
data = pd.read_csv('healthcare-dataset-stroke-data.csv')
data.head()
![](https://habrastorage.org/getpro/habr/upload_files/b3a/b8b/354/b3ab8b35427165365a1457fd23233e24.png)
Наш датасет готов, теперь сгенерируем синтетические данные на основе набора данных. Используем для этого одну из доступных моделей SVD Singular Table GaussianCopula. Создадим экземпляр класса и вызовем метод fit, передав наши данные.
from sdv.tabular import GaussianCopula
model = GaussianCopula()
model.fit(data)
После того как наша модель обучена, вызываем метод sample, указав количество строк, которые хотим сгенерировать, например, 1000.
sample = model.sample(1000)
![](https://habrastorage.org/getpro/habr/upload_files/d82/ed4/a79/d82ed4a7912eabeb5c0a1cab61efc541.png)
Однако, нам необходимо, чтобы данные в колонке с идентификатором были уникальными. Для этого передадим в параметр модели primary_key нашу колонку id.
model = GaussianCopula(primary_key='id')
model.fit(data)
После генерации, мы получим данные с уникальными id.
Теперь вопрос, а насколько хороши сгенерированные синтетические данные? Воспользуемся функцией evaluate из SDV. Эта оценка будет сравнивать реальный набор данных с синтетическим набором.
evaluate(data, sample)
![](https://habrastorage.org/getpro/habr/upload_files/74d/219/f00/74d219f0061eaa30d36d0d846704b7e5.png)
Результатом вызова функции является число от 0 до 1, которое показывает насколько похожи две таблицы: 0 - худший результат, 1 - наилучший возможный результат.
Функция оценки применяет набор предварительно настроенных метрических функций и возвращает среднее значение оценок, полученных по каждой из них.
Для того чтобы увидеть различные метрики, которые были применены, можно передать дополнительный аргумент aggregate=False. Результатом будет словарь с оценками, которые возвращала каждая из метрик. Для проверки доступно много метрик.
Возьмем для примера статистические метрики (критерии Колмогорова–Смирнова и Хи-квадрат) и метрику обнаружения, основанную на классификаторе логистической регрессии.
from sdv.evaluation import evaluate
evaluate(data, sample, metrics=['CSTest', 'KSTest', 'LogisticDetection'], aggregate=False)
![](https://habrastorage.org/getpro/habr/upload_files/214/c0f/1bb/214c0f1bbac6e191a907f063249cb7f8.png)
Статистические метрики сравнивают отдельные столбцы из исходной таблицы с соответствующими столбцами из сгенерированной таблицы и выводится среднее значение. KSTest используется для сравнения столбцов с непрерывными данными, а CSTest с дискретными данными.
Метрика LogisticDetection при помощи машинного обучения позволяет оценить насколько сложно отличить синтетические данные от исходных. Для этого реальные и синтетические данные перемешиваются и устанавливается значение, указывающее, являются ли данные реальными или синтетическими, а затем перекрестно проверяют модель машинного обучения, которая пытается предсказать это значение.
3. Gretel
Gretel или Gretel Synthetics – это пакет Python с открытым исходным кодом, основанный на рекуррентной нейронной сети для создания структурированных и не структурированных данных.
Чтобы установить пакет, запустите следующий код:
pip install gretel-synthetics
Воспользуемся модулем Batch из пакета Gretel. Этот модуль работает непосредственно с датафреймами данных Pandas и позволяет автоматически разбивать датафрейм на более мелкие датафреймы (по кластерам столбцов), выполнять обучение модели и генерацию для каждого фрейма независимо. Затем мы можем объединить все обратно в один окончательный набор синтетических данных. В связи с этим пакет хорошо подходит для наборов данных с высокой размерностью и количеством столбцов.
Импортируем класс DataFrameBatch и определим параметры для обучения модели.
from gretel_synthetics.batch import DataFrameBatch
from pathlib import Path
df = pd.read_csv ("https://gretel-public-website.s3.amazonaws.com/datasets/healthcare-analytics/hospital_ehr_data.csv")
checkpoint_dir = str(Path.cwd() / "test-model")
config_template = {
# Число итераций по всему предоставленному обучающему набору
"epochs": 54,
# Максимальная длина строки для обучения
"max_line_len": 2048,
# Максимальный размер токенов, который будет извлечен из входного набора данных
"vocab_size": 200000,
# Указываем разделитель для структурированного текста
"field_delimiter": ",",
# Перезапись
"overwrite": True,
# Структура каталогов будет создана в расположении “checkpoint_dir”. Внутри папки будет создано по одному каталогу “batch_N”, где N - номер набора, начиная с 0.
"checkpoint_dir": checkpoint_dir
}
Используемый набор данных представляет собой набор данных электронной медицинской карты больницы, доступный от Gretel.
![](https://habrastorage.org/getpro/habr/upload_files/1a5/5a1/789/1a55a178976a6b68402747eabc1f91f9.png)
Приступаем к обучению. Инициализируем класс, указав параметры – исходный датафрейм и параметры для обучения, так же можно указать параметр batch_size и задать число столбцов в наборе (по умолчанию разбивка производится автоматически). Функция create_training_data() создает датафрейм данных и файл "train.csv" для каждого набора. Функция train_all_batches() перебирает все наборы и обучает модели.
batcher = DataFrameBatch(df = df, config = config_template)
batcher.create_training_data()
batcher.train_all_batches()
Генерируем синтетические данные. Результатом функции generate_all_batch_lines() является словарь, который показывает, удалось ли сгенерировать данные в каждом наборе.
status = batcher.generate_all_batch_lines(num_lines=1000)
![](https://habrastorage.org/getpro/habr/upload_files/8f9/b90/751/8f9b90751d9260fccd3a59772b4ee4b5.png)
synthetic_df = batcher.batches_to_df()
![](https://habrastorage.org/getpro/habr/upload_files/468/f3f/b14/468f3fb1497ab38b69695c63a861bb29.png)
Набор синтетических данных получен!
Теперь с помощью пакета Gretel cгенерируем синтетические данные для Stroke Prediction Dataset и проанализируем их относительно данных полученных с помощью пакета SVD из пункта 2. Воспользуемся возможностями API интерфейса Gretel.
Это очень удобный, интуитивно понятный и доступный интерфейс, который отлично подходит для быстрой генерации данных, даже с мобильного устройства. Загрузим данные и выберем параметры по умолчанию.
![](https://habrastorage.org/getpro/habr/upload_files/0f6/cd4/908/0f6cd4908f6e8cb598ed299fec7d4128.jpg)
После обучения и генерации данных в интерфейсе Gretel можно посмотреть отчет о полученных синтетических данных: краткий и полный отчет, сохраненный в html-файл.
![](https://habrastorage.org/getpro/habr/upload_files/bbc/ec5/375/bbcec5375af3b153c12ff782e5185a2f.jpg)
В полном отчете подсчитана сводная статистика, оценка качества синтетических данных, так же представлена таблица с показателями стабильности распределения по каждому полю таблицы и корреляционные матрицы.
Сравнивая время работы двух способов на одном датасете, получилось, что времени на обучение с помощью пакета Gretel уходит больше (SDV – 14,4 c, Gretel – 234 c), при достижении близких оценок качества.
Итак, мы разобрали 3 пакета языка Python для генерации данных – Faker, SDV и Gretel. Надеюсь вам окажется полезна данная информация для работы и тестирования ваших решений.
Благодарю за прочтение!