Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 32 additions & 39 deletions python/cuml/cuml/kernel_ridge/kernel_ridge.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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


Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 = {
Expand All @@ -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

Expand All @@ -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))
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
12 changes: 0 additions & 12 deletions python/cuml/tests/test_sklearn_compatibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Loading