def test_spline_transformer_unity_decomposition(degree, n_knots, knots, extrapolation): """Test that B-splines are indeed a decomposition of unity. Splines basis functions must sum up to 1 per row, if we stay in between boundaries. """ X = np.linspace(0, 1, 100)[:, None] # make the boundaries 0 and 1 part of X_train, for sure. X_train = np.r_[[[0]], X[::2, :], [[1]]] X_test = X[1::2, :] if extrapolation == "periodic": n_knots = n_knots + degree # periodic splines require degree < n_knots splt = SplineTransformer( n_knots=n_knots, degree=degree, knots=knots, include_bias=True, extrapolation=extrapolation, ) splt.fit(X_train) for X in [X_train, X_test]: assert_allclose(np.sum(splt.transform(X), axis=1), 1)
def test_spline_transformer_n_features_out(n_knots, include_bias, degree): """Test that transform results in n_features_out_ features.""" splt = SplineTransformer(n_knots=n_knots, degree=degree, include_bias=include_bias) X = np.linspace(0, 1, 10)[:, None] splt.fit(X) assert splt.transform(X).shape[1] == splt.n_features_out_
def test_spline_transformer_periodicity_of_extrapolation(knots, n_knots, degree): """Test that the SplineTransformer is periodic for multiple features.""" X_1 = linspace((-1, 0), (1, 5), 10) X_2 = linspace((1, 5), (3, 10), 10) splt = SplineTransformer( knots=knots, n_knots=n_knots, degree=degree, extrapolation="periodic" ) splt.fit(X_1) assert_allclose(splt.transform(X_1), splt.transform(X_2))
def test_spline_transformer_extrapolation(bias, intercept, degree): """Test that B-spline extrapolation works correctly.""" # we use a straight line for that X = np.linspace(-1, 1, 100)[:, None] y = X.squeeze() # 'constant' pipe = Pipeline( [ [ "spline", SplineTransformer( n_knots=4, degree=degree, include_bias=bias, extrapolation="constant", ), ], ["ols", LinearRegression(fit_intercept=intercept)], ] ) pipe.fit(X, y) assert_allclose(pipe.predict([[-10], [5]]), [-1, 1]) # 'linear' pipe = Pipeline( [ [ "spline", SplineTransformer( n_knots=4, degree=degree, include_bias=bias, extrapolation="linear", ), ], ["ols", LinearRegression(fit_intercept=intercept)], ] ) pipe.fit(X, y) assert_allclose(pipe.predict([[-10], [5]]), [-10, 5]) # 'error' splt = SplineTransformer( n_knots=4, degree=degree, include_bias=bias, extrapolation="error" ) splt.fit(X) with pytest.raises(ValueError): splt.transform([[-10]]) with pytest.raises(ValueError): splt.transform([[5]])