From 192e543f89cd2dd5831f9f39cbaac6341edad282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20du=20Boisberranger?= Date: Fri, 24 May 2024 12:09:10 +0200 Subject: [PATCH 1/3] inplace kernel centering in KernelPCA --- sklearn/decomposition/_kernel_pca.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sklearn/decomposition/_kernel_pca.py b/sklearn/decomposition/_kernel_pca.py index 88b1bb63a4fb0..a4857df207712 100644 --- a/sklearn/decomposition/_kernel_pca.py +++ b/sklearn/decomposition/_kernel_pca.py @@ -328,7 +328,7 @@ def _get_kernel(self, X, Y=None): def _fit_transform(self, K): """Fit's using kernel K""" # center kernel - K = self._centerer.fit_transform(K) + K = self._centerer.fit(K).transform(K, copy=False) # adjust n_components according to user inputs if self.n_components is None: From cbb13f1df8272eee9c105347f208d28fcd8f75d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20du=20Boisberranger?= Date: Tue, 4 Jun 2024 13:21:56 +0200 Subject: [PATCH 2/3] add some comments --- sklearn/decomposition/_kernel_pca.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sklearn/decomposition/_kernel_pca.py b/sklearn/decomposition/_kernel_pca.py index a4857df207712..1d7191bcd9f09 100644 --- a/sklearn/decomposition/_kernel_pca.py +++ b/sklearn/decomposition/_kernel_pca.py @@ -325,9 +325,9 @@ def _get_kernel(self, X, Y=None): X, Y, metric=self.kernel, filter_params=True, n_jobs=self.n_jobs, **params ) - def _fit_transform(self, K): + def _fit_transform_in_place(self, K): """Fit's using kernel K""" - # center kernel + # center kernel in place K = self._centerer.fit(K).transform(K, copy=False) # adjust n_components according to user inputs @@ -439,7 +439,9 @@ def fit(self, X, y=None): self.gamma_ = 1 / X.shape[1] if self.gamma is None else self.gamma self._centerer = KernelCenterer().set_output(transform="default") K = self._get_kernel(X) - self._fit_transform(K) + # safe to perform in place operations on K because a copy was made before if + # requested. + self._fit_transform_in_place(K) if self.fit_inverse_transform: # no need to use the kernel to transform X, use shortcut expression From d436bcdab52786bbc5592b5fbf4323c3450327dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20du=20Boisberranger?= Date: Thu, 20 Jun 2024 15:01:52 +0200 Subject: [PATCH 3/3] improve comment --- sklearn/decomposition/_kernel_pca.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sklearn/decomposition/_kernel_pca.py b/sklearn/decomposition/_kernel_pca.py index e817dc99842d9..d8910f8f49e5d 100644 --- a/sklearn/decomposition/_kernel_pca.py +++ b/sklearn/decomposition/_kernel_pca.py @@ -438,8 +438,8 @@ def fit(self, X, y=None): self.gamma_ = 1 / X.shape[1] if self.gamma is None else self.gamma self._centerer = KernelCenterer().set_output(transform="default") K = self._get_kernel(X) - # safe to perform in place operations on K because a copy was made before if - # requested. + # When kernel="precomputed", K is X but it's safe to perform in place operations + # on K because a copy was made before if requested by copy_X. self._fit_transform_in_place(K) if self.fit_inverse_transform: