dswah / pyGAM

[HELP REQUESTED] Generalized Additive Models in Python
https://pygam.readthedocs.io
Apache License 2.0
857 stars 157 forks source link

Can't clone LinearGAM estimator object for sklearn cross-validation #291

Open vmgustavo opened 3 years ago

vmgustavo commented 3 years ago

Bug

Can't use LinearGAM with ScikitLearn cross_validate as it get's a RuntimeError for not being able to clone the model.

The only estimator out of all the GAM options that can't be cloned is LinearGAM

To Reproduce

from pygam import LinearGAM, s from pygam.datasets import toy_interaction

X, y = toy_interaction(return_X_y=True)

gam = LinearGAM(s(0, by=1))

cross_validate(gam, X, y, cv=5, scoring='neg_mean_absolute_error')

~/miniconda3/envs/sbid/lib/python3.8/site-packages/sklearn/model_selection/_validation.py in (.0) 242 scores = parallel( 243 delayed(_fit_and_score)( --> 244 clone(estimator), X, y, scorers, train, test, verbose, None, 245 fit_params, return_train_score=return_train_score, 246 return_times=True, return_estimator=return_estimator,

~/miniconda3/envs/sbid/lib/python3.8/site-packages/sklearn/utils/validation.py in inner_f(*args, kwargs) 70 FutureWarning) 71 kwargs.update({k: arg for k, arg in zip(sig.parameters, args)}) ---> 72 return f(kwargs) 73 return inner_f 74

~/miniconda3/envs/sbid/lib/python3.8/site-packages/sklearn/base.py in clone(estimator, safe) 94 param2 = params_set[name] 95 if param1 is not param2: ---> 96 raise RuntimeError('Cannot clone object %s, as the constructor ' 97 'either does not set or modifies parameter %s' % 98 (estimator, name))

RuntimeError: Cannot clone object LinearGAM(callbacks=['deviance', 'diffs'], fit_intercept=True, max_iter=100, scale=None, terms=s(0), tol=0.0001, verbose=False), as the constructor either does not set or modifies parameter callbacks


* If only LinearGAM is not able to be cloned
```python
from sklearn.base import clone

from pygam import LinearGAM, GammaGAM, InvGaussGAM, LogisticGAM, PoissonGAM, ExpectileGAM

for estimator in [LinearGAM, GammaGAM, InvGaussGAM, LogisticGAM, PoissonGAM, ExpectileGAM]:
    try:
        clone(estimator())
    except Exception as e:
        print(estimator.__name__, e.__class__.__name__)
LinearGAM RuntimeError
RuntimeError: Cannot clone object LinearGAM(callbacks=['deviance', 'diffs'], fit_intercept=True, 
   max_iter=100, scale=None, terms='auto', tol=0.0001, verbose=False), as the constructor either does not set or modifies parameter callbacks

Environment

Python 3.8.5 pygam==0.8.0

lucasmazim commented 2 years ago

Same error here!

thistleknot commented 2 years ago

I am having this issue as well

miguelfmc commented 1 year ago

Working on this right now.

It seems like this has to do with a small bug in the __init__ method of LinearGAM in which the callbacks parameter is not getting passed when calling super().__init__().

I tried the examples shared by @vmgustavo and got no runtime errors:

Example 1


from sklearn.model_selection import cross_validate
from pygam import LinearGAM, s
from pygam.datasets import toy_interaction

X, y = toy_interaction(return_X_y=True)

gam = LinearGAM(s(0, by=1))

cross_validate(gam, X, y, cv=5, scoring='neg_mean_absolute_error')

Example 2


from sklearn.base import clone

from pygam import LinearGAM, GammaGAM, InvGaussGAM, LogisticGAM, PoissonGAM, ExpectileGAM

for estimator in [LinearGAM, GammaGAM, InvGaussGAM, LogisticGAM, PoissonGAM, ExpectileGAM]:
    try:
        clone(estimator())
    except Exception as e:
        print(estimator.__name__, e.__class__.__name__)

Environment

Python 3.6.13 scikit-learn 0.24.2

Issue seems to be fixed so I will submit PR shortly.

miguelfmc commented 1 year ago

Just noticed that there was an open PR addressing this as well as the mutable default callbacks values:

267

Cain-Iriving commented 7 months ago

from sklearn.model_selection import cross_validate from pygam import LinearGAM, s from pygam.datasets import toy_interaction X, y = toy_interaction(return_X_y=True) gam = LinearGAM(s(0, by=1)) cross_validate(gam, X, y, cv=5, scoring='neg_mean_absolute_error')

It doesn't work.

Cannot clone object LinearGAM(callbacks=['deviance', 'diffs'], fit_intercept=True, max_iter=100, scale=None, terms=s(0), tol=0.0001, verbose=False), as the constructor either does not set or modifies parameter callbacks

jgu115 commented 1 month ago

Hi, to confirm, has the issue been fixed in any new release? I still see the problem so to confirm if the issue is fixed in any release

phantom-duck commented 1 month ago

+1 I can also confirm this. LinearGAM throws the error, while LogisticGAM for example does not. As far as I can tell the issue is still the bug described by @miguelfmc , which has not been fixed, at least in the master branch. Notice that in the following part of the code the callbacks parameter is not passed anywhere:

https://github.com/dswah/pyGAM/blob/a6c14e48c34310567fdea1698735081b834b742d/pygam/pygam.py#L2448-L2469