5
5
# License: BSD 3 clause
6
6
7
7
import numpy as np
8
- import numbers
8
+ from numbers import Integral , Real
9
9
from scipy import linalg
10
10
from scipy .sparse .linalg import eigsh
11
11
14
14
from ..utils .validation import (
15
15
check_is_fitted ,
16
16
_check_psd_eigenvalues ,
17
- check_scalar ,
18
17
)
18
+ from ..utils ._param_validation import Interval , StrOptions
19
19
from ..utils .deprecation import deprecated
20
20
from ..exceptions import NotFittedError
21
21
from ..base import BaseEstimator , TransformerMixin , _ClassNamePrefixFeaturesOutMixin
@@ -42,8 +42,8 @@ class KernelPCA(_ClassNamePrefixFeaturesOutMixin, TransformerMixin, BaseEstimato
42
42
n_components : int, default=None
43
43
Number of components. If None, all non-zero components are kept.
44
44
45
- kernel : {'linear', 'poly', \
46
- 'rbf', 'sigmoid', 'cosine', 'precomputed'} , default='linear'
45
+ kernel : {'linear', 'poly', 'rbf', 'sigmoid', 'cosine', 'precomputed'} \
46
+ or callable , default='linear'
47
47
Kernel used for PCA.
48
48
49
49
gamma : float, default=None
@@ -239,6 +239,40 @@ class KernelPCA(_ClassNamePrefixFeaturesOutMixin, TransformerMixin, BaseEstimato
239
239
(1797, 7)
240
240
"""
241
241
242
+ _parameter_constraints = {
243
+ "n_components" : [
244
+ Interval (Integral , 1 , None , closed = "left" ),
245
+ None ,
246
+ ],
247
+ "kernel" : [
248
+ StrOptions ({"linear" , "poly" , "rbf" , "sigmoid" , "cosine" , "precomputed" }),
249
+ callable ,
250
+ ],
251
+ "gamma" : [
252
+ Interval (Real , 0 , None , closed = "left" ),
253
+ None ,
254
+ ],
255
+ "degree" : [Interval (Integral , 0 , None , closed = "left" )],
256
+ "coef0" : [Interval (Real , None , None , closed = "neither" )],
257
+ "kernel_params" : [dict , None ],
258
+ "alpha" : [Interval (Real , 0 , None , closed = "left" )],
259
+ "fit_inverse_transform" : ["boolean" ],
260
+ "eigen_solver" : [StrOptions ({"auto" , "dense" , "arpack" , "randomized" })],
261
+ "tol" : [Interval (Real , 0 , None , closed = "left" )],
262
+ "max_iter" : [
263
+ Interval (Integral , 1 , None , closed = "left" ),
264
+ None ,
265
+ ],
266
+ "iterated_power" : [
267
+ Interval (Integral , 0 , None , closed = "left" ),
268
+ StrOptions ({"auto" }),
269
+ ],
270
+ "remove_zero_eig" : ["boolean" ],
271
+ "random_state" : ["random_state" ],
272
+ "copy_X" : ["boolean" ],
273
+ "n_jobs" : [None , Integral ],
274
+ }
275
+
242
276
def __init__ (
243
277
self ,
244
278
n_components = None ,
@@ -313,7 +347,6 @@ def _fit_transform(self, K):
313
347
if self .n_components is None :
314
348
n_components = K .shape [0 ] # use all dimensions
315
349
else :
316
- check_scalar (self .n_components , "n_components" , numbers .Integral , min_val = 1 )
317
350
n_components = min (K .shape [0 ], self .n_components )
318
351
319
352
# compute eigenvectors
@@ -343,8 +376,6 @@ def _fit_transform(self, K):
343
376
random_state = self .random_state ,
344
377
selection = "module" ,
345
378
)
346
- else :
347
- raise ValueError ("Unsupported value for `eigen_solver`: %r" % eigen_solver )
348
379
349
380
# make sure that the eigenvalues are ok and fix numerical issues
350
381
self .eigenvalues_ = _check_psd_eigenvalues (
@@ -416,6 +447,8 @@ def fit(self, X, y=None):
416
447
self : object
417
448
Returns the instance itself.
418
449
"""
450
+ self ._validate_params ()
451
+
419
452
if self .fit_inverse_transform and self .kernel == "precomputed" :
420
453
raise ValueError ("Cannot fit_inverse_transform with a precomputed kernel." )
421
454
X = self ._validate_data (X , accept_sparse = "csr" , copy = self .copy_X )
0 commit comments