scikit-learn-intelex 2024.1.0__py311-none-manylinux1_x86_64.whl → 2024.4.0__py311-none-manylinux1_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of scikit-learn-intelex might be problematic. Click here for more details.
- {scikit_learn_intelex-2024.1.0.dist-info → scikit_learn_intelex-2024.4.0.dist-info}/METADATA +2 -2
- scikit_learn_intelex-2024.4.0.dist-info/RECORD +101 -0
- sklearnex/__init__.py +9 -7
- sklearnex/_device_offload.py +31 -4
- sklearnex/basic_statistics/__init__.py +2 -1
- sklearnex/basic_statistics/incremental_basic_statistics.py +288 -0
- sklearnex/basic_statistics/tests/test_incremental_basic_statistics.py +386 -0
- sklearnex/cluster/dbscan.py +6 -4
- sklearnex/conftest.py +63 -0
- sklearnex/{preview/decomposition → covariance}/__init__.py +19 -19
- sklearnex/covariance/incremental_covariance.py +130 -0
- sklearnex/covariance/tests/test_incremental_covariance.py +143 -0
- sklearnex/decomposition/pca.py +319 -1
- sklearnex/decomposition/tests/test_pca.py +34 -5
- sklearnex/dispatcher.py +93 -61
- sklearnex/ensemble/_forest.py +81 -97
- sklearnex/ensemble/tests/test_forest.py +15 -19
- sklearnex/linear_model/__init__.py +1 -2
- sklearnex/linear_model/linear.py +275 -347
- sklearnex/{preview/linear_model → linear_model}/logistic_regression.py +83 -50
- sklearnex/linear_model/tests/test_linear.py +40 -5
- sklearnex/linear_model/tests/test_logreg.py +70 -7
- sklearnex/neighbors/__init__.py +1 -1
- sklearnex/neighbors/_lof.py +221 -0
- sklearnex/neighbors/common.py +4 -1
- sklearnex/neighbors/knn_classification.py +47 -137
- sklearnex/neighbors/knn_regression.py +20 -132
- sklearnex/neighbors/knn_unsupervised.py +16 -93
- sklearnex/neighbors/tests/test_neighbors.py +12 -16
- sklearnex/preview/__init__.py +1 -1
- sklearnex/preview/cluster/k_means.py +8 -81
- sklearnex/preview/covariance/covariance.py +51 -16
- sklearnex/preview/covariance/tests/test_covariance.py +18 -5
- sklearnex/spmd/__init__.py +1 -0
- sklearnex/{preview/linear_model → spmd/covariance}/__init__.py +5 -5
- sklearnex/spmd/covariance/covariance.py +21 -0
- sklearnex/spmd/ensemble/forest.py +4 -12
- sklearnex/spmd/linear_model/__init__.py +2 -1
- sklearnex/spmd/linear_model/logistic_regression.py +21 -0
- sklearnex/svm/_common.py +4 -7
- sklearnex/svm/nusvc.py +74 -55
- sklearnex/svm/nusvr.py +9 -56
- sklearnex/svm/svc.py +74 -56
- sklearnex/svm/svr.py +6 -53
- sklearnex/tests/_utils.py +164 -0
- sklearnex/tests/test_memory_usage.py +9 -7
- sklearnex/tests/test_monkeypatch.py +179 -138
- sklearnex/tests/test_n_jobs_support.py +77 -9
- sklearnex/tests/test_parallel.py +6 -8
- sklearnex/tests/test_patching.py +338 -89
- sklearnex/utils/__init__.py +2 -1
- sklearnex/utils/_namespace.py +97 -0
- scikit_learn_intelex-2024.1.0.dist-info/RECORD +0 -97
- sklearnex/neighbors/lof.py +0 -436
- sklearnex/preview/decomposition/pca.py +0 -376
- sklearnex/preview/decomposition/tests/test_preview_pca.py +0 -42
- sklearnex/preview/linear_model/tests/test_preview_logistic_regression.py +0 -59
- sklearnex/tests/_models_info.py +0 -170
- sklearnex/tests/utils/_launch_algorithms.py +0 -118
- {scikit_learn_intelex-2024.1.0.dist-info → scikit_learn_intelex-2024.4.0.dist-info}/LICENSE.txt +0 -0
- {scikit_learn_intelex-2024.1.0.dist-info → scikit_learn_intelex-2024.4.0.dist-info}/WHEEL +0 -0
- {scikit_learn_intelex-2024.1.0.dist-info → scikit_learn_intelex-2024.4.0.dist-info}/top_level.txt +0 -0
sklearnex/dispatcher.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# ==============================================================================
|
|
2
2
|
# Copyright 2021 Intel Corporation
|
|
3
|
+
# Copyright 2024 Fujitsu Limited
|
|
3
4
|
#
|
|
4
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
6
|
# you may not use this file except in compliance with the License.
|
|
@@ -22,7 +23,7 @@ from daal4py.sklearn._utils import daal_check_version, sklearn_check_version
|
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
def _is_new_patching_available():
|
|
25
|
-
return os.environ.get("OFF_ONEDAL_IFACE")
|
|
26
|
+
return os.environ.get("OFF_ONEDAL_IFACE", "0") == "0" and daal_check_version(
|
|
26
27
|
(2021, "P", 300)
|
|
27
28
|
)
|
|
28
29
|
|
|
@@ -32,16 +33,66 @@ def _is_preview_enabled():
|
|
|
32
33
|
|
|
33
34
|
|
|
34
35
|
@lru_cache(maxsize=None)
|
|
35
|
-
def
|
|
36
|
+
def get_patch_map_core(preview=False):
|
|
37
|
+
if preview:
|
|
38
|
+
# use recursion to guarantee that state of preview
|
|
39
|
+
# and non-preview maps are done at the same time.
|
|
40
|
+
# The two lru_cache dicts are actually one underneath.
|
|
41
|
+
# Preview is always secondary. Both sklearnex patch
|
|
42
|
+
# maps are referring to the daal4py dict unless the
|
|
43
|
+
# key has been replaced. Use with caution.
|
|
44
|
+
mapping = get_patch_map_core().copy()
|
|
45
|
+
|
|
46
|
+
if _is_new_patching_available():
|
|
47
|
+
import sklearn.covariance as covariance_module
|
|
48
|
+
|
|
49
|
+
# Preview classes for patching
|
|
50
|
+
from .preview.cluster import KMeans as KMeans_sklearnex
|
|
51
|
+
from .preview.covariance import (
|
|
52
|
+
EmpiricalCovariance as EmpiricalCovariance_sklearnex,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# Since the state of the lru_cache without preview cannot be
|
|
56
|
+
# guaranteed to not have already enabled sklearnex algorithms
|
|
57
|
+
# when preview is used, setting the mapping element[1] to None
|
|
58
|
+
# should NOT be done. This may lose track of the unpatched
|
|
59
|
+
# sklearn estimator or function.
|
|
60
|
+
# KMeans
|
|
61
|
+
cluster_module, _, _ = mapping["kmeans"][0][0]
|
|
62
|
+
sklearn_obj = mapping["kmeans"][0][1]
|
|
63
|
+
mapping.pop("kmeans")
|
|
64
|
+
mapping["kmeans"] = [
|
|
65
|
+
[(cluster_module, "kmeans", KMeans_sklearnex), sklearn_obj]
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
# Covariance
|
|
69
|
+
mapping["empiricalcovariance"] = [
|
|
70
|
+
[
|
|
71
|
+
(
|
|
72
|
+
covariance_module,
|
|
73
|
+
"EmpiricalCovariance",
|
|
74
|
+
EmpiricalCovariance_sklearnex,
|
|
75
|
+
),
|
|
76
|
+
None,
|
|
77
|
+
]
|
|
78
|
+
]
|
|
79
|
+
return mapping
|
|
80
|
+
|
|
36
81
|
from daal4py.sklearn.monkeypatch.dispatcher import _get_map_of_algorithms
|
|
37
82
|
|
|
83
|
+
# NOTE: this is a shallow copy of a dict, modification is dangerous
|
|
38
84
|
mapping = _get_map_of_algorithms().copy()
|
|
39
85
|
|
|
86
|
+
# NOTE: Use of daal4py _get_map_of_algorithms and
|
|
87
|
+
# get_patch_map/get_patch_map_core should not be used concurrently.
|
|
88
|
+
# The setting of elements to None below may cause loss of state
|
|
89
|
+
# when interacting with sklearn. A dictionary key must not be
|
|
90
|
+
# modified but totally replaced, otherwise it will cause chaos.
|
|
91
|
+
# Hence why pop is being used.
|
|
40
92
|
if _is_new_patching_available():
|
|
41
93
|
# Scikit-learn* modules
|
|
42
94
|
import sklearn as base_module
|
|
43
95
|
import sklearn.cluster as cluster_module
|
|
44
|
-
import sklearn.covariance as covariance_module
|
|
45
96
|
import sklearn.decomposition as decomposition_module
|
|
46
97
|
import sklearn.ensemble as ensemble_module
|
|
47
98
|
import sklearn.linear_model as linear_model_module
|
|
@@ -64,80 +115,30 @@ def get_patch_map():
|
|
|
64
115
|
from .utils.parallel import _FuncWrapperOld as _FuncWrapper_sklearnex
|
|
65
116
|
|
|
66
117
|
from .cluster import DBSCAN as DBSCAN_sklearnex
|
|
118
|
+
from .decomposition import PCA as PCA_sklearnex
|
|
67
119
|
from .ensemble import ExtraTreesClassifier as ExtraTreesClassifier_sklearnex
|
|
68
120
|
from .ensemble import ExtraTreesRegressor as ExtraTreesRegressor_sklearnex
|
|
69
121
|
from .ensemble import RandomForestClassifier as RandomForestClassifier_sklearnex
|
|
70
122
|
from .ensemble import RandomForestRegressor as RandomForestRegressor_sklearnex
|
|
71
123
|
from .linear_model import LinearRegression as LinearRegression_sklearnex
|
|
124
|
+
from .linear_model import LogisticRegression as LogisticRegression_sklearnex
|
|
72
125
|
from .neighbors import KNeighborsClassifier as KNeighborsClassifier_sklearnex
|
|
73
126
|
from .neighbors import KNeighborsRegressor as KNeighborsRegressor_sklearnex
|
|
74
127
|
from .neighbors import LocalOutlierFactor as LocalOutlierFactor_sklearnex
|
|
75
128
|
from .neighbors import NearestNeighbors as NearestNeighbors_sklearnex
|
|
76
|
-
|
|
77
|
-
# Preview classes for patching
|
|
78
|
-
from .preview.cluster import KMeans as KMeans_sklearnex
|
|
79
|
-
from .preview.covariance import (
|
|
80
|
-
EmpiricalCovariance as EmpiricalCovariance_sklearnex,
|
|
81
|
-
)
|
|
82
|
-
from .preview.decomposition import PCA as PCA_sklearnex
|
|
83
|
-
from .preview.linear_model import (
|
|
84
|
-
LogisticRegression as LogisticRegression_sklearnex,
|
|
85
|
-
)
|
|
86
129
|
from .svm import SVC as SVC_sklearnex
|
|
87
130
|
from .svm import SVR as SVR_sklearnex
|
|
88
131
|
from .svm import NuSVC as NuSVC_sklearnex
|
|
89
132
|
from .svm import NuSVR as NuSVR_sklearnex
|
|
90
133
|
|
|
91
|
-
# Patch for mapping
|
|
92
|
-
if _is_preview_enabled():
|
|
93
|
-
# PCA
|
|
94
|
-
mapping.pop("pca")
|
|
95
|
-
mapping["pca"] = [[(decomposition_module, "PCA", PCA_sklearnex), None]]
|
|
96
|
-
|
|
97
|
-
# KMeans
|
|
98
|
-
mapping.pop("kmeans")
|
|
99
|
-
mapping["kmeans"] = [
|
|
100
|
-
[
|
|
101
|
-
(
|
|
102
|
-
cluster_module,
|
|
103
|
-
"KMeans",
|
|
104
|
-
KMeans_sklearnex,
|
|
105
|
-
),
|
|
106
|
-
None,
|
|
107
|
-
]
|
|
108
|
-
]
|
|
109
|
-
|
|
110
|
-
# Covariance
|
|
111
|
-
mapping["empiricalcovariance"] = [
|
|
112
|
-
[
|
|
113
|
-
(
|
|
114
|
-
covariance_module,
|
|
115
|
-
"EmpiricalCovariance",
|
|
116
|
-
EmpiricalCovariance_sklearnex,
|
|
117
|
-
),
|
|
118
|
-
None,
|
|
119
|
-
]
|
|
120
|
-
]
|
|
121
|
-
|
|
122
|
-
# LogisticRegression
|
|
123
|
-
mapping.pop("logisticregression")
|
|
124
|
-
mapping.pop("log_reg")
|
|
125
|
-
mapping["log_reg"] = [
|
|
126
|
-
[
|
|
127
|
-
(
|
|
128
|
-
linear_model_module,
|
|
129
|
-
"LogisticRegression",
|
|
130
|
-
LogisticRegression_sklearnex,
|
|
131
|
-
),
|
|
132
|
-
None,
|
|
133
|
-
]
|
|
134
|
-
]
|
|
135
|
-
mapping["logisticregression"] = mapping["log_reg"]
|
|
136
|
-
|
|
137
134
|
# DBSCAN
|
|
138
135
|
mapping.pop("dbscan")
|
|
139
136
|
mapping["dbscan"] = [[(cluster_module, "DBSCAN", DBSCAN_sklearnex), None]]
|
|
140
137
|
|
|
138
|
+
# PCA
|
|
139
|
+
mapping.pop("pca")
|
|
140
|
+
mapping["pca"] = [[(decomposition_module, "PCA", PCA_sklearnex), None]]
|
|
141
|
+
|
|
141
142
|
# SVM
|
|
142
143
|
mapping.pop("svm")
|
|
143
144
|
mapping.pop("svc")
|
|
@@ -161,6 +162,24 @@ def get_patch_map():
|
|
|
161
162
|
]
|
|
162
163
|
mapping["linearregression"] = mapping["linear"]
|
|
163
164
|
|
|
165
|
+
# Logistic Regression
|
|
166
|
+
|
|
167
|
+
mapping.pop("logisticregression")
|
|
168
|
+
mapping.pop("log_reg")
|
|
169
|
+
mapping.pop("logistic")
|
|
170
|
+
mapping.pop("_logistic_regression_path")
|
|
171
|
+
mapping["log_reg"] = [
|
|
172
|
+
[
|
|
173
|
+
(
|
|
174
|
+
linear_model_module,
|
|
175
|
+
"LogisticRegression",
|
|
176
|
+
LogisticRegression_sklearnex,
|
|
177
|
+
),
|
|
178
|
+
None,
|
|
179
|
+
]
|
|
180
|
+
]
|
|
181
|
+
mapping["logisticregression"] = mapping["log_reg"]
|
|
182
|
+
|
|
164
183
|
# kNN
|
|
165
184
|
mapping.pop("knn_classifier")
|
|
166
185
|
mapping.pop("kneighborsclassifier")
|
|
@@ -275,6 +294,19 @@ def get_patch_map():
|
|
|
275
294
|
return mapping
|
|
276
295
|
|
|
277
296
|
|
|
297
|
+
# This is necessary to properly cache the patch_map when
|
|
298
|
+
# using preview.
|
|
299
|
+
def get_patch_map():
|
|
300
|
+
preview = _is_preview_enabled()
|
|
301
|
+
return get_patch_map_core(preview=preview)
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
get_patch_map.cache_clear = get_patch_map_core.cache_clear
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
get_patch_map.cache_info = get_patch_map_core.cache_info
|
|
308
|
+
|
|
309
|
+
|
|
278
310
|
def get_patch_names():
|
|
279
311
|
return list(get_patch_map().keys())
|
|
280
312
|
|
|
@@ -282,10 +314,10 @@ def get_patch_names():
|
|
|
282
314
|
def patch_sklearn(name=None, verbose=True, global_patch=False, preview=False):
|
|
283
315
|
if preview:
|
|
284
316
|
os.environ["SKLEARNEX_PREVIEW"] = "enabled_via_patch_sklearn"
|
|
285
|
-
if not sklearn_check_version("0.
|
|
317
|
+
if not sklearn_check_version("0.24"):
|
|
286
318
|
raise NotImplementedError(
|
|
287
319
|
"Intel(R) Extension for Scikit-learn* patches apply "
|
|
288
|
-
"for scikit-learn >= 0.
|
|
320
|
+
"for scikit-learn >= 0.24 only ..."
|
|
289
321
|
)
|
|
290
322
|
|
|
291
323
|
if global_patch:
|
sklearnex/ensemble/_forest.py
CHANGED
|
@@ -25,8 +25,11 @@ from sklearn.ensemble import ExtraTreesClassifier as sklearn_ExtraTreesClassifie
|
|
|
25
25
|
from sklearn.ensemble import ExtraTreesRegressor as sklearn_ExtraTreesRegressor
|
|
26
26
|
from sklearn.ensemble import RandomForestClassifier as sklearn_RandomForestClassifier
|
|
27
27
|
from sklearn.ensemble import RandomForestRegressor as sklearn_RandomForestRegressor
|
|
28
|
+
from sklearn.ensemble._forest import ForestClassifier as sklearn_ForestClassifier
|
|
29
|
+
from sklearn.ensemble._forest import ForestRegressor as sklearn_ForestRegressor
|
|
28
30
|
from sklearn.ensemble._forest import _get_n_samples_bootstrap
|
|
29
31
|
from sklearn.exceptions import DataConversionWarning
|
|
32
|
+
from sklearn.metrics import accuracy_score
|
|
30
33
|
from sklearn.tree import (
|
|
31
34
|
DecisionTreeClassifier,
|
|
32
35
|
DecisionTreeRegressor,
|
|
@@ -35,37 +38,22 @@ from sklearn.tree import (
|
|
|
35
38
|
)
|
|
36
39
|
from sklearn.tree._tree import Tree
|
|
37
40
|
from sklearn.utils import check_random_state, deprecated
|
|
38
|
-
from sklearn.utils.validation import
|
|
39
|
-
check_array,
|
|
40
|
-
check_consistent_length,
|
|
41
|
-
check_is_fitted,
|
|
42
|
-
check_X_y,
|
|
43
|
-
)
|
|
41
|
+
from sklearn.utils.validation import check_array, check_is_fitted
|
|
44
42
|
|
|
43
|
+
from daal4py.sklearn._n_jobs_support import control_n_jobs
|
|
45
44
|
from daal4py.sklearn._utils import (
|
|
46
45
|
check_tree_nodes,
|
|
47
|
-
control_n_jobs,
|
|
48
46
|
daal_check_version,
|
|
49
|
-
run_with_n_jobs,
|
|
50
47
|
sklearn_check_version,
|
|
51
48
|
)
|
|
52
49
|
from onedal.ensemble import ExtraTreesClassifier as onedal_ExtraTreesClassifier
|
|
53
50
|
from onedal.ensemble import ExtraTreesRegressor as onedal_ExtraTreesRegressor
|
|
54
51
|
from onedal.ensemble import RandomForestClassifier as onedal_RandomForestClassifier
|
|
55
52
|
from onedal.ensemble import RandomForestRegressor as onedal_RandomForestRegressor
|
|
56
|
-
|
|
57
|
-
# try catch needed for changes in structures observed in Scikit-learn around v0.22
|
|
58
|
-
try:
|
|
59
|
-
from sklearn.ensemble._forest import ForestClassifier as sklearn_ForestClassifier
|
|
60
|
-
from sklearn.ensemble._forest import ForestRegressor as sklearn_ForestRegressor
|
|
61
|
-
except ModuleNotFoundError:
|
|
62
|
-
from sklearn.ensemble.forest import ForestClassifier as sklearn_ForestClassifier
|
|
63
|
-
from sklearn.ensemble.forest import ForestRegressor as sklearn_ForestRegressor
|
|
64
|
-
|
|
65
53
|
from onedal.primitives import get_tree_state_cls, get_tree_state_reg
|
|
66
54
|
from onedal.utils import _num_features, _num_samples
|
|
55
|
+
from sklearnex.utils import get_namespace
|
|
67
56
|
|
|
68
|
-
from .._config import get_config
|
|
69
57
|
from .._device_offload import dispatch, wrap_output_data
|
|
70
58
|
from .._utils import PatchingConditionsChain
|
|
71
59
|
|
|
@@ -78,26 +66,15 @@ if sklearn_check_version("1.4"):
|
|
|
78
66
|
class BaseForest(ABC):
|
|
79
67
|
_onedal_factory = None
|
|
80
68
|
|
|
81
|
-
@run_with_n_jobs
|
|
82
69
|
def _onedal_fit(self, X, y, sample_weight=None, queue=None):
|
|
83
|
-
|
|
84
|
-
X,
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
)
|
|
92
|
-
else:
|
|
93
|
-
X, y = check_X_y(
|
|
94
|
-
X,
|
|
95
|
-
y,
|
|
96
|
-
accept_sparse=False,
|
|
97
|
-
dtype=[np.float64, np.float32],
|
|
98
|
-
multi_output=False,
|
|
99
|
-
force_all_finite=False,
|
|
100
|
-
)
|
|
70
|
+
X, y = self._validate_data(
|
|
71
|
+
X,
|
|
72
|
+
y,
|
|
73
|
+
multi_output=False,
|
|
74
|
+
accept_sparse=False,
|
|
75
|
+
dtype=[np.float64, np.float32],
|
|
76
|
+
force_all_finite=False,
|
|
77
|
+
)
|
|
101
78
|
|
|
102
79
|
if sample_weight is not None:
|
|
103
80
|
sample_weight = self.check_sample_weight(sample_weight, X)
|
|
@@ -175,15 +152,6 @@ class BaseForest(ABC):
|
|
|
175
152
|
|
|
176
153
|
return self
|
|
177
154
|
|
|
178
|
-
def _fit_proba(self, X, y, sample_weight=None, queue=None):
|
|
179
|
-
params = self.get_params()
|
|
180
|
-
self.__class__(**params)
|
|
181
|
-
|
|
182
|
-
# We use stock metaestimators below, so the only way
|
|
183
|
-
# to pass a queue is using config_context.
|
|
184
|
-
cfg = get_config()
|
|
185
|
-
cfg["target_offload"] = queue
|
|
186
|
-
|
|
187
155
|
def _save_attributes(self):
|
|
188
156
|
if self.oob_score:
|
|
189
157
|
self.oob_score_ = self._onedal_estimator.oob_score_
|
|
@@ -206,8 +174,6 @@ class BaseForest(ABC):
|
|
|
206
174
|
self._validate_estimator()
|
|
207
175
|
return self
|
|
208
176
|
|
|
209
|
-
# TODO:
|
|
210
|
-
# move to onedal modul.
|
|
211
177
|
def _check_parameters(self):
|
|
212
178
|
if isinstance(self.min_samples_leaf, numbers.Integral):
|
|
213
179
|
if not 1 <= self.min_samples_leaf:
|
|
@@ -455,14 +421,12 @@ class ForestClassifier(sklearn_ForestClassifier, BaseForest):
|
|
|
455
421
|
|
|
456
422
|
# The estimator is checked against the class attribute for conformance.
|
|
457
423
|
# This should only trigger if the user uses this class directly.
|
|
458
|
-
if (
|
|
459
|
-
self.
|
|
460
|
-
and self._onedal_factory != onedal_RandomForestClassifier
|
|
424
|
+
if self.estimator.__class__ == DecisionTreeClassifier and not issubclass(
|
|
425
|
+
self._onedal_factory, onedal_RandomForestClassifier
|
|
461
426
|
):
|
|
462
427
|
self._onedal_factory = onedal_RandomForestClassifier
|
|
463
|
-
elif (
|
|
464
|
-
self.
|
|
465
|
-
and self._onedal_factory != onedal_ExtraTreesClassifier
|
|
428
|
+
elif self.estimator.__class__ == ExtraTreeClassifier and not issubclass(
|
|
429
|
+
self._onedal_factory, onedal_ExtraTreesClassifier
|
|
466
430
|
):
|
|
467
431
|
self._onedal_factory = onedal_ExtraTreesClassifier
|
|
468
432
|
|
|
@@ -554,18 +518,14 @@ class ForestClassifier(sklearn_ForestClassifier, BaseForest):
|
|
|
554
518
|
)
|
|
555
519
|
|
|
556
520
|
if patching_status.get_status():
|
|
557
|
-
|
|
558
|
-
X,
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
)
|
|
566
|
-
else:
|
|
567
|
-
X = check_array(X, dtype=[np.float64, np.float32], force_all_finite=False)
|
|
568
|
-
y = check_array(y, ensure_2d=False, dtype=X.dtype, force_all_finite=False)
|
|
521
|
+
X, y = self._validate_data(
|
|
522
|
+
X,
|
|
523
|
+
y,
|
|
524
|
+
multi_output=True,
|
|
525
|
+
accept_sparse=True,
|
|
526
|
+
dtype=[np.float64, np.float32],
|
|
527
|
+
force_all_finite=False,
|
|
528
|
+
)
|
|
569
529
|
|
|
570
530
|
if y.ndim == 2 and y.shape[1] == 1:
|
|
571
531
|
warnings.warn(
|
|
@@ -659,9 +619,38 @@ class ForestClassifier(sklearn_ForestClassifier, BaseForest):
|
|
|
659
619
|
X,
|
|
660
620
|
)
|
|
661
621
|
|
|
622
|
+
def predict_log_proba(self, X):
|
|
623
|
+
xp, _ = get_namespace(X)
|
|
624
|
+
proba = self.predict_proba(X)
|
|
625
|
+
|
|
626
|
+
if self.n_outputs_ == 1:
|
|
627
|
+
return xp.log(proba)
|
|
628
|
+
|
|
629
|
+
else:
|
|
630
|
+
for k in range(self.n_outputs_):
|
|
631
|
+
proba[k] = xp.log(proba[k])
|
|
632
|
+
|
|
633
|
+
return proba
|
|
634
|
+
|
|
635
|
+
@wrap_output_data
|
|
636
|
+
def score(self, X, y, sample_weight=None):
|
|
637
|
+
return dispatch(
|
|
638
|
+
self,
|
|
639
|
+
"score",
|
|
640
|
+
{
|
|
641
|
+
"onedal": self.__class__._onedal_score,
|
|
642
|
+
"sklearn": sklearn_ForestClassifier.score,
|
|
643
|
+
},
|
|
644
|
+
X,
|
|
645
|
+
y,
|
|
646
|
+
sample_weight=sample_weight,
|
|
647
|
+
)
|
|
648
|
+
|
|
662
649
|
fit.__doc__ = sklearn_ForestClassifier.fit.__doc__
|
|
663
650
|
predict.__doc__ = sklearn_ForestClassifier.predict.__doc__
|
|
664
651
|
predict_proba.__doc__ = sklearn_ForestClassifier.predict_proba.__doc__
|
|
652
|
+
predict_log_proba.__doc__ = sklearn_ForestClassifier.predict_log_proba.__doc__
|
|
653
|
+
score.__doc__ = sklearn_ForestClassifier.score.__doc__
|
|
665
654
|
|
|
666
655
|
def _onedal_cpu_supported(self, method_name, *data):
|
|
667
656
|
class_name = self.__class__.__name__
|
|
@@ -688,7 +677,7 @@ class ForestClassifier(sklearn_ForestClassifier, BaseForest):
|
|
|
688
677
|
]
|
|
689
678
|
)
|
|
690
679
|
|
|
691
|
-
elif method_name in ["predict", "predict_proba"]:
|
|
680
|
+
elif method_name in ["predict", "predict_proba", "score"]:
|
|
692
681
|
X = data[0]
|
|
693
682
|
|
|
694
683
|
patching_status.and_conditions(
|
|
@@ -749,11 +738,11 @@ class ForestClassifier(sklearn_ForestClassifier, BaseForest):
|
|
|
749
738
|
or self.estimator.__class__ == DecisionTreeClassifier,
|
|
750
739
|
"ExtraTrees only supported starting from oneDAL version 2023.1",
|
|
751
740
|
),
|
|
752
|
-
(sample_weight is
|
|
741
|
+
(sample_weight is None, "sample_weight is not supported."),
|
|
753
742
|
]
|
|
754
743
|
)
|
|
755
744
|
|
|
756
|
-
elif method_name in ["predict", "predict_proba"]:
|
|
745
|
+
elif method_name in ["predict", "predict_proba", "score"]:
|
|
757
746
|
X = data[0]
|
|
758
747
|
|
|
759
748
|
patching_status.and_conditions(
|
|
@@ -787,7 +776,6 @@ class ForestClassifier(sklearn_ForestClassifier, BaseForest):
|
|
|
787
776
|
|
|
788
777
|
return patching_status
|
|
789
778
|
|
|
790
|
-
@run_with_n_jobs
|
|
791
779
|
def _onedal_predict(self, X, queue=None):
|
|
792
780
|
X = check_array(
|
|
793
781
|
X,
|
|
@@ -802,17 +790,20 @@ class ForestClassifier(sklearn_ForestClassifier, BaseForest):
|
|
|
802
790
|
res = self._onedal_estimator.predict(X, queue=queue)
|
|
803
791
|
return np.take(self.classes_, res.ravel().astype(np.int64, casting="unsafe"))
|
|
804
792
|
|
|
805
|
-
@run_with_n_jobs
|
|
806
793
|
def _onedal_predict_proba(self, X, queue=None):
|
|
807
794
|
X = check_array(X, dtype=[np.float64, np.float32], force_all_finite=False)
|
|
808
795
|
check_is_fitted(self, "_onedal_estimator")
|
|
809
796
|
|
|
810
|
-
|
|
811
|
-
self._check_n_features(X, reset=False)
|
|
797
|
+
self._check_n_features(X, reset=False)
|
|
812
798
|
if sklearn_check_version("1.0"):
|
|
813
799
|
self._check_feature_names(X, reset=False)
|
|
814
800
|
return self._onedal_estimator.predict_proba(X, queue=queue)
|
|
815
801
|
|
|
802
|
+
def _onedal_score(self, X, y, sample_weight=None, queue=None):
|
|
803
|
+
return accuracy_score(
|
|
804
|
+
y, self._onedal_predict(X, queue=queue), sample_weight=sample_weight
|
|
805
|
+
)
|
|
806
|
+
|
|
816
807
|
|
|
817
808
|
class ForestRegressor(sklearn_ForestRegressor, BaseForest):
|
|
818
809
|
_err = "out_of_bag_error_r2|out_of_bag_error_prediction"
|
|
@@ -847,14 +838,12 @@ class ForestRegressor(sklearn_ForestRegressor, BaseForest):
|
|
|
847
838
|
|
|
848
839
|
# The splitter is checked against the class attribute for conformance
|
|
849
840
|
# This should only trigger if the user uses this class directly.
|
|
850
|
-
if (
|
|
851
|
-
self.
|
|
852
|
-
and self._onedal_factory != onedal_RandomForestRegressor
|
|
841
|
+
if self.estimator.__class__ == DecisionTreeRegressor and not issubclass(
|
|
842
|
+
self._onedal_factory, onedal_RandomForestRegressor
|
|
853
843
|
):
|
|
854
844
|
self._onedal_factory = onedal_RandomForestRegressor
|
|
855
|
-
elif (
|
|
856
|
-
self.
|
|
857
|
-
and self._onedal_factory != onedal_ExtraTreesRegressor
|
|
845
|
+
elif self.estimator.__class__ == ExtraTreeRegressor and not issubclass(
|
|
846
|
+
self._onedal_factory, onedal_ExtraTreesRegressor
|
|
858
847
|
):
|
|
859
848
|
self._onedal_factory = onedal_ExtraTreesRegressor
|
|
860
849
|
|
|
@@ -924,18 +913,14 @@ class ForestRegressor(sklearn_ForestRegressor, BaseForest):
|
|
|
924
913
|
)
|
|
925
914
|
|
|
926
915
|
if patching_status.get_status():
|
|
927
|
-
|
|
928
|
-
X,
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
)
|
|
936
|
-
else:
|
|
937
|
-
X = check_array(X, dtype=[np.float64, np.float32], force_all_finite=False)
|
|
938
|
-
y = check_array(y, ensure_2d=False, dtype=X.dtype, force_all_finite=False)
|
|
916
|
+
X, y = self._validate_data(
|
|
917
|
+
X,
|
|
918
|
+
y,
|
|
919
|
+
multi_output=True,
|
|
920
|
+
accept_sparse=True,
|
|
921
|
+
dtype=[np.float64, np.float32],
|
|
922
|
+
force_all_finite=False,
|
|
923
|
+
)
|
|
939
924
|
|
|
940
925
|
if y.ndim == 2 and y.shape[1] == 1:
|
|
941
926
|
warnings.warn(
|
|
@@ -1060,7 +1045,7 @@ class ForestRegressor(sklearn_ForestRegressor, BaseForest):
|
|
|
1060
1045
|
or self.estimator.__class__ == DecisionTreeClassifier,
|
|
1061
1046
|
"ExtraTrees only supported starting from oneDAL version 2023.1",
|
|
1062
1047
|
),
|
|
1063
|
-
(sample_weight is
|
|
1048
|
+
(sample_weight is None, "sample_weight is not supported."),
|
|
1064
1049
|
]
|
|
1065
1050
|
)
|
|
1066
1051
|
|
|
@@ -1096,7 +1081,6 @@ class ForestRegressor(sklearn_ForestRegressor, BaseForest):
|
|
|
1096
1081
|
|
|
1097
1082
|
return patching_status
|
|
1098
1083
|
|
|
1099
|
-
@run_with_n_jobs
|
|
1100
1084
|
def _onedal_predict(self, X, queue=None):
|
|
1101
1085
|
X = check_array(
|
|
1102
1086
|
X, dtype=[np.float64, np.float32], force_all_finite=False
|
|
@@ -1138,7 +1122,7 @@ class ForestRegressor(sklearn_ForestRegressor, BaseForest):
|
|
|
1138
1122
|
predict.__doc__ = sklearn_ForestRegressor.predict.__doc__
|
|
1139
1123
|
|
|
1140
1124
|
|
|
1141
|
-
@control_n_jobs
|
|
1125
|
+
@control_n_jobs(decorated_methods=["fit", "predict", "predict_proba", "score"])
|
|
1142
1126
|
class RandomForestClassifier(ForestClassifier):
|
|
1143
1127
|
__doc__ = sklearn_RandomForestClassifier.__doc__
|
|
1144
1128
|
_onedal_factory = onedal_RandomForestClassifier
|
|
@@ -1348,7 +1332,7 @@ class RandomForestClassifier(ForestClassifier):
|
|
|
1348
1332
|
self.min_bin_size = min_bin_size
|
|
1349
1333
|
|
|
1350
1334
|
|
|
1351
|
-
@control_n_jobs
|
|
1335
|
+
@control_n_jobs(decorated_methods=["fit", "predict"])
|
|
1352
1336
|
class RandomForestRegressor(ForestRegressor):
|
|
1353
1337
|
__doc__ = sklearn_RandomForestRegressor.__doc__
|
|
1354
1338
|
_onedal_factory = onedal_RandomForestRegressor
|
|
@@ -1549,7 +1533,7 @@ class RandomForestRegressor(ForestRegressor):
|
|
|
1549
1533
|
self.min_bin_size = min_bin_size
|
|
1550
1534
|
|
|
1551
1535
|
|
|
1552
|
-
@control_n_jobs
|
|
1536
|
+
@control_n_jobs(decorated_methods=["fit", "predict", "predict_proba", "score"])
|
|
1553
1537
|
class ExtraTreesClassifier(ForestClassifier):
|
|
1554
1538
|
__doc__ = sklearn_ExtraTreesClassifier.__doc__
|
|
1555
1539
|
_onedal_factory = onedal_ExtraTreesClassifier
|
|
@@ -1759,7 +1743,7 @@ class ExtraTreesClassifier(ForestClassifier):
|
|
|
1759
1743
|
self.min_bin_size = min_bin_size
|
|
1760
1744
|
|
|
1761
1745
|
|
|
1762
|
-
@control_n_jobs
|
|
1746
|
+
@control_n_jobs(decorated_methods=["fit", "predict"])
|
|
1763
1747
|
class ExtraTreesRegressor(ForestRegressor):
|
|
1764
1748
|
__doc__ = sklearn_ExtraTreesRegressor.__doc__
|
|
1765
1749
|
_onedal_factory = onedal_ExtraTreesRegressor
|
|
@@ -45,11 +45,7 @@ def test_sklearnex_import_rf_classifier(dataframe, queue):
|
|
|
45
45
|
assert_allclose([1], _as_numpy(rf.predict([[0, 0, 0, 0]])))
|
|
46
46
|
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
# investigate failure for `dpnp.ndarrays` and `dpctl.tensors` on `GPU`
|
|
50
|
-
@pytest.mark.parametrize(
|
|
51
|
-
"dataframe,queue", get_dataframes_and_queues(device_filter_="cpu")
|
|
52
|
-
)
|
|
48
|
+
@pytest.mark.parametrize("dataframe,queue", get_dataframes_and_queues())
|
|
53
49
|
def test_sklearnex_import_rf_regression(dataframe, queue):
|
|
54
50
|
from sklearnex.ensemble import RandomForestRegressor
|
|
55
51
|
|
|
@@ -59,17 +55,17 @@ def test_sklearnex_import_rf_regression(dataframe, queue):
|
|
|
59
55
|
rf = RandomForestRegressor(max_depth=2, random_state=0).fit(X, y)
|
|
60
56
|
assert "sklearnex" in rf.__module__
|
|
61
57
|
pred = _as_numpy(rf.predict([[0, 0, 0, 0]]))
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
|
|
59
|
+
if queue is not None and queue.sycl_device.is_gpu:
|
|
60
|
+
assert_allclose([-0.011208], pred, atol=1e-2)
|
|
64
61
|
else:
|
|
65
|
-
|
|
62
|
+
if daal_check_version((2024, "P", 0)):
|
|
63
|
+
assert_allclose([-6.971], pred, atol=1e-2)
|
|
64
|
+
else:
|
|
65
|
+
assert_allclose([-6.839], pred, atol=1e-2)
|
|
66
66
|
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
# investigate failure for `dpnp.ndarrays` and `dpctl.tensors` on `GPU`
|
|
70
|
-
@pytest.mark.parametrize(
|
|
71
|
-
"dataframe,queue", get_dataframes_and_queues(device_filter_="cpu")
|
|
72
|
-
)
|
|
68
|
+
@pytest.mark.parametrize("dataframe,queue", get_dataframes_and_queues())
|
|
73
69
|
def test_sklearnex_import_et_classifier(dataframe, queue):
|
|
74
70
|
from sklearnex.ensemble import ExtraTreesClassifier
|
|
75
71
|
|
|
@@ -90,11 +86,7 @@ def test_sklearnex_import_et_classifier(dataframe, queue):
|
|
|
90
86
|
assert_allclose([1], _as_numpy(rf.predict([[0, 0, 0, 0]])))
|
|
91
87
|
|
|
92
88
|
|
|
93
|
-
|
|
94
|
-
# investigate failure for `dpnp.ndarrays` and `dpctl.tensors` on `GPU`
|
|
95
|
-
@pytest.mark.parametrize(
|
|
96
|
-
"dataframe,queue", get_dataframes_and_queues(device_filter_="cpu")
|
|
97
|
-
)
|
|
89
|
+
@pytest.mark.parametrize("dataframe,queue", get_dataframes_and_queues())
|
|
98
90
|
def test_sklearnex_import_et_regression(dataframe, queue):
|
|
99
91
|
from sklearnex.ensemble import ExtraTreesRegressor
|
|
100
92
|
|
|
@@ -114,4 +106,8 @@ def test_sklearnex_import_et_regression(dataframe, queue):
|
|
|
114
106
|
]
|
|
115
107
|
)
|
|
116
108
|
)
|
|
117
|
-
|
|
109
|
+
|
|
110
|
+
if queue is not None and queue.sycl_device.is_gpu:
|
|
111
|
+
assert_allclose([1.909769], pred, atol=1e-2)
|
|
112
|
+
else:
|
|
113
|
+
assert_allclose([0.445], pred, atol=1e-2)
|
|
@@ -16,14 +16,13 @@
|
|
|
16
16
|
|
|
17
17
|
from .coordinate_descent import ElasticNet, Lasso
|
|
18
18
|
from .linear import LinearRegression
|
|
19
|
-
from .
|
|
19
|
+
from .logistic_regression import LogisticRegression
|
|
20
20
|
from .ridge import Ridge
|
|
21
21
|
|
|
22
22
|
__all__ = [
|
|
23
23
|
"Ridge",
|
|
24
24
|
"LinearRegression",
|
|
25
25
|
"LogisticRegression",
|
|
26
|
-
"logistic_regression_path",
|
|
27
26
|
"ElasticNet",
|
|
28
27
|
"Lasso",
|
|
29
28
|
]
|