Skip to content

TreeDGP

A piecewise-constant target built from a random decision tree. The tree is generated from the RNG alone — nothing is fitted to data, and no scikit-learn tree is involved — so the structure is fully determined by random_state.

This is the natural home ground for tree ensembles and the natural weak spot for linear models, which makes it a good check that a benchmark is not quietly rewarding one inductive bias.

Complexity Max depth Leaf noise σ
"low" 2 0.0
"medium" 3 0.3
"high" 5 1.0

At "low" the splits are clean, so a deep enough tree can in principle recover the target exactly.

from synthbench import BenchPipeline, TreeDGP

dgp = TreeDGP(complexity="medium", task_type="regression", random_state=0)
result = BenchPipeline(dgp).run(n_samples=500, n_features=10, random_state=42)

print(result.X.shape)  # (500, 10)
print(sum(result.metadata["signal_feature_importances"].values()))  # 1.0

Importances are depth-weighted split counts: a split on feature f at depth d contributes 1/d, summed over splits and normalised. Splits near the root therefore count for more, which mirrors how much of the sample space they partition. Features never split on get exactly 0.0.

For more than two classes, pass n_classes. Leaf values become vectors — one score per class — and the labels are drawn through a softmax, so the classes are unordered. The tree structure itself is unchanged, so the importances still describe which features the splits use.

Full parameter list: TreeDGP in the API reference.