SeqTrees Documentation¶
SeqTrees builds synthetic tabular rows by learning an ordered product of conditional distributions. Given tabular data with variables \(X_1, X_2, ..., X_d\), it estimates:
This implementation follows the sequential synthesis idea shown in 1: generate the first variable, append it to the synthetic row, then use the generated prefix to synthesize the next variable until the row is complete.
Model¶
SequentialTreeSynthesizer uses:
- an empirical marginal distribution for the first variable;
- one conditional decision tree for each later variable;
- empirical leaf distributions, so sampling preserves values seen in the preprocessed training data.
SeqTrees accepts raw pandas DataFrames and uses
ifcfill with label encoding to
prepare them for the tree model. The fitted transformer is retained so sampled
DataFrame output is restored to the original labels and column types.
Use model.get_preprocessed_data() after fitting to inspect the exact
model-ready DataFrame used by the sequential trees.
List-based inputs still need to be model-ready data with no null values:
continuous variables represented as floats and discrete variables represented
as integer category codes. Binary variables are ordinary discrete variables with
codes 0 and 1.
Continuous Variables¶
SeqTrees' default sampling strategy is empirical: every generated value is one of the values observed in the transformed training data. For continuous float variables, and for integer variables detected from DataFrame input, you can opt into interpolation inside the reached leaf distribution:
model = SequentialTreeSynthesizer(
continuous_strategy="interpolate",
continuous_columns=["age", "bmi"],
discrete_columns=["sex_code", "risk_code"],
)
SeqTrees can infer variable types when both continuous_columns and
discrete_columns are omitted: all-float columns become continuous and all-int
list-based columns become discrete. For DataFrame input, SeqTrees uses
IFCTransformer.column_types_: original categorical columns stay discrete and
never generate unseen labels, while original integer columns are treated as
numeric integer variables. For production use with preprocessed list data,
prefer declaring both lists:
model = SequentialTreeSynthesizer(
continuous_columns=["age", "bmi"],
discrete_columns=["sex_code", "income_bin", "risk_code"],
)
When either type list is supplied, the two lists must classify every input column exactly once. One-hot encoded inputs are intentionally out of scope; keep each categorical field as a single integer-coded variable before fitting SeqTrees.
Performance¶
SeqTrees can use either:
tree_backend="native": the pure-Python fallback with no required dependencies;tree_backend="lightgbm": LightGBM's histogram-based gradient boosting regressor, using leaf-index buckets for empirical sampling;tree_backend="sklearn": scikit-learn's compiledDecisionTreeRegressorwith empirical leaf sampling;tree_backend="auto": use LightGBM when installed, then scikit-learn, and otherwise fall back to the native backend.
Install the faster optional dependencies with:
python -m pip install "seqtrees[fast]"
Use LightGBM explicitly with:
model = SequentialTreeSynthesizer(tree_backend="lightgbm", n_jobs=-1)
Set n_jobs to control parallelism. n_jobs=1 runs serially, a positive
integer sets the worker count, and n_jobs=-1 uses all detected CPU cores.
SeqTrees parallelizes conditional tree fitting across variables once the order is
known, parallelizes candidate scoring inside greedy order optimization, and can
parallelize synthetic row generation through sample(..., n_jobs=...).
When fitting many conditional models in parallel, SeqTrees gives each LightGBM
model one internal thread to avoid oversubscribing CPU cores.
Variable Ordering¶
You can provide an exact order:
model = SequentialTreeSynthesizer(variable_order=["age", "sex_code", "risk_code"])
Or ask SeqTrees to choose a greedy order:
model = SequentialTreeSynthesizer(optimize_order=True)
The optimizer starts with the lowest-entropy variable and repeatedly picks the remaining variable with the lowest tree-estimated conditional entropy given the variables already selected.
For a full explanation of sequential factorization and variable ordering, see Theoretical Background.
API¶
See API for constructor parameters and learned attributes.
Comparison¶
For comparison with Synthpop , please check Comparison.
Diagrams¶
Both activity and class diagrams are provided in Diagrams
-
Emam Khaled El, Lucy Mosquera, and Chaoyi Zheng. Optimizing the synthesis of clinical trial data using sequential trees. Journal of the American Medical Informatics Association, 28(1):3–13, Nov 2020. URL: https://academic.oup.com/jamia/article/28/1/3/5981525. ↩