# GAMRegressor


Scikit-learn compatible GAM regressor.


Usage

``` python
GAMRegressor(
    formula=None,
    *,
    family=None,
    method="GCV",
    select=False,
)
```


[GAMRegressor](GAMRegressor.md#whittaker.GAMRegressor) wraps [whittaker.gam.GAM](GAM.md#whittaker.GAM) behind the scikit-learn `BaseEstimator` / `RegressorMixin` interface, exposing the familiar `fit(X, y)`, `predict(X)`, `get_params()`/`set_params()` methods instead of [GAM](GAM.md#whittaker.GAM)'s formula-and-data-dictionary API. This makes it a drop-in estimator anywhere scikit-learn expects one: inside a `Pipeline` (e.g. chained after a `StandardScaler` or a `ColumnTransformer`), as the estimator tuned by `GridSearchCV` or `RandomizedSearchCV` (searching over `formula`, [method](CausalGAM.md#whittaker.CausalGAM.method), or `select`), scored with `cross_val_score` or [cross_validate](cross_validate.md#whittaker.cross_validate), or combined with other regressors inside a `VotingRegressor` or a stacking ensemble.

Because raw numpy feature columns carry no names, [GAMRegressor](GAMRegressor.md#whittaker.GAMRegressor) assigns synthetic names `x0`, `x1`, …, `x{n_features - 1}` to the columns of `X` in order (see `_make_feature_names`). Unless an explicit `formula` is supplied, a default additive formula with one smooth `s(xi)` per feature is built automatically (see `_build_formula`), giving

 \eta = \beta_0 + \sum\_{i=0}^{p-1} f_i(x_i), 

connected to the mean response through the link implied by `family`. Supplying `formula` overrides this default; it accepts either a bare right-hand side such as `"s(x0) + s(x1)"` -- in which case the response name `"y"` is prepended automatically to form `"y ~ s(x0) + s(x1)"` -- or a complete formula already containing `"~"`, which is used as-is. This makes it possible to mix smooth and linear terms, use interactions (`x0:x1`), or omit features, exactly as with [GAM](GAM.md#whittaker.GAM) directly.


## Parameters


`formula: str = None`  
GAM formula for the right-hand side (e.g. `"s(x0) + s(x1)"`), or a complete formula containing `"~"` (e.g. `"y ~ s(x0) + x1"`). If it contains `"~"` it is used verbatim; otherwise the response `"y"` is prepended. If `None` (the default), a formula with one `s(xi)` smooth per input feature is generated automatically.

`family: Family = None`  
Response distribution family passed through to the underlying [GAM](GAM.md#whittaker.GAM). Defaults to [Gaussian()](Gaussian.md#whittaker.Gaussian) (identity link), i.e. ordinary least-squares-style additive regression.

`method: str = ``"GCV"`  
Smoothing parameter selection criterion forwarded to [GAM.fit](GAM.md#whittaker.GAM.fit): `"GCV"` (default), `"REML"`, or `"ML"`. See [whittaker.gam.GAM.fit](GAM.md#whittaker.GAM.fit) for the meaning of each option.

`select: bool = ``False`  
If `True`, enable double-penalty smooth selection (an extra penalty that can shrink an entire smooth to zero), forwarded to [GAM.fit](GAM.md#whittaker.GAM.fit). Defaults to `False`.


## Notes

The hyperparameters exposed to `GridSearchCV`/`RandomizedSearchCV` via `get_params()` are exactly the constructor arguments -- `formula`, `family`, [method](CausalGAM.md#whittaker.CausalGAM.method), and `select` -- because scikit-learn's `get_params` introspects the `__init__` signature. The smoothing parameters `\lambda_j` themselves are never tunable hyperparameters of [GAMRegressor](GAMRegressor.md#whittaker.GAMRegressor): they are always chosen internally, for the given [method](CausalGAM.md#whittaker.CausalGAM.method), during `fit()`. To tune smoothing behavior via cross-validation, search over [method](CausalGAM.md#whittaker.CausalGAM.method) and `select` (which change how `\lambda_j` are selected) rather than trying to pass `\lambda_j` values directly.


## Examples


``` python
import numpy as np
from whittaker.sklearn import GAMRegressor

rng = np.random.default_rng(0)
X = rng.uniform(-2, 2, size=(200, 2))
y = np.sin(X[:, 0]) + 0.5 * X[:, 1] ** 2 + rng.normal(scale=0.2, size=200)

reg = GAMRegressor(formula="s(x0) + s(x1)")
reg.fit(X, y)
reg.predict(X[:5])
```


    array([0.89871156, 0.83528962, 2.44803234, 0.8379585 , 1.77990934])


[GAMRegressor](GAMRegressor.md#whittaker.GAMRegressor) works inside scikit-learn model-selection tooling, such as `sklearn.model_selection.cross_val_score` (requires `pip install scikit-learn`):


``` python
from sklearn.model_selection import cross_val_score

scores = cross_val_score(GAMRegressor(), X, y, cv=5)
scores
```


    array([0.95659528, 0.97558708, 0.95126233, 0.94950696, 0.97066468])


## Methods

| Name | Description |
|----|----|
| [fit()](#fit) | Fit the GAM regressor. |
| [predict()](#predict) | Predict target values for X. |

------------------------------------------------------------------------


### fit()


Fit the GAM regressor.


Usage

``` python
fit(
    X,
    y,
    **fit_params,
)
```


Validates `X` and `y` with scikit-learn's `check_X_y`, assigns synthetic feature names, builds the model formula (from `formula` if given, otherwise one `s(xi)` smooth per feature), and fits an internal [whittaker.gam.GAM](GAM.md#whittaker.GAM) to the resulting data dictionary using [method](CausalGAM.md#whittaker.CausalGAM.method) and `select`.


#### Parameters


`X: numpy.ndarray`  
Feature matrix, shape `(n_samples, n_features)`. Coerced to `float64` and checked by `sklearn.utils.validation.check_X_y`, which rejects non-finite values, non-2-D input, and samples with zero features.

`y: numpy.ndarray`  
Target values, shape `(n_samples,)`. Coerced to `float64` alongside `X` by `check_X_y`; must have the same number of samples as `X`.

`**fit_params: Any`  
Accepted for compatibility with the scikit-learn `fit` signature but currently unused.


#### Returns


`GAMRegressor`  
Returns `self`, with fitted attributes `n_features_in_` (number of input features), `feature_names_` (the synthetic `x0`, `x1`, … names used internally), and `gam_` (the underlying fitted [whittaker.gam.GAM](GAM.md#whittaker.GAM) instance), so that scikit-learn's `fit(...).predict(...)` chaining works as usual.


------------------------------------------------------------------------


### predict()


Predict target values for X.


Usage

``` python
predict(X)
```


Requires `fit()` to have been called first (checked via `sklearn.utils.validation. check_is_fitted`). Converts `X` into the internal data dictionary using the feature names recorded during `fit()`, and delegates to the fitted [GAM](GAM.md#whittaker.GAM)'s `predict()`.


#### Parameters


`X: numpy.ndarray`  
Feature matrix, shape `(n_samples, n_features_in_)`, where `n_features_in_` matches the number of features seen during `fit()`. Coerced to `float64` and validated by `sklearn.utils.validation.check_array`.


#### Returns


`NDArray`  
Predicted mean response values, shape `(n_samples,)`, in the original (non-linear predictor) scale.
