Faker Synthesizer from a YAML configuration
This section demonstrates driving the FakerSynthesizer from a single declarative YAML file carrying the columns, the structural scaffold, the numerical distributions and the conditional generation rules — with only the reference data and calculated features (Python callables) supplied in code.
Configuration file
# FakerSynthesizer configuration: columns + structure + statistical behavior in
# one declarative file. Loaded with `load_faker_config` (see
# faker_synthesizer_from_yaml.py). Reserved keys: scaffold, distributions,
# conditions — everything else under `columns` is the per-column metadata
# configuration. Calculated features are Python callables and are passed in code.
columns:
quantity:
datatype: numerical
vartype: float
min: 1.0
max: 5000.0
n_transactions:
datatype: numerical
vartype: int
min: 1
max: 500
segment:
datatype: categorical
vartype: string
categories:
retail: 80
fleet: 20
payment_type:
datatype: categorical
vartype: string
categories:
card: 70
cash: 25
app: 5
# WHICH rows exist: one row per product per day of March 2026, with
# category-aware density — fuel books every day, shop items have quiet days.
# `products` is provided at fit() time through `reference_data`.
scaffold:
dimensions:
- column: product_id
from_table: products
from_column: product_id
- column: booking_date
date_range: {start: "2026-03-01", end: "2026-03-31", freq: D}
density:
by: {table: products, column: category}
rates: {fuel: 1.0, beverages: 0.85, snacks: 0.7, car_wash: 0.5}
multipliers:
- {when: weekend, factor: 1.25, except: [fuel]}
# statistical shape of numerical columns (default would be uniform in domain)
distributions:
n_transactions: {distribution: poisson, lam: 60}
# per-segment behavior: fleet customers buy in bulk and pay by card/app
conditions:
- column: quantity
rules:
- when: {segment: fleet}
distribution: {distribution: lognormal, mean: 7.2, sigma: 0.4}
default:
distribution: {distribution: lognormal, mean: 4.6, sigma: 0.6}
- column: payment_type
rules:
- when: {segment: fleet}
values: {card: 0.85, app: 0.15}
# retail rows fall back to the column's declared category distribution
Example Code
"""
Example: FakerSynthesizer driven by a single YAML configuration file.
The YAML (faker_config.yaml) declares the columns, the structural scaffold
(product x day grid with category-aware density), the numerical distributions,
and the conditional generation rules. This script only supplies what cannot
live in YAML: the reference DataFrame backing the scaffold's `from_table`
dimension, and the calculated features (Python callables).
Generated table: daily fuel-station bookings for March 2026 —
- every product x active-day combination exists exactly once (scaffold)
- fleet bookings are bulk-sized and card/app-paid (conditions)
- n_transactions follows a Poisson shape (distributions)
- avg_ticket is computed exactly, never sampled (calculated features)
Fully deterministic under `random_state`; zero LLM calls.
"""
from pathlib import Path
import pandas as pd
from ydata.metadata import Metadata
from ydata.metadata.builder import MetadataConfigurationBuilder
from ydata.synthesizers import FakerSynthesizer
from ydata.synthesizers.faker.config import load_faker_config
# reference table backing the scaffold's `from_table` dimension (in practice:
# read from your product master)
products = pd.DataFrame(
{
"product_id": ["P-001", "P-002", "P-003", "P-004", "P-005"],
"name": ["Diesel", "Unleaded 95", "Craft Beer 6-pack", "Trail Mix", "Deluxe Car Wash"],
"category": ["fuel", "fuel", "beverages", "snacks", "car_wash"],
}
)
# one file: columns + scaffold + distributions + conditions
config = load_faker_config(Path(__file__).parent / "faker_config.yaml")
metadata = Metadata(configuration_builder=MetadataConfigurationBuilder(config.columns))
synth = FakerSynthesizer(locale="en")
synth.fit(
metadata,
scaffold=config.scaffold,
reference_data={"products": products},
distributions=config.distributions,
conditions=config.conditions,
calculated_features=[
{
"calculated_features": "avg_ticket",
"function": lambda quantity, n_transactions: (quantity / n_transactions).round(2),
"calculated_from": ["quantity", "n_transactions"],
},
],
)
# the scaffold defines the row count; random_state makes the run reproducible
data = synth.sample(random_state=42)
df = data.to_pandas()
print(df.head(10))
print(f"\n{len(df)} bookings | {df['product_id'].nunique()} products | "
f"{df['booking_date'].nunique()} days")
print("\nMean quantity per segment (fleet buys in bulk):")
print(df.groupby('segment')['quantity'].mean().round(1))
print("\nPayment mix for fleet bookings (card/app only):")
print(df.loc[df['segment'] == 'fleet', 'payment_type'].value_counts(normalize=True).round(2))
# the calculated identity holds exactly on every row
assert (df["avg_ticket"] == (df["quantity"] / df["n_transactions"]).round(2)).all()