LinearDGP
The target is a linear combination of the features plus Gaussian noise. This is the DGP to reach for when you want a baseline that every method should handle, or when you need a task whose difficulty you can reason about analytically.
complexity moves two dials at once — how many features carry signal, and how much noise
sits on top:
| Complexity | Informative features | Noise σ |
|---|---|---|
"low" |
p // 5 |
0.1 |
"medium" |
p // 2 |
0.5 |
"high" |
all p |
1.0 |
So "high" is not a richer signal, it is a harder problem: more coefficients to estimate and
more noise obscuring them.
from synthbench import BenchPipeline, LinearDGP
dgp = LinearDGP(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)
importances = result.metadata["signal_feature_importances"]
print(sum(importances.values())) # 1.0
print(sum(v == 0.0 for v in importances.values())) # uninformative features
Importances are squared coefficient magnitudes, normalised to sum to 1. Features outside the
informative set get exactly 0.0, not a small number — you can filter on equality.
For more than two classes, pass n_classes. The coefficient vector becomes a matrix, one
column per class, and the labels are drawn through a softmax over the resulting scores. The
classes are unordered — any pair can be confused — which is what makes this usable as a general
multiclass benchmark. Importances then sum each feature's squared coefficients across classes,
so a feature counts as informative if it drives any of them.
Full parameter list: LinearDGP in the API reference.