diff --git a/econml/sklearn_extensions/linear_model.py b/econml/sklearn_extensions/linear_model.py index 56091899c..2ccba55d6 100644 --- a/econml/sklearn_extensions/linear_model.py +++ b/econml/sklearn_extensions/linear_model.py @@ -437,7 +437,6 @@ def __init__(self, eps=1e-3, n_alphas=100, alphas=None, fit_intercept=True, cv=cv, verbose=verbose, n_jobs=n_jobs, positive=positive, random_state=random_state, selection=selection) self.n_alphas = n_alphas - self.alphas = alphas else: super().__init__( eps=eps, n_alphas=n_alphas, alphas=alphas, @@ -561,7 +560,6 @@ def __init__(self, eps=1e-3, n_alphas=100, alphas=None, fit_intercept=True, cv=cv, verbose=verbose, n_jobs=n_jobs, random_state=random_state, selection=selection) self.n_alphas = n_alphas - self.alphas = alphas else: super().__init__( eps=eps, n_alphas=n_alphas, alphas=alphas, diff --git a/econml/tests/test_linear_model.py b/econml/tests/test_linear_model.py index bf28a5a5b..0608e2f93 100644 --- a/econml/tests/test_linear_model.py +++ b/econml/tests/test_linear_model.py @@ -296,6 +296,35 @@ def test_wrapper_attributes(self): assert wrapper.max_iter == 100 assert wrapper.tol == 0.01 + def test_default_alphas_fits_on_strict_sklearn(self): + # Regression test for #1032. WeightedLassoCV.__init__ used to overwrite + # self.alphas = None after the version-dispatch correctly translated + # the default n_alphas=100 into alphas=100 on the super().__init__() + # call. sklearn 1.9's strict param validation rejected the resulting + # None and SparseLinearDML.fit / DebiasedLasso.fit raised + # InvalidParameterError. With default args, the dispatched alphas value + # must survive to fit time. + from packaging.version import parse + import sklearn + if parse(sklearn.__version__) < parse("1.7"): + self.skipTest("dispatch only active on sklearn 1.7+") + + for cls in (WeightedLassoCV, WeightedMultiTaskLassoCV): + est = cls() + assert est.alphas is not None, \ + f"{cls.__name__}.alphas was clobbered to None by __init__ (#1032)" + assert est.n_alphas == 100, \ + f"{cls.__name__}.n_alphas should be preserved at 100 (#1032)" + + rng = np.random.default_rng(0) + n = 300 + X = rng.normal(size=(n, 3)) + y_1d = rng.normal(size=n) + y_2d = rng.normal(size=(n, 2)) + # neither call should raise sklearn.InvalidParameterError + WeightedLassoCV(cv=3).fit(X, y_1d) + WeightedMultiTaskLassoCV(cv=3).fit(X, y_2d) + ################# # DebiasedLasso # ################# diff --git a/pyproject.toml b/pyproject.toml index 615ce8672..1fd51b14b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,7 @@ dependencies = [ # in addition to dependencies) "numba > 0.53.1", "scipy > 1.4.0", - "scikit-learn >= 1.0, < 1.9", + "scikit-learn >= 1.0, < 1.10", "sparse", "joblib >= 0.13.0", "statsmodels >= 0.10",