Skip to content

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.