scikit-learn-intelex 2025.0.0__py312-none-manylinux_2_28_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.
- daal4py/__init__.py +73 -0
- daal4py/__main__.py +58 -0
- daal4py/_daal4py.cpython-312-x86_64-linux-gnu.so +0 -0
- daal4py/doc/third-party-programs.txt +424 -0
- daal4py/mb/__init__.py +19 -0
- daal4py/mb/model_builders.py +377 -0
- daal4py/mpi_transceiver.cpython-312-x86_64-linux-gnu.so +0 -0
- daal4py/sklearn/__init__.py +40 -0
- daal4py/sklearn/_n_jobs_support.py +242 -0
- daal4py/sklearn/_utils.py +241 -0
- daal4py/sklearn/cluster/__init__.py +20 -0
- daal4py/sklearn/cluster/dbscan.py +165 -0
- daal4py/sklearn/cluster/k_means.py +597 -0
- daal4py/sklearn/cluster/tests/test_dbscan.py +109 -0
- daal4py/sklearn/decomposition/__init__.py +19 -0
- daal4py/sklearn/decomposition/_pca.py +524 -0
- daal4py/sklearn/ensemble/AdaBoostClassifier.py +192 -0
- daal4py/sklearn/ensemble/GBTDAAL.py +318 -0
- daal4py/sklearn/ensemble/__init__.py +27 -0
- daal4py/sklearn/ensemble/_forest.py +1397 -0
- daal4py/sklearn/ensemble/tests/test_decision_forest.py +206 -0
- daal4py/sklearn/linear_model/__init__.py +29 -0
- daal4py/sklearn/linear_model/_coordinate_descent.py +848 -0
- daal4py/sklearn/linear_model/_linear.py +272 -0
- daal4py/sklearn/linear_model/_ridge.py +325 -0
- daal4py/sklearn/linear_model/coordinate_descent.py +17 -0
- daal4py/sklearn/linear_model/linear.py +17 -0
- daal4py/sklearn/linear_model/logistic_loss.py +195 -0
- daal4py/sklearn/linear_model/logistic_path.py +1026 -0
- daal4py/sklearn/linear_model/ridge.py +17 -0
- daal4py/sklearn/linear_model/tests/test_linear.py +196 -0
- daal4py/sklearn/linear_model/tests/test_ridge.py +69 -0
- daal4py/sklearn/manifold/__init__.py +19 -0
- daal4py/sklearn/manifold/_t_sne.py +405 -0
- daal4py/sklearn/metrics/__init__.py +20 -0
- daal4py/sklearn/metrics/_pairwise.py +155 -0
- daal4py/sklearn/metrics/_ranking.py +210 -0
- daal4py/sklearn/model_selection/__init__.py +19 -0
- daal4py/sklearn/model_selection/_split.py +309 -0
- daal4py/sklearn/model_selection/tests/test_split.py +56 -0
- daal4py/sklearn/monkeypatch/__init__.py +0 -0
- daal4py/sklearn/monkeypatch/dispatcher.py +232 -0
- daal4py/sklearn/monkeypatch/tests/_models_info.py +161 -0
- daal4py/sklearn/monkeypatch/tests/test_monkeypatch.py +71 -0
- daal4py/sklearn/monkeypatch/tests/test_patching.py +87 -0
- daal4py/sklearn/monkeypatch/tests/utils/_launch_algorithms.py +118 -0
- daal4py/sklearn/neighbors/__init__.py +21 -0
- daal4py/sklearn/neighbors/_base.py +503 -0
- daal4py/sklearn/neighbors/_classification.py +139 -0
- daal4py/sklearn/neighbors/_regression.py +74 -0
- daal4py/sklearn/neighbors/_unsupervised.py +55 -0
- daal4py/sklearn/neighbors/tests/test_kneighbors.py +113 -0
- daal4py/sklearn/svm/__init__.py +19 -0
- daal4py/sklearn/svm/svm.py +734 -0
- daal4py/sklearn/utils/__init__.py +21 -0
- daal4py/sklearn/utils/base.py +75 -0
- daal4py/sklearn/utils/tests/test_utils.py +51 -0
- daal4py/sklearn/utils/validation.py +693 -0
- onedal/__init__.py +83 -0
- onedal/_config.py +53 -0
- onedal/_device_offload.py +229 -0
- onedal/_onedal_py_dpc.cpython-312-x86_64-linux-gnu.so +0 -0
- onedal/_onedal_py_host.cpython-312-x86_64-linux-gnu.so +0 -0
- onedal/_onedal_py_spmd_dpc.cpython-312-x86_64-linux-gnu.so +0 -0
- onedal/basic_statistics/__init__.py +20 -0
- onedal/basic_statistics/basic_statistics.py +107 -0
- onedal/basic_statistics/incremental_basic_statistics.py +160 -0
- onedal/basic_statistics/tests/test_basic_statistics.py +298 -0
- onedal/basic_statistics/tests/test_incremental_basic_statistics.py +196 -0
- onedal/cluster/__init__.py +27 -0
- onedal/cluster/dbscan.py +110 -0
- onedal/cluster/kmeans.py +560 -0
- onedal/cluster/kmeans_init.py +115 -0
- onedal/cluster/tests/test_dbscan.py +125 -0
- onedal/cluster/tests/test_kmeans.py +88 -0
- onedal/cluster/tests/test_kmeans_init.py +93 -0
- onedal/common/_base.py +38 -0
- onedal/common/_estimator_checks.py +47 -0
- onedal/common/_mixin.py +62 -0
- onedal/common/_policy.py +59 -0
- onedal/common/_spmd_policy.py +30 -0
- onedal/common/hyperparameters.py +116 -0
- onedal/common/tests/test_policy.py +75 -0
- onedal/covariance/__init__.py +20 -0
- onedal/covariance/covariance.py +125 -0
- onedal/covariance/incremental_covariance.py +146 -0
- onedal/covariance/tests/test_covariance.py +50 -0
- onedal/covariance/tests/test_incremental_covariance.py +122 -0
- onedal/datatypes/__init__.py +19 -0
- onedal/datatypes/_data_conversion.py +95 -0
- onedal/datatypes/tests/test_data.py +235 -0
- onedal/decomposition/__init__.py +20 -0
- onedal/decomposition/incremental_pca.py +204 -0
- onedal/decomposition/pca.py +186 -0
- onedal/decomposition/tests/test_incremental_pca.py +198 -0
- onedal/ensemble/__init__.py +29 -0
- onedal/ensemble/forest.py +720 -0
- onedal/ensemble/tests/test_random_forest.py +97 -0
- onedal/linear_model/__init__.py +27 -0
- onedal/linear_model/incremental_linear_model.py +258 -0
- onedal/linear_model/linear_model.py +329 -0
- onedal/linear_model/logistic_regression.py +249 -0
- onedal/linear_model/tests/test_incremental_linear_regression.py +168 -0
- onedal/linear_model/tests/test_incremental_ridge_regression.py +107 -0
- onedal/linear_model/tests/test_linear_regression.py +149 -0
- onedal/linear_model/tests/test_logistic_regression.py +95 -0
- onedal/linear_model/tests/test_ridge.py +95 -0
- onedal/neighbors/__init__.py +19 -0
- onedal/neighbors/neighbors.py +778 -0
- onedal/neighbors/tests/test_knn_classification.py +49 -0
- onedal/primitives/__init__.py +27 -0
- onedal/primitives/get_tree.py +25 -0
- onedal/primitives/kernel_functions.py +153 -0
- onedal/primitives/tests/test_kernel_functions.py +159 -0
- onedal/spmd/__init__.py +25 -0
- onedal/spmd/_base.py +30 -0
- onedal/spmd/basic_statistics/__init__.py +20 -0
- onedal/spmd/basic_statistics/basic_statistics.py +30 -0
- onedal/spmd/basic_statistics/incremental_basic_statistics.py +69 -0
- onedal/spmd/cluster/__init__.py +28 -0
- onedal/spmd/cluster/dbscan.py +23 -0
- onedal/spmd/cluster/kmeans.py +56 -0
- onedal/spmd/covariance/__init__.py +20 -0
- onedal/spmd/covariance/covariance.py +26 -0
- onedal/spmd/covariance/incremental_covariance.py +82 -0
- onedal/spmd/decomposition/__init__.py +20 -0
- onedal/spmd/decomposition/incremental_pca.py +117 -0
- onedal/spmd/decomposition/pca.py +26 -0
- onedal/spmd/ensemble/__init__.py +19 -0
- onedal/spmd/ensemble/forest.py +28 -0
- onedal/spmd/linear_model/__init__.py +21 -0
- onedal/spmd/linear_model/incremental_linear_model.py +97 -0
- onedal/spmd/linear_model/linear_model.py +30 -0
- onedal/spmd/linear_model/logistic_regression.py +38 -0
- onedal/spmd/neighbors/__init__.py +19 -0
- onedal/spmd/neighbors/neighbors.py +75 -0
- onedal/svm/__init__.py +19 -0
- onedal/svm/svm.py +556 -0
- onedal/svm/tests/test_csr_svm.py +351 -0
- onedal/svm/tests/test_nusvc.py +204 -0
- onedal/svm/tests/test_nusvr.py +210 -0
- onedal/svm/tests/test_svc.py +168 -0
- onedal/svm/tests/test_svr.py +243 -0
- onedal/tests/test_common.py +41 -0
- onedal/tests/utils/_dataframes_support.py +168 -0
- onedal/tests/utils/_device_selection.py +107 -0
- onedal/utils/__init__.py +49 -0
- onedal/utils/_array_api.py +91 -0
- onedal/utils/validation.py +432 -0
- scikit_learn_intelex-2025.0.0.dist-info/LICENSE.txt +202 -0
- scikit_learn_intelex-2025.0.0.dist-info/METADATA +231 -0
- scikit_learn_intelex-2025.0.0.dist-info/RECORD +278 -0
- scikit_learn_intelex-2025.0.0.dist-info/WHEEL +5 -0
- scikit_learn_intelex-2025.0.0.dist-info/top_level.txt +3 -0
- sklearnex/__init__.py +65 -0
- sklearnex/__main__.py +58 -0
- sklearnex/_config.py +98 -0
- sklearnex/_device_offload.py +121 -0
- sklearnex/_utils.py +109 -0
- sklearnex/basic_statistics/__init__.py +20 -0
- sklearnex/basic_statistics/basic_statistics.py +140 -0
- sklearnex/basic_statistics/incremental_basic_statistics.py +288 -0
- sklearnex/basic_statistics/tests/test_basic_statistics.py +251 -0
- sklearnex/basic_statistics/tests/test_incremental_basic_statistics.py +384 -0
- sklearnex/cluster/__init__.py +20 -0
- sklearnex/cluster/dbscan.py +192 -0
- sklearnex/cluster/k_means.py +383 -0
- sklearnex/cluster/tests/test_dbscan.py +38 -0
- sklearnex/cluster/tests/test_kmeans.py +153 -0
- sklearnex/conftest.py +73 -0
- sklearnex/covariance/__init__.py +19 -0
- sklearnex/covariance/incremental_covariance.py +368 -0
- sklearnex/covariance/tests/test_incremental_covariance.py +226 -0
- sklearnex/decomposition/__init__.py +19 -0
- sklearnex/decomposition/pca.py +414 -0
- sklearnex/decomposition/tests/test_pca.py +58 -0
- sklearnex/dispatcher.py +543 -0
- sklearnex/doc/third-party-programs.txt +424 -0
- sklearnex/ensemble/__init__.py +29 -0
- sklearnex/ensemble/_forest.py +2016 -0
- sklearnex/ensemble/tests/test_forest.py +120 -0
- sklearnex/glob/__main__.py +72 -0
- sklearnex/glob/dispatcher.py +101 -0
- sklearnex/linear_model/__init__.py +32 -0
- sklearnex/linear_model/coordinate_descent.py +30 -0
- sklearnex/linear_model/incremental_linear.py +463 -0
- sklearnex/linear_model/incremental_ridge.py +418 -0
- sklearnex/linear_model/linear.py +302 -0
- sklearnex/linear_model/logistic_path.py +17 -0
- sklearnex/linear_model/logistic_regression.py +403 -0
- sklearnex/linear_model/ridge.py +24 -0
- sklearnex/linear_model/tests/test_incremental_linear.py +203 -0
- sklearnex/linear_model/tests/test_incremental_ridge.py +153 -0
- sklearnex/linear_model/tests/test_linear.py +142 -0
- sklearnex/linear_model/tests/test_logreg.py +134 -0
- sklearnex/manifold/__init__.py +19 -0
- sklearnex/manifold/t_sne.py +21 -0
- sklearnex/manifold/tests/test_tsne.py +26 -0
- sklearnex/metrics/__init__.py +23 -0
- sklearnex/metrics/pairwise.py +22 -0
- sklearnex/metrics/ranking.py +20 -0
- sklearnex/metrics/tests/test_metrics.py +39 -0
- sklearnex/model_selection/__init__.py +21 -0
- sklearnex/model_selection/split.py +22 -0
- sklearnex/model_selection/tests/test_model_selection.py +34 -0
- sklearnex/neighbors/__init__.py +27 -0
- sklearnex/neighbors/_lof.py +231 -0
- sklearnex/neighbors/common.py +310 -0
- sklearnex/neighbors/knn_classification.py +226 -0
- sklearnex/neighbors/knn_regression.py +203 -0
- sklearnex/neighbors/knn_unsupervised.py +170 -0
- sklearnex/neighbors/tests/test_neighbors.py +80 -0
- sklearnex/preview/__init__.py +17 -0
- sklearnex/preview/covariance/__init__.py +19 -0
- sklearnex/preview/covariance/covariance.py +133 -0
- sklearnex/preview/covariance/tests/test_covariance.py +66 -0
- sklearnex/preview/decomposition/__init__.py +19 -0
- sklearnex/preview/decomposition/incremental_pca.py +228 -0
- sklearnex/preview/decomposition/tests/test_incremental_pca.py +266 -0
- sklearnex/preview/linear_model/__init__.py +19 -0
- sklearnex/preview/linear_model/ridge.py +419 -0
- sklearnex/preview/linear_model/tests/test_ridge.py +102 -0
- sklearnex/spmd/__init__.py +25 -0
- sklearnex/spmd/basic_statistics/__init__.py +20 -0
- sklearnex/spmd/basic_statistics/basic_statistics.py +21 -0
- sklearnex/spmd/basic_statistics/incremental_basic_statistics.py +30 -0
- sklearnex/spmd/basic_statistics/tests/test_basic_statistics_spmd.py +107 -0
- sklearnex/spmd/basic_statistics/tests/test_incremental_basic_statistics_spmd.py +307 -0
- sklearnex/spmd/cluster/__init__.py +30 -0
- sklearnex/spmd/cluster/dbscan.py +50 -0
- sklearnex/spmd/cluster/kmeans.py +21 -0
- sklearnex/spmd/cluster/tests/test_dbscan_spmd.py +97 -0
- sklearnex/spmd/cluster/tests/test_kmeans_spmd.py +172 -0
- sklearnex/spmd/covariance/__init__.py +20 -0
- sklearnex/spmd/covariance/covariance.py +21 -0
- sklearnex/spmd/covariance/incremental_covariance.py +37 -0
- sklearnex/spmd/covariance/tests/test_covariance_spmd.py +107 -0
- sklearnex/spmd/covariance/tests/test_incremental_covariance_spmd.py +184 -0
- sklearnex/spmd/decomposition/__init__.py +20 -0
- sklearnex/spmd/decomposition/incremental_pca.py +30 -0
- sklearnex/spmd/decomposition/pca.py +21 -0
- sklearnex/spmd/decomposition/tests/test_incremental_pca_spmd.py +269 -0
- sklearnex/spmd/decomposition/tests/test_pca_spmd.py +128 -0
- sklearnex/spmd/ensemble/__init__.py +19 -0
- sklearnex/spmd/ensemble/forest.py +71 -0
- sklearnex/spmd/ensemble/tests/test_forest_spmd.py +265 -0
- sklearnex/spmd/linear_model/__init__.py +21 -0
- sklearnex/spmd/linear_model/incremental_linear_model.py +35 -0
- sklearnex/spmd/linear_model/linear_model.py +21 -0
- sklearnex/spmd/linear_model/logistic_regression.py +21 -0
- sklearnex/spmd/linear_model/tests/test_incremental_linear_spmd.py +329 -0
- sklearnex/spmd/linear_model/tests/test_linear_regression_spmd.py +145 -0
- sklearnex/spmd/linear_model/tests/test_logistic_regression_spmd.py +166 -0
- sklearnex/spmd/neighbors/__init__.py +19 -0
- sklearnex/spmd/neighbors/neighbors.py +25 -0
- sklearnex/spmd/neighbors/tests/test_neighbors_spmd.py +288 -0
- sklearnex/svm/__init__.py +29 -0
- sklearnex/svm/_common.py +328 -0
- sklearnex/svm/nusvc.py +332 -0
- sklearnex/svm/nusvr.py +148 -0
- sklearnex/svm/svc.py +360 -0
- sklearnex/svm/svr.py +149 -0
- sklearnex/svm/tests/test_svm.py +93 -0
- sklearnex/tests/_utils.py +328 -0
- sklearnex/tests/_utils_spmd.py +198 -0
- sklearnex/tests/test_common.py +54 -0
- sklearnex/tests/test_config.py +43 -0
- sklearnex/tests/test_memory_usage.py +291 -0
- sklearnex/tests/test_monkeypatch.py +276 -0
- sklearnex/tests/test_n_jobs_support.py +103 -0
- sklearnex/tests/test_parallel.py +48 -0
- sklearnex/tests/test_patching.py +385 -0
- sklearnex/tests/test_run_to_run_stability.py +296 -0
- sklearnex/utils/__init__.py +19 -0
- sklearnex/utils/_array_api.py +82 -0
- sklearnex/utils/parallel.py +59 -0
- sklearnex/utils/tests/test_finite.py +89 -0
- sklearnex/utils/validation.py +17 -0
|
@@ -0,0 +1,848 @@
|
|
|
1
|
+
# ==============================================================================
|
|
2
|
+
# Copyright 2020 Intel Corporation
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
# ==============================================================================
|
|
16
|
+
|
|
17
|
+
import numbers
|
|
18
|
+
|
|
19
|
+
import numpy as np
|
|
20
|
+
from scipy import sparse as sp
|
|
21
|
+
from sklearn.linear_model._coordinate_descent import ElasticNet as ElasticNet_original
|
|
22
|
+
from sklearn.linear_model._coordinate_descent import Lasso as Lasso_original
|
|
23
|
+
from sklearn.utils import check_array, check_X_y
|
|
24
|
+
|
|
25
|
+
import daal4py
|
|
26
|
+
from daal4py.sklearn._utils import (
|
|
27
|
+
PatchingConditionsChain,
|
|
28
|
+
get_patch_message,
|
|
29
|
+
getFPType,
|
|
30
|
+
make2d,
|
|
31
|
+
sklearn_check_version,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
from .._n_jobs_support import control_n_jobs
|
|
35
|
+
|
|
36
|
+
if sklearn_check_version("1.0") and not sklearn_check_version("1.2"):
|
|
37
|
+
from sklearn.linear_model._base import _deprecate_normalize
|
|
38
|
+
if sklearn_check_version("1.1") and not sklearn_check_version("1.2"):
|
|
39
|
+
from sklearn.utils import check_scalar
|
|
40
|
+
|
|
41
|
+
import logging
|
|
42
|
+
|
|
43
|
+
# only for compliance with Sklearn
|
|
44
|
+
import warnings
|
|
45
|
+
|
|
46
|
+
from sklearn.exceptions import ConvergenceWarning
|
|
47
|
+
from sklearn.preprocessing import normalize
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _daal4py_check(self, X, y, check_input):
|
|
51
|
+
_fptype = getFPType(X)
|
|
52
|
+
|
|
53
|
+
# check alpha
|
|
54
|
+
if self.alpha == 0:
|
|
55
|
+
warnings.warn(
|
|
56
|
+
"With alpha=0, this algorithm does not converge "
|
|
57
|
+
"well. You are advised to use the LinearRegression "
|
|
58
|
+
"estimator",
|
|
59
|
+
stacklevel=2,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
# check l1_ratio
|
|
63
|
+
if (
|
|
64
|
+
not isinstance(self.l1_ratio, numbers.Number)
|
|
65
|
+
or self.l1_ratio < 0
|
|
66
|
+
or self.l1_ratio > 1
|
|
67
|
+
):
|
|
68
|
+
raise ValueError(
|
|
69
|
+
"l1_ratio must be between 0 and 1; " f"got l1_ratio={self.l1_ratio}"
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
# check precompute
|
|
73
|
+
if isinstance(self.precompute, np.ndarray):
|
|
74
|
+
if check_input:
|
|
75
|
+
check_array(self.precompute, dtype=_fptype)
|
|
76
|
+
self.precompute = make2d(self.precompute)
|
|
77
|
+
else:
|
|
78
|
+
if self.precompute not in [False, True, "auto"]:
|
|
79
|
+
raise ValueError(
|
|
80
|
+
"precompute should be one of True, False, "
|
|
81
|
+
"'auto' or array-like. Got %r" % self.precompute
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# check selection
|
|
85
|
+
if self.selection not in ["random", "cyclic"]:
|
|
86
|
+
raise ValueError("selection should be either random or cyclic.")
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _daal4py_fit_enet(self, X, y_, check_input):
|
|
90
|
+
# appropriate checks
|
|
91
|
+
_daal4py_check(self, X, y_, check_input)
|
|
92
|
+
X = make2d(X)
|
|
93
|
+
y = make2d(y_)
|
|
94
|
+
_fptype = getFPType(X)
|
|
95
|
+
|
|
96
|
+
# only for dual_gap computation, it is not required for Intel(R) oneAPI
|
|
97
|
+
# Data Analytics Library
|
|
98
|
+
self._X = X
|
|
99
|
+
self.n_features_in_ = X.shape[1]
|
|
100
|
+
self._y = y
|
|
101
|
+
|
|
102
|
+
penalty_L1 = np.asarray(self.alpha * self.l1_ratio, dtype=X.dtype)
|
|
103
|
+
penalty_L2 = np.asarray(self.alpha * (1.0 - self.l1_ratio), dtype=X.dtype)
|
|
104
|
+
if penalty_L1.size != 1 or penalty_L2.size != 1:
|
|
105
|
+
raise ValueError("alpha or l1_ratio length is wrong")
|
|
106
|
+
penalty_L1 = penalty_L1.reshape((1, -1))
|
|
107
|
+
penalty_L2 = penalty_L2.reshape((1, -1))
|
|
108
|
+
|
|
109
|
+
# normalizing and centering
|
|
110
|
+
X_offset = np.zeros(X.shape[1], dtype=X.dtype)
|
|
111
|
+
X_scale = np.ones(X.shape[1], dtype=X.dtype)
|
|
112
|
+
if y.ndim == 1:
|
|
113
|
+
y_offset = X.dtype.type(0)
|
|
114
|
+
else:
|
|
115
|
+
y_offset = np.zeros(y.shape[1], dtype=X.dtype)
|
|
116
|
+
|
|
117
|
+
if sklearn_check_version("1.2"):
|
|
118
|
+
_normalize = False
|
|
119
|
+
else:
|
|
120
|
+
_normalize = self._normalize if sklearn_check_version("1.0") else self.normalize
|
|
121
|
+
if self.fit_intercept:
|
|
122
|
+
X_offset = np.average(X, axis=0)
|
|
123
|
+
if _normalize:
|
|
124
|
+
if self.copy_X:
|
|
125
|
+
X = np.copy(X) - X_offset
|
|
126
|
+
else:
|
|
127
|
+
X -= X_offset
|
|
128
|
+
X, X_scale = normalize(X, axis=0, copy=False, return_norm=True)
|
|
129
|
+
y_offset = np.average(y, axis=0)
|
|
130
|
+
y = y - y_offset
|
|
131
|
+
|
|
132
|
+
# only for compliance with Sklearn
|
|
133
|
+
if (
|
|
134
|
+
isinstance(self.precompute, np.ndarray)
|
|
135
|
+
and self.fit_intercept
|
|
136
|
+
and (
|
|
137
|
+
not np.allclose(X_offset, np.zeros(X.shape[1]))
|
|
138
|
+
or _normalize
|
|
139
|
+
and not np.allclose(X_scale, np.ones(X.shape[1]))
|
|
140
|
+
)
|
|
141
|
+
):
|
|
142
|
+
if sklearn_check_version("1.4"):
|
|
143
|
+
warnings.warn(
|
|
144
|
+
"Gram matrix was provided but X was centered"
|
|
145
|
+
" to fit intercept: recomputing Gram matrix.",
|
|
146
|
+
UserWarning,
|
|
147
|
+
)
|
|
148
|
+
else:
|
|
149
|
+
warnings.warn(
|
|
150
|
+
"Gram matrix was provided but X was centered"
|
|
151
|
+
" to fit intercept, "
|
|
152
|
+
"or X was normalized : recomputing Gram matrix.",
|
|
153
|
+
UserWarning,
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
mse_alg = daal4py.optimization_solver_mse(
|
|
157
|
+
numberOfTerms=X.shape[0], fptype=_fptype, method="defaultDense"
|
|
158
|
+
)
|
|
159
|
+
mse_alg.setup(X, y, None)
|
|
160
|
+
|
|
161
|
+
cd_solver = daal4py.optimization_solver_coordinate_descent(
|
|
162
|
+
function=mse_alg,
|
|
163
|
+
fptype=_fptype,
|
|
164
|
+
method="defaultDense",
|
|
165
|
+
selection=self.selection,
|
|
166
|
+
seed=0 if self.random_state is None else self.random_state,
|
|
167
|
+
nIterations=self.max_iter,
|
|
168
|
+
positive=self.positive,
|
|
169
|
+
accuracyThreshold=self.tol,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
# set warm_start
|
|
173
|
+
if self.warm_start and hasattr(self, "coef_") and isinstance(self.coef_, np.ndarray):
|
|
174
|
+
n_rows = y.shape[1]
|
|
175
|
+
n_cols = X.shape[1] + 1
|
|
176
|
+
inputArgument = np.zeros((n_rows, n_cols), dtype=_fptype)
|
|
177
|
+
for i in range(n_rows):
|
|
178
|
+
inputArgument[i][0] = self.intercept_ if (n_rows == 1) else self.intercept_[i]
|
|
179
|
+
inputArgument[i][1:] = (
|
|
180
|
+
self.coef_[:].copy(order="C")
|
|
181
|
+
if (n_rows == 1)
|
|
182
|
+
else self.coef_[i, :].copy(order="C")
|
|
183
|
+
)
|
|
184
|
+
cd_solver.setup(inputArgument)
|
|
185
|
+
doUse_condition = self.copy_X is False or (
|
|
186
|
+
self.fit_intercept and _normalize and self.copy_X
|
|
187
|
+
)
|
|
188
|
+
elastic_net_alg = daal4py.elastic_net_training(
|
|
189
|
+
fptype=_fptype,
|
|
190
|
+
method="defaultDense",
|
|
191
|
+
interceptFlag=(self.fit_intercept is True),
|
|
192
|
+
dataUseInComputation="doUse" if doUse_condition else "doNotUse",
|
|
193
|
+
penaltyL1=penalty_L1,
|
|
194
|
+
penaltyL2=penalty_L2,
|
|
195
|
+
optimizationSolver=cd_solver,
|
|
196
|
+
)
|
|
197
|
+
try:
|
|
198
|
+
if isinstance(self.precompute, np.ndarray):
|
|
199
|
+
elastic_net_res = elastic_net_alg.compute(
|
|
200
|
+
data=X, dependentVariables=y, gramMatrix=self.precompute
|
|
201
|
+
)
|
|
202
|
+
else:
|
|
203
|
+
elastic_net_res = elastic_net_alg.compute(data=X, dependentVariables=y)
|
|
204
|
+
except RuntimeError:
|
|
205
|
+
return None
|
|
206
|
+
|
|
207
|
+
# set coef_ and intersept_ results
|
|
208
|
+
elastic_net_model = elastic_net_res.model
|
|
209
|
+
self.daal_model_ = elastic_net_model
|
|
210
|
+
|
|
211
|
+
# update coefficients if normalizing and centering
|
|
212
|
+
if self.fit_intercept and _normalize:
|
|
213
|
+
elastic_net_model.Beta[:, 1:] = elastic_net_model.Beta[:, 1:] / X_scale
|
|
214
|
+
elastic_net_model.Beta[:, 0] = (
|
|
215
|
+
y_offset - np.dot(X_offset, elastic_net_model.Beta[:, 1:].T)
|
|
216
|
+
).T
|
|
217
|
+
|
|
218
|
+
coefs = elastic_net_model.Beta
|
|
219
|
+
|
|
220
|
+
self.intercept_ = coefs[:, 0].copy(order="C")
|
|
221
|
+
self.coef_ = coefs[:, 1:].copy(order="C")
|
|
222
|
+
|
|
223
|
+
# only for compliance with Sklearn
|
|
224
|
+
if y.shape[1] == 1:
|
|
225
|
+
self.coef_ = np.ravel(self.coef_)
|
|
226
|
+
self.intercept_ = np.ravel(self.intercept_)
|
|
227
|
+
if self.intercept_.shape[0] == 1:
|
|
228
|
+
self.intercept_ = self.intercept_[0]
|
|
229
|
+
|
|
230
|
+
# set n_iter_
|
|
231
|
+
n_iter = cd_solver.__get_result__().nIterations[0][0]
|
|
232
|
+
if y.shape[1] == 1:
|
|
233
|
+
self.n_iter_ = n_iter
|
|
234
|
+
else:
|
|
235
|
+
self.n_iter_ = np.full(y.shape[1], n_iter)
|
|
236
|
+
|
|
237
|
+
# only for compliance with Sklearn
|
|
238
|
+
if self.max_iter == n_iter + 1:
|
|
239
|
+
warnings.warn(
|
|
240
|
+
"Objective did not converge. You might want to "
|
|
241
|
+
"increase the number of iterations.",
|
|
242
|
+
ConvergenceWarning,
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
return self
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
def _daal4py_predict_enet(self, X):
|
|
249
|
+
X = make2d(X)
|
|
250
|
+
_fptype = getFPType(self.coef_)
|
|
251
|
+
|
|
252
|
+
elastic_net_palg = daal4py.elastic_net_prediction(
|
|
253
|
+
fptype=_fptype, method="defaultDense"
|
|
254
|
+
)
|
|
255
|
+
if self.n_features_in_ != X.shape[1]:
|
|
256
|
+
raise ValueError(
|
|
257
|
+
f"X has {X.shape[1]} features, "
|
|
258
|
+
f"but ElasticNet is expecting "
|
|
259
|
+
f"{self.n_features_in_} features as input"
|
|
260
|
+
)
|
|
261
|
+
elastic_net_res = elastic_net_palg.compute(X, self.daal_model_)
|
|
262
|
+
|
|
263
|
+
res = elastic_net_res.prediction
|
|
264
|
+
|
|
265
|
+
if res.shape[1] == 1 and self.coef_.ndim == 1:
|
|
266
|
+
res = np.ravel(res)
|
|
267
|
+
return res
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def _daal4py_fit_lasso(self, X, y_, check_input):
|
|
271
|
+
# appropriate checks
|
|
272
|
+
_daal4py_check(self, X, y_, check_input)
|
|
273
|
+
X = make2d(X)
|
|
274
|
+
y = make2d(y_)
|
|
275
|
+
_fptype = getFPType(X)
|
|
276
|
+
|
|
277
|
+
# only for dual_gap computation, it is not required for Intel(R) oneAPI
|
|
278
|
+
# Data Analytics Library
|
|
279
|
+
self._X = X
|
|
280
|
+
self.n_features_in_ = X.shape[1]
|
|
281
|
+
self._y = y
|
|
282
|
+
|
|
283
|
+
# normalizing and centering
|
|
284
|
+
X_offset = np.zeros(X.shape[1], dtype=X.dtype)
|
|
285
|
+
X_scale = np.ones(X.shape[1], dtype=X.dtype)
|
|
286
|
+
if y.ndim == 1:
|
|
287
|
+
y_offset = X.dtype.type(0)
|
|
288
|
+
else:
|
|
289
|
+
y_offset = np.zeros(y.shape[1], dtype=X.dtype)
|
|
290
|
+
|
|
291
|
+
if sklearn_check_version("1.2"):
|
|
292
|
+
_normalize = False
|
|
293
|
+
else:
|
|
294
|
+
_normalize = self._normalize if sklearn_check_version("1.0") else self.normalize
|
|
295
|
+
if self.fit_intercept:
|
|
296
|
+
X_offset = np.average(X, axis=0)
|
|
297
|
+
if _normalize:
|
|
298
|
+
if self.copy_X:
|
|
299
|
+
X = np.copy(X) - X_offset
|
|
300
|
+
else:
|
|
301
|
+
X -= X_offset
|
|
302
|
+
X, X_scale = normalize(X, axis=0, copy=False, return_norm=True)
|
|
303
|
+
y_offset = np.average(y, axis=0)
|
|
304
|
+
y = y - y_offset
|
|
305
|
+
|
|
306
|
+
# only for compliance with Sklearn
|
|
307
|
+
if (
|
|
308
|
+
isinstance(self.precompute, np.ndarray)
|
|
309
|
+
and self.fit_intercept
|
|
310
|
+
and (
|
|
311
|
+
not np.allclose(X_offset, np.zeros(X.shape[1]))
|
|
312
|
+
or _normalize
|
|
313
|
+
and not np.allclose(X_scale, np.ones(X.shape[1]))
|
|
314
|
+
)
|
|
315
|
+
):
|
|
316
|
+
warnings.warn(
|
|
317
|
+
"Gram matrix was provided but X was centered"
|
|
318
|
+
" to fit intercept, "
|
|
319
|
+
"or X was normalized : recomputing Gram matrix.",
|
|
320
|
+
UserWarning,
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
mse_alg = daal4py.optimization_solver_mse(
|
|
324
|
+
numberOfTerms=X.shape[0], fptype=_fptype, method="defaultDense"
|
|
325
|
+
)
|
|
326
|
+
mse_alg.setup(X, y, None)
|
|
327
|
+
|
|
328
|
+
cd_solver = daal4py.optimization_solver_coordinate_descent(
|
|
329
|
+
function=mse_alg,
|
|
330
|
+
fptype=_fptype,
|
|
331
|
+
method="defaultDense",
|
|
332
|
+
selection=self.selection,
|
|
333
|
+
seed=0 if self.random_state is None else self.random_state,
|
|
334
|
+
nIterations=self.max_iter,
|
|
335
|
+
positive=self.positive,
|
|
336
|
+
accuracyThreshold=self.tol,
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
# set warm_start
|
|
340
|
+
if self.warm_start and hasattr(self, "coef_") and isinstance(self.coef_, np.ndarray):
|
|
341
|
+
n_rows = y.shape[1]
|
|
342
|
+
n_cols = X.shape[1] + 1
|
|
343
|
+
inputArgument = np.zeros((n_rows, n_cols), dtype=_fptype)
|
|
344
|
+
for i in range(n_rows):
|
|
345
|
+
inputArgument[i][0] = self.intercept_ if (n_rows == 1) else self.intercept_[i]
|
|
346
|
+
inputArgument[i][1:] = (
|
|
347
|
+
self.coef_[:].copy(order="C")
|
|
348
|
+
if (n_rows == 1)
|
|
349
|
+
else self.coef_[i, :].copy(order="C")
|
|
350
|
+
)
|
|
351
|
+
cd_solver.setup(inputArgument)
|
|
352
|
+
doUse_condition = self.copy_X is False or (
|
|
353
|
+
self.fit_intercept and _normalize and self.copy_X
|
|
354
|
+
)
|
|
355
|
+
lasso_alg = daal4py.lasso_regression_training(
|
|
356
|
+
fptype=_fptype,
|
|
357
|
+
method="defaultDense",
|
|
358
|
+
interceptFlag=(self.fit_intercept is True),
|
|
359
|
+
dataUseInComputation="doUse" if doUse_condition else "doNotUse",
|
|
360
|
+
lassoParameters=np.asarray(self.alpha, dtype=X.dtype).reshape((1, -1)),
|
|
361
|
+
optimizationSolver=cd_solver,
|
|
362
|
+
)
|
|
363
|
+
try:
|
|
364
|
+
if isinstance(self.precompute, np.ndarray):
|
|
365
|
+
lasso_res = lasso_alg.compute(
|
|
366
|
+
data=X, dependentVariables=y, gramMatrix=self.precompute
|
|
367
|
+
)
|
|
368
|
+
else:
|
|
369
|
+
lasso_res = lasso_alg.compute(data=X, dependentVariables=y)
|
|
370
|
+
except RuntimeError:
|
|
371
|
+
return None
|
|
372
|
+
|
|
373
|
+
# set coef_ and intersept_ results
|
|
374
|
+
lasso_model = lasso_res.model
|
|
375
|
+
self.daal_model_ = lasso_model
|
|
376
|
+
|
|
377
|
+
# update coefficients if normalizing and centering
|
|
378
|
+
if self.fit_intercept and _normalize:
|
|
379
|
+
lasso_model.Beta[:, 1:] = lasso_model.Beta[:, 1:] / X_scale
|
|
380
|
+
lasso_model.Beta[:, 0] = (
|
|
381
|
+
y_offset - np.dot(X_offset, lasso_model.Beta[:, 1:].T)
|
|
382
|
+
).T
|
|
383
|
+
|
|
384
|
+
coefs = lasso_model.Beta
|
|
385
|
+
|
|
386
|
+
self.intercept_ = coefs[:, 0].copy(order="C")
|
|
387
|
+
self.coef_ = coefs[:, 1:].copy(order="C")
|
|
388
|
+
|
|
389
|
+
# only for compliance with Sklearn
|
|
390
|
+
if y.shape[1] == 1:
|
|
391
|
+
self.coef_ = np.ravel(self.coef_)
|
|
392
|
+
self.intercept_ = np.ravel(self.intercept_)
|
|
393
|
+
if self.intercept_.shape[0] == 1:
|
|
394
|
+
self.intercept_ = self.intercept_[0]
|
|
395
|
+
|
|
396
|
+
# set n_iter_
|
|
397
|
+
n_iter = cd_solver.__get_result__().nIterations[0][0]
|
|
398
|
+
if y.shape[1] == 1:
|
|
399
|
+
self.n_iter_ = n_iter
|
|
400
|
+
else:
|
|
401
|
+
self.n_iter_ = np.full(y.shape[1], n_iter)
|
|
402
|
+
|
|
403
|
+
# only for compliance with Sklearn
|
|
404
|
+
if self.max_iter == n_iter + 1:
|
|
405
|
+
warnings.warn(
|
|
406
|
+
"Objective did not converge. You might want to "
|
|
407
|
+
"increase the number of iterations.",
|
|
408
|
+
ConvergenceWarning,
|
|
409
|
+
)
|
|
410
|
+
|
|
411
|
+
return self
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
def _daal4py_predict_lasso(self, X):
|
|
415
|
+
X = make2d(X)
|
|
416
|
+
_fptype = getFPType(self.coef_)
|
|
417
|
+
|
|
418
|
+
lasso_palg = daal4py.lasso_regression_prediction(
|
|
419
|
+
fptype=_fptype, method="defaultDense"
|
|
420
|
+
)
|
|
421
|
+
if self.n_features_in_ != X.shape[1]:
|
|
422
|
+
raise ValueError(
|
|
423
|
+
f"X has {X.shape[1]} features, "
|
|
424
|
+
f"but Lasso is expecting "
|
|
425
|
+
f"{self.n_features_in_} features as input"
|
|
426
|
+
)
|
|
427
|
+
lasso_res = lasso_palg.compute(X, self.daal_model_)
|
|
428
|
+
|
|
429
|
+
res = lasso_res.prediction
|
|
430
|
+
|
|
431
|
+
if res.shape[1] == 1 and self.coef_.ndim == 1:
|
|
432
|
+
res = np.ravel(res)
|
|
433
|
+
return res
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
def _fit(self, _X, _y, sample_weight=None, check_input=True):
|
|
437
|
+
if sklearn_check_version("1.0"):
|
|
438
|
+
self._check_feature_names(_X, reset=True)
|
|
439
|
+
if sklearn_check_version("1.2"):
|
|
440
|
+
self._validate_params()
|
|
441
|
+
elif sklearn_check_version("1.1"):
|
|
442
|
+
check_scalar(
|
|
443
|
+
self.alpha,
|
|
444
|
+
"alpha",
|
|
445
|
+
target_type=numbers.Real,
|
|
446
|
+
min_val=0.0,
|
|
447
|
+
)
|
|
448
|
+
if self.alpha == 0:
|
|
449
|
+
warnings.warn(
|
|
450
|
+
"With alpha=0, this algorithm does not converge "
|
|
451
|
+
"well. You are advised to use the LinearRegression "
|
|
452
|
+
"estimator",
|
|
453
|
+
stacklevel=2,
|
|
454
|
+
)
|
|
455
|
+
if isinstance(self.precompute, str):
|
|
456
|
+
raise ValueError(
|
|
457
|
+
"precompute should be one of True, False or array-like. Got %r"
|
|
458
|
+
% self.precompute
|
|
459
|
+
)
|
|
460
|
+
check_scalar(
|
|
461
|
+
self.l1_ratio,
|
|
462
|
+
"l1_ratio",
|
|
463
|
+
target_type=numbers.Real,
|
|
464
|
+
min_val=0.0,
|
|
465
|
+
max_val=1.0,
|
|
466
|
+
)
|
|
467
|
+
if self.max_iter is not None:
|
|
468
|
+
check_scalar(
|
|
469
|
+
self.max_iter, "max_iter", target_type=numbers.Integral, min_val=1
|
|
470
|
+
)
|
|
471
|
+
check_scalar(self.tol, "tol", target_type=numbers.Real, min_val=0.0)
|
|
472
|
+
# check X and y
|
|
473
|
+
if check_input:
|
|
474
|
+
X, y = check_X_y(
|
|
475
|
+
_X,
|
|
476
|
+
_y,
|
|
477
|
+
copy=False,
|
|
478
|
+
accept_sparse="csc",
|
|
479
|
+
dtype=[np.float64, np.float32],
|
|
480
|
+
multi_output=True,
|
|
481
|
+
y_numeric=True,
|
|
482
|
+
)
|
|
483
|
+
y = check_array(_y, copy=False, dtype=X.dtype.type, ensure_2d=False)
|
|
484
|
+
else:
|
|
485
|
+
X, y = _X, _y
|
|
486
|
+
|
|
487
|
+
if not sp.issparse(X):
|
|
488
|
+
self.fit_shape_good_for_daal_ = (
|
|
489
|
+
True if X.ndim <= 1 else True if X.shape[0] >= X.shape[1] else False
|
|
490
|
+
)
|
|
491
|
+
else:
|
|
492
|
+
self.fit_shape_good_for_daal_ = False
|
|
493
|
+
|
|
494
|
+
class_name = self.__class__.__name__
|
|
495
|
+
class_inst = ElasticNet if class_name == "ElasticNet" else Lasso
|
|
496
|
+
|
|
497
|
+
_function_name = f"sklearn.linear_model.{class_name}.fit"
|
|
498
|
+
_patching_status = PatchingConditionsChain(_function_name)
|
|
499
|
+
_dal_ready = _patching_status.and_conditions(
|
|
500
|
+
[
|
|
501
|
+
(not sp.issparse(X), "X is sparse. Sparse input is not supported."),
|
|
502
|
+
(
|
|
503
|
+
self.fit_shape_good_for_daal_,
|
|
504
|
+
"The shape of X does not satisfy oneDAL requirements: "
|
|
505
|
+
"number of features > number of samples.",
|
|
506
|
+
),
|
|
507
|
+
(
|
|
508
|
+
X.dtype == np.float64 or X.dtype == np.float32,
|
|
509
|
+
f"'{X.dtype}' X data type is not supported. "
|
|
510
|
+
"Only np.float32 and np.float64 are supported.",
|
|
511
|
+
),
|
|
512
|
+
(sample_weight is None, "Sample weights are not supported."),
|
|
513
|
+
]
|
|
514
|
+
)
|
|
515
|
+
_patching_status.write_log()
|
|
516
|
+
|
|
517
|
+
if not _dal_ready:
|
|
518
|
+
if hasattr(self, "daal_model_"):
|
|
519
|
+
del self.daal_model_
|
|
520
|
+
res_new = super(class_inst, self).fit(
|
|
521
|
+
X, y, sample_weight=sample_weight, check_input=check_input
|
|
522
|
+
)
|
|
523
|
+
self._gap = res_new.dual_gap_
|
|
524
|
+
return res_new
|
|
525
|
+
self.n_iter_ = None
|
|
526
|
+
self._gap = None
|
|
527
|
+
|
|
528
|
+
if not check_input:
|
|
529
|
+
# only for compliance with Sklearn,
|
|
530
|
+
# this assert is not required for Intel(R) oneAPI Data
|
|
531
|
+
# Analytics Library
|
|
532
|
+
print(type(X), X.flags["F_CONTIGUOUS"])
|
|
533
|
+
if isinstance(X, np.ndarray) and X.flags["F_CONTIGUOUS"] is False:
|
|
534
|
+
# print(X.flags)
|
|
535
|
+
raise ValueError("ndarray is not Fortran contiguous")
|
|
536
|
+
|
|
537
|
+
if sklearn_check_version("1.0") and not sklearn_check_version("1.2"):
|
|
538
|
+
self._normalize = _deprecate_normalize(
|
|
539
|
+
self.normalize, default=False, estimator_name=class_name
|
|
540
|
+
)
|
|
541
|
+
|
|
542
|
+
# only for pass tests
|
|
543
|
+
# "check_estimators_fit_returns_self(readonly_memmap=True) and
|
|
544
|
+
# check_regressors_train(readonly_memmap=True)
|
|
545
|
+
if not X.flags.writeable:
|
|
546
|
+
X = np.copy(X)
|
|
547
|
+
if not y.flags.writeable:
|
|
548
|
+
y = np.copy(y)
|
|
549
|
+
|
|
550
|
+
if class_name == "ElasticNet":
|
|
551
|
+
res = _daal4py_fit_enet(self, X, y, check_input=check_input)
|
|
552
|
+
else:
|
|
553
|
+
res = _daal4py_fit_lasso(self, X, y, check_input=check_input)
|
|
554
|
+
if res is None:
|
|
555
|
+
if hasattr(self, "daal_model_"):
|
|
556
|
+
del self.daal_model_
|
|
557
|
+
logging.info(_function_name + ": " + get_patch_message("sklearn_after_daal"))
|
|
558
|
+
res_new = super(class_inst, self).fit(
|
|
559
|
+
_X, _y, sample_weight=sample_weight, check_input=check_input
|
|
560
|
+
)
|
|
561
|
+
self._gap = res_new.dual_gap_
|
|
562
|
+
return res_new
|
|
563
|
+
return res
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
def _dual_gap(self):
|
|
567
|
+
if self._gap is None:
|
|
568
|
+
l1_reg = self.alpha * self.l1_ratio * self._X.shape[0]
|
|
569
|
+
l2_reg = self.alpha * (1.0 - self.l1_ratio) * self._X.shape[0]
|
|
570
|
+
n_targets = self._y.shape[1]
|
|
571
|
+
|
|
572
|
+
if n_targets == 1:
|
|
573
|
+
self._gap = self.tol + 1.0
|
|
574
|
+
X_offset = np.average(self._X, axis=0)
|
|
575
|
+
y_offset = np.average(self._y, axis=0)
|
|
576
|
+
coef = np.reshape(self.coef_, (self.coef_.shape[0], 1))
|
|
577
|
+
R = (self._y - y_offset) - np.dot((self._X - X_offset), coef)
|
|
578
|
+
XtA = np.dot((self._X - X_offset).T, R) - l2_reg * coef
|
|
579
|
+
R_norm2 = np.dot(R.T, R)
|
|
580
|
+
coef_norm2 = np.dot(self.coef_, self.coef_)
|
|
581
|
+
dual_norm_XtA = np.max(XtA) if self.positive else np.max(np.abs(XtA))
|
|
582
|
+
if dual_norm_XtA > l1_reg:
|
|
583
|
+
const = l1_reg / dual_norm_XtA
|
|
584
|
+
A_norm2 = R_norm2 * (const**2)
|
|
585
|
+
self._gap = 0.5 * (R_norm2 + A_norm2)
|
|
586
|
+
else:
|
|
587
|
+
const = 1.0
|
|
588
|
+
self._gap = R_norm2
|
|
589
|
+
l1_norm = np.sum(np.abs(self.coef_))
|
|
590
|
+
tmp = l1_reg * l1_norm
|
|
591
|
+
tmp -= const * np.dot(R.T, (self._y - y_offset))
|
|
592
|
+
tmp += 0.5 * l2_reg * (1 + const**2) * coef_norm2
|
|
593
|
+
self._gap += tmp
|
|
594
|
+
self._gap = self._gap[0][0]
|
|
595
|
+
else:
|
|
596
|
+
self._gap = np.full(n_targets, self.tol + 1.0)
|
|
597
|
+
X_offset = np.average(self._X, axis=0)
|
|
598
|
+
y_offset = np.average(self._y, axis=0)
|
|
599
|
+
for k in range(n_targets):
|
|
600
|
+
R = (self._y[:, k] - y_offset[k]) - np.dot(
|
|
601
|
+
(self._X - X_offset), self.coef_[k, :].T
|
|
602
|
+
)
|
|
603
|
+
XtA = np.dot((self._X - X_offset).T, R) - l2_reg * self.coef_[k, :].T
|
|
604
|
+
R_norm2 = np.dot(R.T, R)
|
|
605
|
+
coef_norm2 = np.dot(self.coef_[k, :], self.coef_[k, :].T)
|
|
606
|
+
dual_norm_XtA = np.max(XtA) if self.positive else np.max(np.abs(XtA))
|
|
607
|
+
if dual_norm_XtA > l1_reg:
|
|
608
|
+
const = l1_reg / dual_norm_XtA
|
|
609
|
+
A_norm2 = R_norm2 * (const**2)
|
|
610
|
+
self._gap[k] = 0.5 * (R_norm2 + A_norm2)
|
|
611
|
+
else:
|
|
612
|
+
const = 1.0
|
|
613
|
+
self._gap[k] = R_norm2
|
|
614
|
+
l1_norm = np.sum(np.abs(self.coef_[k, :]))
|
|
615
|
+
tmp = l1_reg * l1_norm
|
|
616
|
+
tmp -= const * np.dot(R.T, (self._y[:, k] - y_offset[k]))
|
|
617
|
+
tmp += 0.5 * l2_reg * (1 + const**2) * coef_norm2
|
|
618
|
+
self._gap[k] += tmp
|
|
619
|
+
return self._gap
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
@control_n_jobs(decorated_methods=["fit", "predict"])
|
|
623
|
+
class ElasticNet(ElasticNet_original):
|
|
624
|
+
__doc__ = ElasticNet_original.__doc__
|
|
625
|
+
|
|
626
|
+
if sklearn_check_version("1.2"):
|
|
627
|
+
_parameter_constraints: dict = {**ElasticNet_original._parameter_constraints}
|
|
628
|
+
|
|
629
|
+
def __init__(
|
|
630
|
+
self,
|
|
631
|
+
alpha=1.0,
|
|
632
|
+
l1_ratio=0.5,
|
|
633
|
+
fit_intercept=True,
|
|
634
|
+
precompute=False,
|
|
635
|
+
max_iter=1000,
|
|
636
|
+
copy_X=True,
|
|
637
|
+
tol=1e-4,
|
|
638
|
+
warm_start=False,
|
|
639
|
+
positive=False,
|
|
640
|
+
random_state=None,
|
|
641
|
+
selection="cyclic",
|
|
642
|
+
):
|
|
643
|
+
super(ElasticNet, self).__init__(
|
|
644
|
+
alpha=alpha,
|
|
645
|
+
l1_ratio=l1_ratio,
|
|
646
|
+
fit_intercept=fit_intercept,
|
|
647
|
+
precompute=precompute,
|
|
648
|
+
max_iter=max_iter,
|
|
649
|
+
copy_X=copy_X,
|
|
650
|
+
tol=tol,
|
|
651
|
+
warm_start=warm_start,
|
|
652
|
+
positive=positive,
|
|
653
|
+
random_state=random_state,
|
|
654
|
+
selection=selection,
|
|
655
|
+
)
|
|
656
|
+
|
|
657
|
+
else:
|
|
658
|
+
|
|
659
|
+
def __init__(
|
|
660
|
+
self,
|
|
661
|
+
alpha=1.0,
|
|
662
|
+
l1_ratio=0.5,
|
|
663
|
+
fit_intercept=True,
|
|
664
|
+
normalize="deprecated" if sklearn_check_version("1.0") else False,
|
|
665
|
+
precompute=False,
|
|
666
|
+
max_iter=1000,
|
|
667
|
+
copy_X=True,
|
|
668
|
+
tol=1e-4,
|
|
669
|
+
warm_start=False,
|
|
670
|
+
positive=False,
|
|
671
|
+
random_state=None,
|
|
672
|
+
selection="cyclic",
|
|
673
|
+
):
|
|
674
|
+
super(ElasticNet, self).__init__(
|
|
675
|
+
alpha=alpha,
|
|
676
|
+
l1_ratio=l1_ratio,
|
|
677
|
+
fit_intercept=fit_intercept,
|
|
678
|
+
normalize=normalize,
|
|
679
|
+
precompute=precompute,
|
|
680
|
+
max_iter=max_iter,
|
|
681
|
+
copy_X=copy_X,
|
|
682
|
+
tol=tol,
|
|
683
|
+
warm_start=warm_start,
|
|
684
|
+
positive=positive,
|
|
685
|
+
random_state=random_state,
|
|
686
|
+
selection=selection,
|
|
687
|
+
)
|
|
688
|
+
|
|
689
|
+
def fit(self, X, y, sample_weight=None, check_input=True):
|
|
690
|
+
return _fit(self, X, y, sample_weight=sample_weight, check_input=check_input)
|
|
691
|
+
|
|
692
|
+
def predict(self, X):
|
|
693
|
+
if sklearn_check_version("1.0"):
|
|
694
|
+
self._check_feature_names(X, reset=False)
|
|
695
|
+
|
|
696
|
+
_X = check_array(
|
|
697
|
+
X, accept_sparse=["csr", "csc", "coo"], dtype=[np.float64, np.float32]
|
|
698
|
+
)
|
|
699
|
+
good_shape_for_daal = (
|
|
700
|
+
True if _X.ndim <= 1 else True if _X.shape[0] >= _X.shape[1] else False
|
|
701
|
+
)
|
|
702
|
+
|
|
703
|
+
_patching_status = PatchingConditionsChain(
|
|
704
|
+
"sklearn.linear_model.ElasticNet.predict"
|
|
705
|
+
)
|
|
706
|
+
_dal_ready = _patching_status.and_conditions(
|
|
707
|
+
[
|
|
708
|
+
(hasattr(self, "daal_model_"), "oneDAL model was not trained."),
|
|
709
|
+
(not sp.issparse(_X), "X is sparse. Sparse input is not supported."),
|
|
710
|
+
(
|
|
711
|
+
good_shape_for_daal,
|
|
712
|
+
"The shape of X does not satisfy oneDAL requirements: "
|
|
713
|
+
"number of features > number of samples.",
|
|
714
|
+
),
|
|
715
|
+
]
|
|
716
|
+
)
|
|
717
|
+
_patching_status.write_log()
|
|
718
|
+
|
|
719
|
+
if not _dal_ready:
|
|
720
|
+
return self._decision_function(X)
|
|
721
|
+
return _daal4py_predict_enet(self, _X)
|
|
722
|
+
|
|
723
|
+
@property
|
|
724
|
+
def dual_gap_(self):
|
|
725
|
+
return _dual_gap(self)
|
|
726
|
+
|
|
727
|
+
@dual_gap_.setter
|
|
728
|
+
def dual_gap_(self, value):
|
|
729
|
+
self._gap = value
|
|
730
|
+
|
|
731
|
+
@dual_gap_.deleter
|
|
732
|
+
def dual_gap_(self):
|
|
733
|
+
self._gap = None
|
|
734
|
+
|
|
735
|
+
fit.__doc__ = ElasticNet_original.fit.__doc__
|
|
736
|
+
predict.__doc__ = ElasticNet_original.predict.__doc__
|
|
737
|
+
|
|
738
|
+
|
|
739
|
+
@control_n_jobs(decorated_methods=["fit", "predict"])
|
|
740
|
+
class Lasso(Lasso_original):
|
|
741
|
+
__doc__ = Lasso_original.__doc__
|
|
742
|
+
|
|
743
|
+
if sklearn_check_version("1.2"):
|
|
744
|
+
_parameter_constraints: dict = {**Lasso_original._parameter_constraints}
|
|
745
|
+
|
|
746
|
+
def __init__(
|
|
747
|
+
self,
|
|
748
|
+
alpha=1.0,
|
|
749
|
+
fit_intercept=True,
|
|
750
|
+
precompute=False,
|
|
751
|
+
copy_X=True,
|
|
752
|
+
max_iter=1000,
|
|
753
|
+
tol=1e-4,
|
|
754
|
+
warm_start=False,
|
|
755
|
+
positive=False,
|
|
756
|
+
random_state=None,
|
|
757
|
+
selection="cyclic",
|
|
758
|
+
):
|
|
759
|
+
self.l1_ratio = 1.0
|
|
760
|
+
super().__init__(
|
|
761
|
+
alpha=alpha,
|
|
762
|
+
fit_intercept=fit_intercept,
|
|
763
|
+
precompute=precompute,
|
|
764
|
+
copy_X=copy_X,
|
|
765
|
+
max_iter=max_iter,
|
|
766
|
+
tol=tol,
|
|
767
|
+
warm_start=warm_start,
|
|
768
|
+
positive=positive,
|
|
769
|
+
random_state=random_state,
|
|
770
|
+
selection=selection,
|
|
771
|
+
)
|
|
772
|
+
|
|
773
|
+
else:
|
|
774
|
+
|
|
775
|
+
def __init__(
|
|
776
|
+
self,
|
|
777
|
+
alpha=1.0,
|
|
778
|
+
fit_intercept=True,
|
|
779
|
+
normalize="deprecated" if sklearn_check_version("1.0") else False,
|
|
780
|
+
precompute=False,
|
|
781
|
+
copy_X=True,
|
|
782
|
+
max_iter=1000,
|
|
783
|
+
tol=1e-4,
|
|
784
|
+
warm_start=False,
|
|
785
|
+
positive=False,
|
|
786
|
+
random_state=None,
|
|
787
|
+
selection="cyclic",
|
|
788
|
+
):
|
|
789
|
+
self.l1_ratio = 1.0
|
|
790
|
+
super().__init__(
|
|
791
|
+
alpha=alpha,
|
|
792
|
+
fit_intercept=fit_intercept,
|
|
793
|
+
normalize=normalize,
|
|
794
|
+
precompute=precompute,
|
|
795
|
+
copy_X=copy_X,
|
|
796
|
+
max_iter=max_iter,
|
|
797
|
+
tol=tol,
|
|
798
|
+
warm_start=warm_start,
|
|
799
|
+
positive=positive,
|
|
800
|
+
random_state=random_state,
|
|
801
|
+
selection=selection,
|
|
802
|
+
)
|
|
803
|
+
|
|
804
|
+
def fit(self, X, y, sample_weight=None, check_input=True):
|
|
805
|
+
return _fit(self, X, y, sample_weight, check_input)
|
|
806
|
+
|
|
807
|
+
def predict(self, X):
|
|
808
|
+
if sklearn_check_version("1.0"):
|
|
809
|
+
self._check_feature_names(X, reset=False)
|
|
810
|
+
_X = check_array(
|
|
811
|
+
X, accept_sparse=["csr", "csc", "coo"], dtype=[np.float64, np.float32]
|
|
812
|
+
)
|
|
813
|
+
good_shape_for_daal = (
|
|
814
|
+
True if _X.ndim <= 1 else True if _X.shape[0] >= _X.shape[1] else False
|
|
815
|
+
)
|
|
816
|
+
|
|
817
|
+
_patching_status = PatchingConditionsChain("sklearn.linear_model.Lasso.predict")
|
|
818
|
+
_dal_ready = _patching_status.and_conditions(
|
|
819
|
+
[
|
|
820
|
+
(hasattr(self, "daal_model_"), "oneDAL model was not trained."),
|
|
821
|
+
(not sp.issparse(_X), "X is sparse. Sparse input is not supported."),
|
|
822
|
+
(
|
|
823
|
+
good_shape_for_daal,
|
|
824
|
+
"The shape of X does not satisfy oneDAL requirements: "
|
|
825
|
+
"number of features > number of samples.",
|
|
826
|
+
),
|
|
827
|
+
]
|
|
828
|
+
)
|
|
829
|
+
_patching_status.write_log()
|
|
830
|
+
|
|
831
|
+
if not _dal_ready:
|
|
832
|
+
return self._decision_function(X)
|
|
833
|
+
return _daal4py_predict_lasso(self, _X)
|
|
834
|
+
|
|
835
|
+
@property
|
|
836
|
+
def dual_gap_(self):
|
|
837
|
+
return _dual_gap(self)
|
|
838
|
+
|
|
839
|
+
@dual_gap_.setter
|
|
840
|
+
def dual_gap_(self, value):
|
|
841
|
+
self._gap = value
|
|
842
|
+
|
|
843
|
+
@dual_gap_.deleter
|
|
844
|
+
def dual_gap_(self):
|
|
845
|
+
self._gap = None
|
|
846
|
+
|
|
847
|
+
fit.__doc__ = Lasso_original.fit.__doc__
|
|
848
|
+
predict.__doc__ = Lasso_original.predict.__doc__
|