diff --git a/doc/whats_new/v1.4.rst b/doc/whats_new/v1.4.rst index 7af12c870cf45..8881aa10fe185 100644 --- a/doc/whats_new/v1.4.rst +++ b/doc/whats_new/v1.4.rst @@ -253,6 +253,11 @@ Changelog :pr:`26315` and :pr:`27098` by :user:`Mateusz Sokół `, :user:`Olivier Grisel ` and :user:`Edoardo Abati `. +- |Fix| Fixes a bug in :class:`decomposition.KernelPCA` by forcing the output of + the internal :class:`preprocessing.KernelCenterer` to be a default array. When the + arpack solver was used, it would expect an array with a `dtype` attribute. + :pr:`27583` by :user:`Guillaume Lemaitre `. + :mod:`sklearn.ensemble` ....................... diff --git a/sklearn/decomposition/_kernel_pca.py b/sklearn/decomposition/_kernel_pca.py index ccf79e896f210..800b472a9b3a6 100644 --- a/sklearn/decomposition/_kernel_pca.py +++ b/sklearn/decomposition/_kernel_pca.py @@ -432,7 +432,7 @@ def fit(self, X, y=None): raise ValueError("Cannot fit_inverse_transform with a precomputed kernel.") X = self._validate_data(X, accept_sparse="csr", copy=self.copy_X) self.gamma_ = 1 / X.shape[1] if self.gamma is None else self.gamma - self._centerer = KernelCenterer() + self._centerer = KernelCenterer().set_output(transform="default") K = self._get_kernel(X) self._fit_transform(K) diff --git a/sklearn/decomposition/tests/test_kernel_pca.py b/sklearn/decomposition/tests/test_kernel_pca.py index 76f7c4f832086..b222cf4e158ff 100644 --- a/sklearn/decomposition/tests/test_kernel_pca.py +++ b/sklearn/decomposition/tests/test_kernel_pca.py @@ -3,7 +3,8 @@ import numpy as np import pytest -from sklearn.datasets import make_blobs, make_circles +import sklearn +from sklearn.datasets import load_iris, make_blobs, make_circles from sklearn.decomposition import PCA, KernelPCA from sklearn.exceptions import NotFittedError from sklearn.linear_model import Perceptron @@ -551,3 +552,15 @@ def test_kernel_pca_inverse_correct_gamma(): X2_recon = kpca2.inverse_transform(kpca1.transform(X)) assert_allclose(X1_recon, X2_recon) + + +def test_kernel_pca_pandas_output(): + """Check that KernelPCA works with pandas output when the solver is arpack. + + Non-regression test for: + https://github.com/scikit-learn/scikit-learn/issues/27579 + """ + pytest.importorskip("pandas") + X, _ = load_iris(as_frame=True, return_X_y=True) + with sklearn.config_context(transform_output="pandas"): + KernelPCA(n_components=2, eigen_solver="arpack").fit_transform(X)