Skip to content

SparseDGP

Exactly k features drive the target and the remaining p − k are pure noise. Built for feature-selection work: you know the true support, so you can compute precision and recall of a selection method rather than only its predictive error.

Note that k and complexity control different things, and complexity is inverted from what the name suggests. It sets the coefficient scale, so a higher complexity means a weaker signal buried in the same fixed σ = 0.5 noise:

Complexity Coefficient scale Effect
"low" 3.0 Strong signal, easy to detect
"medium" 1.0
"high" 0.3 Weak signal, hard to separate from noise

Sparsity itself never changes with complexity — that is k's job alone.

from synthbench import BenchPipeline, SparseDGP

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

importances = result.metadata["signal_feature_importances"]
print(sum(importances.values()))  # 1.0
print(sum(v == 0.0 for v in importances.values()))  # 7 noise features

Noise features get exactly 0.0, not a small number — that is a contract, not a floating-point accident, so v == 0.0 is a safe test for "outside the true support". k must not exceed the n_features you pass to .run().

For more than two classes, pass n_classes. Each of the k informative features gets one coefficient per class and the labels come from a softmax over those scores, so the classes are unordered. The support is unchanged: the same k features drive every class, and the rest stay exactly 0.0, which keeps the feature-selection ground truth meaningful.

Full parameter list: SparseDGP in the API reference.