def test_spline_transformer_periodic_splines_smoothness(degree): """Test that spline transformation is smooth at first / last knot.""" X = np.linspace(-2, 10, 10_000)[:, None] transformer = SplineTransformer(degree=degree, extrapolation="periodic", knots=[[0.0], [1.0], [3.0], [4.0], [5.0], [8.0]]) Xt = transformer.fit_transform(X) delta = (X.max() - X.min()) / len(X) tol = 10 * delta dXt = Xt # We expect splines of degree `degree` to be (`degree`-1) times # continuously differentiable. I.e. for d = 0, ..., `degree` - 1 the d-th # derivative should be continous. This is the case if the (d+1)-th # numerical derivative is reasonably small (smaller than `tol` in absolute # value). We thus compute d-th numeric derivatives for d = 1, ..., `degree` # and compare them to `tol`. # # Note that the 0-th derivative is the function itself, such that we are # also checking its continuity. for d in range(1, degree + 1): # Check continuity of the (d-1)-th derivative diff = np.diff(dXt, axis=0) assert np.abs(diff).max() < tol # Compute d-th numeric derivative dXt = diff / delta # As degree `degree` splines are not `degree` times continously # differentiable at the knots, the `degree + 1`-th numeric derivative # should have spikes at the knots. diff = np.diff(dXt, axis=0) assert np.abs(diff).max() > 1
def test_spline_transformer_periodic_splines_periodicity(): """ Test if shifted knots result in the same transformation up to permutation. """ X = np.linspace(0, 10, 101)[:, None] transformer_1 = SplineTransformer(degree=3, extrapolation="periodic", knots=[[0.0], [1.0], [3.0], [4.0], [5.0], [8.0]]) transformer_2 = SplineTransformer(degree=3, extrapolation="periodic", knots=[[1.0], [3.0], [4.0], [5.0], [8.0], [9.0]]) Xt_1 = transformer_1.fit_transform(X) Xt_2 = transformer_2.fit_transform(X) assert_allclose(Xt_1, Xt_2[:, [4, 0, 1, 2, 3]])
def test_spline_transformer_periodic_spline_backport(): """Test that the backport of extrapolate="periodic" works correctly""" X = np.linspace(-2, 3.5, 10)[:, None] degree = 2 # Use periodic extrapolation backport in SplineTransformer transformer = SplineTransformer(degree=degree, extrapolation="periodic", knots=[[-1.0], [0.0], [1.0]]) Xt = transformer.fit_transform(X) # Use periodic extrapolation in BSpline coef = np.array([[1.0, 0.0], [0.0, 1.0], [1.0, 0.0], [0.0, 1.0]]) spl = BSpline(np.arange(-3, 4), coef, degree, "periodic") Xspl = spl(X[:, 0]) assert_allclose(Xt, Xspl)
def test_spline_transformer_kbindiscretizer(): """Test that a B-spline of degree=0 is equivalent to KBinsDiscretizer.""" rng = np.random.RandomState(97531) X = rng.randn(200).reshape(200, 1) n_bins = 5 n_knots = n_bins + 1 splt = SplineTransformer( n_knots=n_knots, degree=0, knots="quantile", include_bias=True ) splines = splt.fit_transform(X) kbd = KBinsDiscretizer(n_bins=n_bins, encode="onehot-dense", strategy="quantile") kbins = kbd.fit_transform(X) # Though they should be exactly equal, we test approximately with high # accuracy. assert_allclose(splines, kbins, rtol=1e-13)
# parametrized by their polynomial degree and the positions of the knots. The # :class:`~preprocessing.SplineTransformer` implements a B-spline basis. # # .. figure:: ../linear_model/images/sphx_glr_plot_polynomial_interpolation_001.png # :target: ../linear_model/plot_polynomial_interpolation.html # :align: center # # The following code shows splines in action, for more information, please # refer to the :ref:`User Guide <spline_transformer>`. import numpy as np from sklearn.preprocessing import SplineTransformer X = np.arange(5).reshape(5, 1) spline = SplineTransformer(degree=2, n_knots=3) spline.fit_transform(X) ############################################################################## # Quantile Regressor # -------------------------------------------------------------------------- # Quantile regression estimates the median or other quantiles of :math:`y` # conditional on :math:`X`, while ordinary least squares (OLS) estimates the # conditional mean. # # As a linear model, the new :class:`~linear_model.QuantileRegressor` gives # linear predictions :math:`\hat{y}(w, X) = Xw` for the :math:`q`-th quantile, # :math:`q \in (0, 1)`. The weights or coefficients :math:`w` are then found by # the following minimization problem: # # .. math::