Skip to content

Commit a5b4e69

Browse files
Support for sklearn 1.6 conformance testing (#2465)
* tweaks to logistic_path to match sklearn * follow ups * sklearn 1.4 gpu conformance fix attempt * restore svm changes and move ridge checks to sklearnex * update deselected tests file * add 4 more deselections * apply black formatting * xpass/xfail deselections...I give up * one more xfail --------- Co-authored-by: Alexander Andreev <[email protected]>
1 parent 63cfefe commit a5b4e69

File tree

4 files changed

+45
-11
lines changed

4 files changed

+45
-11
lines changed

daal4py/sklearn/linear_model/logistic_path.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -359,14 +359,16 @@ def __logistic_regression_path(
359359
y_bin = np.ones(y.shape, dtype=X.dtype)
360360
# for compute_class_weight
361361

362-
if solver in ["lbfgs", "newton-cg"]:
362+
if solver == "liblinear" or (
363+
not sklearn_check_version("1.6") and solver not in ["lbfgs", "newton-cg"]
364+
):
365+
mask_classes = np.array([-1, 1])
366+
y_bin[~mask] = -1.0
367+
else:
363368
# HalfBinomialLoss, used for those solvers, represents y in [0, 1] instead
364369
# of in [-1, 1].
365370
mask_classes = np.array([0, 1])
366371
y_bin[~mask] = 0.0
367-
else:
368-
mask_classes = np.array([-1, 1])
369-
y_bin[~mask] = -1.0
370372
else:
371373
mask_classes = np.array([-1, 1])
372374
mask = y == pos_class
@@ -388,7 +390,11 @@ def __logistic_regression_path(
388390

389391
else:
390392
if sklearn_check_version("1.1"):
391-
if solver in ["sag", "saga", "lbfgs", "newton-cg"]:
393+
if sklearn_check_version("1.6"):
394+
solver_list = ["sag", "saga", "lbfgs", "newton-cg", "newton-cholesky"]
395+
else:
396+
solver_list = ["sag", "saga", "lbfgs", "newton-cg"]
397+
if solver in solver_list:
392398
# SAG, lbfgs and newton-cg multinomial solvers need LabelEncoder,
393399
# not LabelBinarizer, i.e. y as a 1d-array of integers.
394400
# LabelEncoder also saves memory compared to LabelBinarizer, especially
@@ -488,7 +494,11 @@ def __logistic_regression_path(
488494

489495
if multi_class == "multinomial":
490496
# fmin_l_bfgs_b and newton-cg accepts only ravelled parameters.
491-
if solver in ["lbfgs", "newton-cg"]:
497+
if sklearn_check_version("1.6"):
498+
solver_list = ["lbfgs", "newton-cg", "newton-cholesky"]
499+
else:
500+
solver_list = ["lbfgs", "newton-cg"]
501+
if solver in solver_list:
492502
if _dal_ready and classes.size == 2:
493503
w0 = w0[-1:, :]
494504
if sklearn_check_version("1.1"):
@@ -753,7 +763,11 @@ def _func_(x, *args):
753763
else:
754764
n_classes = max(2, classes.size)
755765
if sklearn_check_version("1.1"):
756-
if solver in ["lbfgs", "newton-cg"]:
766+
if sklearn_check_version("1.6"):
767+
solver_list = ["lbfgs", "newton-cg", "newton-cholesky"]
768+
else:
769+
solver_list = ["lbfgs", "newton-cg"]
770+
if solver in solver_list:
757771
multi_w0 = np.reshape(w0, (n_classes, -1), order="F")
758772
else:
759773
multi_w0 = w0

deselected_tests.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,21 @@ deselected_tests:
342342
# to CI parameters, as parameter validation is globally handled in sklearn version 1.2 onward
343343
- cluster/tests/test_dbscan.py::test_dbscan_params_validation
344344

345+
# From sklearn 1.6, need to resolve logreg bug from joblib with_parallel_backend.
346+
# Removal of this deselection will result in test_logistic fails (this one will pass).
347+
- feature_selection/tests/test_rfe.py::test_rfe_with_joblib_threading_backend
348+
# Failing tests since sklearn 1.6
349+
- tests/test_common.py::test_estimators[CalibratedClassifierCV(cv=3,estimator=LogisticRegression(C=1))-check_sample_weight_equivalence_on_dense_data]
350+
- tests/test_common.py::test_estimators[ExtraTreesClassifier(n_estimators=5)-check_sample_weight_equivalence_on_dense_data]
351+
- tests/test_common.py::test_estimators[ExtraTreesRegressor(n_estimators=5)-check_sample_weight_equivalence_on_dense_data]
352+
- utils/tests/test_estimator_checks.py::test_xfail_count_with_no_fast_fail
353+
# XFail vs XPass differs between scikit-learn and scikit-learn-intelex since 1.6
354+
- tests/test_common.py::test_estimators[LinearRegression()-check_sample_weight_equivalence_on_dense_data] <1.7
355+
- tests/test_common.py::test_estimators[LogisticRegression(max_iter=5)-check_sample_weight_equivalence_on_dense_data]
356+
- tests/test_common.py::test_estimators[LogisticRegression(max_iter=5,solver='newton-cg')-check_sample_weight_equivalence_on_dense_data]
357+
- tests/test_common.py::test_estimators[NuSVC()-check_class_weight_classifiers]
358+
- tests/test_common.py::test_estimators[CalibratedClassifierCV(estimator=LogisticRegression(C=1))-check_sample_weights_invariance(kind=ones)]
359+
345360
# --------------------------------------------------------
346361
# No need to test daal4py patching
347362
reduced_tests:

onedal/linear_model/linear_model.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,4 @@ def fit(self, X, y, queue=None):
340340
packed_coefficients[:, 0],
341341
)
342342

343-
if self.coef_.shape[0] == 1 and y.ndim == 1:
344-
self.coef_ = self.coef_.ravel()
345-
self.intercept_ = self.intercept_[0]
346-
347343
return self

sklearnex/linear_model/ridge.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,15 @@ def _onedal_fit(self, X, y, sample_weight, queue=None):
325325
self._onedal_estimator.fit(X, y, queue=queue)
326326
self._save_attributes()
327327

328+
if sklearn_check_version("1.6"):
329+
if y.ndim == 1 or y.shape[1] == 1:
330+
self.coef_ = self.coef_.ravel()
331+
self.intercept_ = self.intercept_[0]
332+
else:
333+
if self.coef_.shape[0] == 1 and y.ndim == 1:
334+
self.coef_ = self.coef_.ravel()
335+
self.intercept_ = self.intercept_[0]
336+
328337
def _onedal_predict(self, X, queue=None):
329338
X = validate_data(self, X, accept_sparse=False, reset=False)
330339

0 commit comments

Comments
 (0)