diff --git a/python/cuml/cuml/kernel_ridge/kernel_ridge.py b/python/cuml/cuml/kernel_ridge/kernel_ridge.py index db75aa7909..a01882bcf4 100644 --- a/python/cuml/cuml/kernel_ridge/kernel_ridge.py +++ b/python/cuml/cuml/kernel_ridge/kernel_ridge.py @@ -9,7 +9,6 @@ from cupy import linalg from cupyx import geterr, lapack, seterr -from cuml.common import input_to_cuml_array from cuml.common.array_descriptor import CumlArrayDescriptor from cuml.common.doc_utils import generate_docstring from cuml.internals import reflect @@ -22,7 +21,7 @@ to_gpu, ) from cuml.internals.mixins import RegressorMixin -from cuml.internals.validation import check_features, check_is_fitted +from cuml.internals.validation import check_inputs, check_is_fitted from cuml.metrics import pairwise_kernels @@ -53,7 +52,7 @@ def _solve_cholesky_kernel(K, y, alpha, sample_weight=None): n_samples = K.shape[0] n_targets = y.shape[1] - K = cp.array(K, dtype=np.float64) + K = cp.asarray(K, dtype=np.float64) alpha = cp.atleast_1d(alpha) one_alpha = alpha.size == 1 @@ -266,6 +265,10 @@ def __init__( self.coef0 = coef0 self.kernel_params = kernel_params + @staticmethod + def _more_static_tags(): + return {"multioutput": True} + def _get_kernel(self, X, Y=None): if isinstance(self.kernel, str): params = { @@ -277,42 +280,35 @@ def _get_kernel(self, X, Y=None): params = self.kernel_params or {} return pairwise_kernels( X, Y, metric=self.kernel, filter_params=True, **params - ) + ).to_output("cupy") @generate_docstring() - @reflect(reset=True) + @reflect(reset="type") def fit( self, X, y, sample_weight=None, *, convert_dtype=True ) -> "KernelRidge": - ravel = False - if len(y.shape) == 1: - y = y.reshape(-1, 1) - ravel = True - - X_m = input_to_cuml_array( + X, y, sample_weight, index = check_inputs( + self, X, - convert_to_dtype=(np.float32 if convert_dtype else None), - check_dtype=[np.float32, np.float64], - ).array - - y_m = input_to_cuml_array( y, - check_dtype=X_m.dtype, - convert_to_dtype=(X_m.dtype if convert_dtype else None), - check_rows=X_m.shape[0], - ).array - - if X.shape[1] < 1: - raise ValueError("X matrix must have at least a column") + sample_weight, + dtype=("float32", "float64"), + convert_dtype=convert_dtype, + accept_multi_output=True, + return_index=True, + reset=True, + ) + if ravel := (y.ndim == 1): + y = y.reshape(-1, 1) - K = self._get_kernel(X_m) + K = self._get_kernel(X) dual_coef = _solve_cholesky_kernel( - K, cp.asarray(y_m), cp.asarray(self.alpha), sample_weight - ).astype(X_m.dtype, copy=False) + K, y, cp.asarray(self.alpha), sample_weight + ).astype(X.dtype, copy=False) if ravel: dual_coef = dual_coef.ravel() - self.X_fit_ = X_m + self.X_fit_ = CumlArray(data=X, index=index) self.dual_coef_ = CumlArray(data=dual_coef) return self @@ -335,17 +331,14 @@ def predict(self, X, *, convert_dtype=True): Returns predicted values. """ check_is_fitted(self) - check_features(self, X) - - dtype = self.X_fit_.dtype - - X_m = input_to_cuml_array( + X = check_inputs( + self, X, - check_dtype=dtype, - convert_to_dtype=(dtype if convert_dtype else None), - check_cols=self.n_features_in_, - ).array - - K = cp.asarray(self._get_kernel(X_m, self.X_fit_), dtype=dtype) + dtype=self.X_fit_.dtype, + convert_dtype=convert_dtype, + ) + K = self._get_kernel(X, self.X_fit_.to_output("cupy")).astype( + X.dtype, copy=False + ) dual_coef = self.dual_coef_.to_output("cupy") - return CumlArray(cp.dot(K, dual_coef)) + return CumlArray(data=cp.dot(K, dual_coef)) diff --git a/python/cuml/cuml_accel_tests/upstream/scikit-learn/xfail-list.yaml b/python/cuml/cuml_accel_tests/upstream/scikit-learn/xfail-list.yaml index af02fd39f7..1ed1626590 100644 --- a/python/cuml/cuml_accel_tests/upstream/scikit-learn/xfail-list.yaml +++ b/python/cuml/cuml_accel_tests/upstream/scikit-learn/xfail-list.yaml @@ -806,18 +806,7 @@ - reason: KernelRidge input handling and validation marker: cuml_accel_kernel_ridge_estimator_checks tests: - - "sklearn.tests.test_common::test_estimators[KernelRidge()-check_dtype_object]" - - "sklearn.tests.test_common::test_estimators[KernelRidge()-check_estimators_empty_data_messages]" - - "sklearn.tests.test_common::test_estimators[KernelRidge()-check_estimators_nan_inf]" - "sklearn.tests.test_common::test_estimators[KernelRidge()-check_estimators_pickle(readonly_memmap=True)]" - - "sklearn.tests.test_common::test_estimators[KernelRidge()-check_regressor_data_not_an_array]" - - "sklearn.tests.test_common::test_estimators[KernelRidge()-check_regressors_train(readonly_memmap=True)]" - - "sklearn.tests.test_common::test_estimators[KernelRidge()-check_regressors_train(readonly_memmap=True,X_dtype=float32)]" - - "sklearn.tests.test_common::test_estimators[KernelRidge()-check_regressors_train]" - - "sklearn.tests.test_common::test_estimators[KernelRidge()-check_requires_y_none]" - - "sklearn.tests.test_common::test_estimators[KernelRidge()-check_sample_weights_not_an_array]" - - "sklearn.tests.test_common::test_estimators[KernelRidge()-check_sample_weights_pandas_series]" - - "sklearn.tests.test_common::test_estimators[KernelRidge()-check_supervised_y_no_nan]" - reason: cuml.accel does not support callable initialization for KMeans marker: cuml_accel_kmeans_callable_init tests: diff --git a/python/cuml/tests/test_sklearn_compatibility.py b/python/cuml/tests/test_sklearn_compatibility.py index ae92a374d8..f932a24ab0 100644 --- a/python/cuml/tests/test_sklearn_compatibility.py +++ b/python/cuml/tests/test_sklearn_compatibility.py @@ -97,19 +97,7 @@ }, KernelRidge: { "check_estimator_tags_renamed": "No support for modern tags infrastructure", - "check_sample_weights_pandas_series": "KernelRidge does not handle pandas Series sample weights", - "check_sample_weights_not_an_array": "KernelRidge does not handle non-array sample weights", - "check_all_zero_sample_weights_error": "KernelRidge does not validate all-zero sample weights", - "check_dtype_object": "KernelRidge does not handle object dtype", - "check_estimators_empty_data_messages": "KernelRidge does not handle empty data", - "check_estimators_nan_inf": "KernelRidge does not check for NaN and inf", - "check_regressors_train": "KernelRidge does not handle list inputs", - "check_regressors_train(readonly_memmap=True)": "KernelRidge does not handle readonly memmap", - "check_regressors_train(readonly_memmap=True,X_dtype=float32)": "KernelRidge does not handle readonly memmap with float32", "check_regressor_data_not_an_array": "KernelRidge does not handle non-array data", - "check_supervised_y_2d": "KernelRidge does not handle 2D y", - "check_supervised_y_no_nan": "KernelRidge does not check for NaN in y", - "check_requires_y_none": "KernelRidge does not handle y=None", }, LogisticRegression: { "check_estimator_tags_renamed": "No support for modern tags infrastructure",