Skip to content

FriedmanDGP

The three benchmark functions from Friedman (1991), still in wide use for nonlinear regression comparisons. Their value is comparability: results on Friedman #1 can be read against decades of published numbers.

Pick the variant with function=1, 2, or 3.

Function 1 needs at least 5 features, all ~ U[0,1]:

y = 10·sin(π·x₀·x₁) + 20·(x₂ − 0.5)² + 10·x₃ + 5·x₄ + noise

Function 2 needs at least 4 features, on the original paper's non-unit ranges (x₀ ~ U[0,100], x₁ ~ U[40π, 560π], x₂ ~ U[0,1], x₃ ~ U[1,11]):

y = √(x₀² + (x₁·x₂ − 1/(x₁·x₃))²) + noise

Function 3 uses the same ranges as #2:

y = arctan((x₁·x₂ − 1/(x₁·x₃)) / x₀) + noise

complexity sets the additive noise only — "low" is σ = 0.0 and gives a deterministic signal, "medium" is 1.0, "high" is 3.0. Note that σ = 3.0 means something quite different for function 1 (whose output spans roughly 0–30) than for function 3 (an arctangent, bounded by ±π/2).

from synthbench import BenchPipeline, FriedmanDGP

dgp = FriedmanDGP(
    function=1, 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

Features beyond those the formula uses are N(0,1) padding with exactly 0.0 importance. Formula features share importance equally, which reflects the formula's structure rather than each term's variance contribution — 10·x₃ and 5·x₄ are weighted the same here even though the first moves the target twice as much.

FriedmanDGP is the one DGP that refuses n_classes > 2. These are specific published scalar functions, and the reason to use them is comparability with results reported against them; a multi-output variant would be a different thing wearing the same name. For multiclass use LinearDGP, SparseDGP, TreeDGP, RandomNeuralDGP, or GeometricDGP.

Full parameter list: FriedmanDGP in the API reference.