scikit-learn-intelex 2025.4.0__py313-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.

Files changed (282) hide show
  1. daal4py/__init__.py +73 -0
  2. daal4py/__main__.py +58 -0
  3. daal4py/_daal4py.cpython-313-x86_64-linux-gnu.so +0 -0
  4. daal4py/doc/third-party-programs.txt +424 -0
  5. daal4py/mb/__init__.py +19 -0
  6. daal4py/mb/model_builders.py +377 -0
  7. daal4py/mpi_transceiver.cpython-313-x86_64-linux-gnu.so +0 -0
  8. daal4py/sklearn/__init__.py +40 -0
  9. daal4py/sklearn/_n_jobs_support.py +248 -0
  10. daal4py/sklearn/_utils.py +245 -0
  11. daal4py/sklearn/cluster/__init__.py +20 -0
  12. daal4py/sklearn/cluster/dbscan.py +165 -0
  13. daal4py/sklearn/cluster/k_means.py +597 -0
  14. daal4py/sklearn/cluster/tests/test_dbscan.py +109 -0
  15. daal4py/sklearn/decomposition/__init__.py +19 -0
  16. daal4py/sklearn/decomposition/_pca.py +524 -0
  17. daal4py/sklearn/ensemble/AdaBoostClassifier.py +196 -0
  18. daal4py/sklearn/ensemble/GBTDAAL.py +337 -0
  19. daal4py/sklearn/ensemble/__init__.py +27 -0
  20. daal4py/sklearn/ensemble/_forest.py +1397 -0
  21. daal4py/sklearn/ensemble/tests/test_decision_forest.py +206 -0
  22. daal4py/sklearn/linear_model/__init__.py +29 -0
  23. daal4py/sklearn/linear_model/_coordinate_descent.py +848 -0
  24. daal4py/sklearn/linear_model/_linear.py +272 -0
  25. daal4py/sklearn/linear_model/_ridge.py +325 -0
  26. daal4py/sklearn/linear_model/coordinate_descent.py +17 -0
  27. daal4py/sklearn/linear_model/linear.py +17 -0
  28. daal4py/sklearn/linear_model/logistic_loss.py +195 -0
  29. daal4py/sklearn/linear_model/logistic_path.py +1026 -0
  30. daal4py/sklearn/linear_model/ridge.py +17 -0
  31. daal4py/sklearn/linear_model/tests/test_linear.py +208 -0
  32. daal4py/sklearn/linear_model/tests/test_ridge.py +69 -0
  33. daal4py/sklearn/manifold/__init__.py +19 -0
  34. daal4py/sklearn/manifold/_t_sne.py +405 -0
  35. daal4py/sklearn/metrics/__init__.py +20 -0
  36. daal4py/sklearn/metrics/_pairwise.py +236 -0
  37. daal4py/sklearn/metrics/_ranking.py +210 -0
  38. daal4py/sklearn/model_selection/__init__.py +19 -0
  39. daal4py/sklearn/model_selection/_split.py +309 -0
  40. daal4py/sklearn/model_selection/tests/test_split.py +56 -0
  41. daal4py/sklearn/monkeypatch/__init__.py +0 -0
  42. daal4py/sklearn/monkeypatch/dispatcher.py +232 -0
  43. daal4py/sklearn/monkeypatch/tests/_models_info.py +161 -0
  44. daal4py/sklearn/monkeypatch/tests/test_monkeypatch.py +71 -0
  45. daal4py/sklearn/monkeypatch/tests/test_patching.py +90 -0
  46. daal4py/sklearn/monkeypatch/tests/utils/_launch_algorithms.py +117 -0
  47. daal4py/sklearn/neighbors/__init__.py +21 -0
  48. daal4py/sklearn/neighbors/_base.py +503 -0
  49. daal4py/sklearn/neighbors/_classification.py +139 -0
  50. daal4py/sklearn/neighbors/_regression.py +74 -0
  51. daal4py/sklearn/neighbors/_unsupervised.py +55 -0
  52. daal4py/sklearn/neighbors/tests/test_kneighbors.py +113 -0
  53. daal4py/sklearn/svm/__init__.py +19 -0
  54. daal4py/sklearn/svm/svm.py +734 -0
  55. daal4py/sklearn/utils/__init__.py +21 -0
  56. daal4py/sklearn/utils/base.py +75 -0
  57. daal4py/sklearn/utils/tests/test_utils.py +51 -0
  58. daal4py/sklearn/utils/validation.py +696 -0
  59. onedal/__init__.py +83 -0
  60. onedal/_config.py +54 -0
  61. onedal/_device_offload.py +204 -0
  62. onedal/_onedal_py_dpc.cpython-313-x86_64-linux-gnu.so +0 -0
  63. onedal/_onedal_py_host.cpython-313-x86_64-linux-gnu.so +0 -0
  64. onedal/_onedal_py_spmd_dpc.cpython-313-x86_64-linux-gnu.so +0 -0
  65. onedal/basic_statistics/__init__.py +20 -0
  66. onedal/basic_statistics/basic_statistics.py +107 -0
  67. onedal/basic_statistics/incremental_basic_statistics.py +175 -0
  68. onedal/basic_statistics/tests/test_basic_statistics.py +242 -0
  69. onedal/basic_statistics/tests/test_incremental_basic_statistics.py +279 -0
  70. onedal/basic_statistics/tests/utils.py +50 -0
  71. onedal/cluster/__init__.py +27 -0
  72. onedal/cluster/dbscan.py +105 -0
  73. onedal/cluster/kmeans.py +557 -0
  74. onedal/cluster/kmeans_init.py +112 -0
  75. onedal/cluster/tests/test_dbscan.py +125 -0
  76. onedal/cluster/tests/test_kmeans.py +88 -0
  77. onedal/cluster/tests/test_kmeans_init.py +93 -0
  78. onedal/common/_base.py +38 -0
  79. onedal/common/_estimator_checks.py +47 -0
  80. onedal/common/_mixin.py +62 -0
  81. onedal/common/_policy.py +55 -0
  82. onedal/common/_spmd_policy.py +30 -0
  83. onedal/common/hyperparameters.py +125 -0
  84. onedal/common/tests/test_policy.py +76 -0
  85. onedal/common/tests/test_sycl.py +128 -0
  86. onedal/covariance/__init__.py +20 -0
  87. onedal/covariance/covariance.py +122 -0
  88. onedal/covariance/incremental_covariance.py +161 -0
  89. onedal/covariance/tests/test_covariance.py +50 -0
  90. onedal/covariance/tests/test_incremental_covariance.py +190 -0
  91. onedal/datatypes/__init__.py +19 -0
  92. onedal/datatypes/_data_conversion.py +121 -0
  93. onedal/datatypes/tests/common.py +126 -0
  94. onedal/datatypes/tests/test_data.py +475 -0
  95. onedal/decomposition/__init__.py +20 -0
  96. onedal/decomposition/incremental_pca.py +214 -0
  97. onedal/decomposition/pca.py +186 -0
  98. onedal/decomposition/tests/test_incremental_pca.py +285 -0
  99. onedal/ensemble/__init__.py +29 -0
  100. onedal/ensemble/forest.py +736 -0
  101. onedal/ensemble/tests/test_random_forest.py +97 -0
  102. onedal/linear_model/__init__.py +27 -0
  103. onedal/linear_model/incremental_linear_model.py +292 -0
  104. onedal/linear_model/linear_model.py +325 -0
  105. onedal/linear_model/logistic_regression.py +247 -0
  106. onedal/linear_model/tests/test_incremental_linear_regression.py +213 -0
  107. onedal/linear_model/tests/test_incremental_ridge_regression.py +171 -0
  108. onedal/linear_model/tests/test_linear_regression.py +259 -0
  109. onedal/linear_model/tests/test_logistic_regression.py +95 -0
  110. onedal/linear_model/tests/test_ridge.py +95 -0
  111. onedal/neighbors/__init__.py +19 -0
  112. onedal/neighbors/neighbors.py +763 -0
  113. onedal/neighbors/tests/test_knn_classification.py +49 -0
  114. onedal/primitives/__init__.py +27 -0
  115. onedal/primitives/get_tree.py +25 -0
  116. onedal/primitives/kernel_functions.py +152 -0
  117. onedal/primitives/tests/test_kernel_functions.py +159 -0
  118. onedal/spmd/__init__.py +25 -0
  119. onedal/spmd/_base.py +30 -0
  120. onedal/spmd/basic_statistics/__init__.py +20 -0
  121. onedal/spmd/basic_statistics/basic_statistics.py +30 -0
  122. onedal/spmd/basic_statistics/incremental_basic_statistics.py +71 -0
  123. onedal/spmd/cluster/__init__.py +28 -0
  124. onedal/spmd/cluster/dbscan.py +23 -0
  125. onedal/spmd/cluster/kmeans.py +56 -0
  126. onedal/spmd/covariance/__init__.py +20 -0
  127. onedal/spmd/covariance/covariance.py +26 -0
  128. onedal/spmd/covariance/incremental_covariance.py +83 -0
  129. onedal/spmd/decomposition/__init__.py +20 -0
  130. onedal/spmd/decomposition/incremental_pca.py +124 -0
  131. onedal/spmd/decomposition/pca.py +26 -0
  132. onedal/spmd/ensemble/__init__.py +19 -0
  133. onedal/spmd/ensemble/forest.py +28 -0
  134. onedal/spmd/linear_model/__init__.py +21 -0
  135. onedal/spmd/linear_model/incremental_linear_model.py +101 -0
  136. onedal/spmd/linear_model/linear_model.py +30 -0
  137. onedal/spmd/linear_model/logistic_regression.py +38 -0
  138. onedal/spmd/neighbors/__init__.py +19 -0
  139. onedal/spmd/neighbors/neighbors.py +75 -0
  140. onedal/svm/__init__.py +19 -0
  141. onedal/svm/svm.py +556 -0
  142. onedal/svm/tests/test_csr_svm.py +351 -0
  143. onedal/svm/tests/test_nusvc.py +204 -0
  144. onedal/svm/tests/test_nusvr.py +210 -0
  145. onedal/svm/tests/test_svc.py +176 -0
  146. onedal/svm/tests/test_svr.py +243 -0
  147. onedal/tests/test_common.py +57 -0
  148. onedal/tests/utils/_dataframes_support.py +162 -0
  149. onedal/tests/utils/_device_selection.py +102 -0
  150. onedal/utils/__init__.py +49 -0
  151. onedal/utils/_array_api.py +81 -0
  152. onedal/utils/_dpep_helpers.py +56 -0
  153. onedal/utils/tests/test_validation.py +142 -0
  154. onedal/utils/validation.py +464 -0
  155. scikit_learn_intelex-2025.4.0.dist-info/LICENSE.txt +202 -0
  156. scikit_learn_intelex-2025.4.0.dist-info/METADATA +190 -0
  157. scikit_learn_intelex-2025.4.0.dist-info/RECORD +282 -0
  158. scikit_learn_intelex-2025.4.0.dist-info/WHEEL +5 -0
  159. scikit_learn_intelex-2025.4.0.dist-info/top_level.txt +3 -0
  160. sklearnex/__init__.py +66 -0
  161. sklearnex/__main__.py +58 -0
  162. sklearnex/_config.py +116 -0
  163. sklearnex/_device_offload.py +126 -0
  164. sklearnex/_utils.py +177 -0
  165. sklearnex/basic_statistics/__init__.py +20 -0
  166. sklearnex/basic_statistics/basic_statistics.py +261 -0
  167. sklearnex/basic_statistics/incremental_basic_statistics.py +352 -0
  168. sklearnex/basic_statistics/tests/test_basic_statistics.py +405 -0
  169. sklearnex/basic_statistics/tests/test_incremental_basic_statistics.py +455 -0
  170. sklearnex/cluster/__init__.py +20 -0
  171. sklearnex/cluster/dbscan.py +197 -0
  172. sklearnex/cluster/k_means.py +397 -0
  173. sklearnex/cluster/tests/test_dbscan.py +38 -0
  174. sklearnex/cluster/tests/test_kmeans.py +157 -0
  175. sklearnex/conftest.py +82 -0
  176. sklearnex/covariance/__init__.py +19 -0
  177. sklearnex/covariance/incremental_covariance.py +405 -0
  178. sklearnex/covariance/tests/test_incremental_covariance.py +287 -0
  179. sklearnex/decomposition/__init__.py +19 -0
  180. sklearnex/decomposition/pca.py +427 -0
  181. sklearnex/decomposition/tests/test_pca.py +58 -0
  182. sklearnex/dispatcher.py +534 -0
  183. sklearnex/doc/third-party-programs.txt +424 -0
  184. sklearnex/ensemble/__init__.py +29 -0
  185. sklearnex/ensemble/_forest.py +2029 -0
  186. sklearnex/ensemble/tests/test_forest.py +140 -0
  187. sklearnex/glob/__main__.py +72 -0
  188. sklearnex/glob/dispatcher.py +101 -0
  189. sklearnex/linear_model/__init__.py +32 -0
  190. sklearnex/linear_model/coordinate_descent.py +30 -0
  191. sklearnex/linear_model/incremental_linear.py +495 -0
  192. sklearnex/linear_model/incremental_ridge.py +432 -0
  193. sklearnex/linear_model/linear.py +346 -0
  194. sklearnex/linear_model/logistic_regression.py +415 -0
  195. sklearnex/linear_model/ridge.py +390 -0
  196. sklearnex/linear_model/tests/test_incremental_linear.py +267 -0
  197. sklearnex/linear_model/tests/test_incremental_ridge.py +214 -0
  198. sklearnex/linear_model/tests/test_linear.py +142 -0
  199. sklearnex/linear_model/tests/test_logreg.py +134 -0
  200. sklearnex/linear_model/tests/test_ridge.py +256 -0
  201. sklearnex/manifold/__init__.py +19 -0
  202. sklearnex/manifold/t_sne.py +26 -0
  203. sklearnex/manifold/tests/test_tsne.py +250 -0
  204. sklearnex/metrics/__init__.py +23 -0
  205. sklearnex/metrics/pairwise.py +22 -0
  206. sklearnex/metrics/ranking.py +20 -0
  207. sklearnex/metrics/tests/test_metrics.py +39 -0
  208. sklearnex/model_selection/__init__.py +21 -0
  209. sklearnex/model_selection/split.py +22 -0
  210. sklearnex/model_selection/tests/test_model_selection.py +34 -0
  211. sklearnex/neighbors/__init__.py +27 -0
  212. sklearnex/neighbors/_lof.py +236 -0
  213. sklearnex/neighbors/common.py +310 -0
  214. sklearnex/neighbors/knn_classification.py +231 -0
  215. sklearnex/neighbors/knn_regression.py +207 -0
  216. sklearnex/neighbors/knn_unsupervised.py +178 -0
  217. sklearnex/neighbors/tests/test_neighbors.py +82 -0
  218. sklearnex/preview/__init__.py +17 -0
  219. sklearnex/preview/covariance/__init__.py +19 -0
  220. sklearnex/preview/covariance/covariance.py +142 -0
  221. sklearnex/preview/covariance/tests/test_covariance.py +66 -0
  222. sklearnex/preview/decomposition/__init__.py +19 -0
  223. sklearnex/preview/decomposition/incremental_pca.py +244 -0
  224. sklearnex/preview/decomposition/tests/test_incremental_pca.py +336 -0
  225. sklearnex/spmd/__init__.py +25 -0
  226. sklearnex/spmd/basic_statistics/__init__.py +20 -0
  227. sklearnex/spmd/basic_statistics/basic_statistics.py +21 -0
  228. sklearnex/spmd/basic_statistics/incremental_basic_statistics.py +30 -0
  229. sklearnex/spmd/basic_statistics/tests/test_basic_statistics_spmd.py +107 -0
  230. sklearnex/spmd/basic_statistics/tests/test_incremental_basic_statistics_spmd.py +306 -0
  231. sklearnex/spmd/cluster/__init__.py +30 -0
  232. sklearnex/spmd/cluster/dbscan.py +50 -0
  233. sklearnex/spmd/cluster/kmeans.py +21 -0
  234. sklearnex/spmd/cluster/tests/test_dbscan_spmd.py +97 -0
  235. sklearnex/spmd/cluster/tests/test_kmeans_spmd.py +173 -0
  236. sklearnex/spmd/covariance/__init__.py +20 -0
  237. sklearnex/spmd/covariance/covariance.py +21 -0
  238. sklearnex/spmd/covariance/incremental_covariance.py +37 -0
  239. sklearnex/spmd/covariance/tests/test_covariance_spmd.py +107 -0
  240. sklearnex/spmd/covariance/tests/test_incremental_covariance_spmd.py +184 -0
  241. sklearnex/spmd/decomposition/__init__.py +20 -0
  242. sklearnex/spmd/decomposition/incremental_pca.py +30 -0
  243. sklearnex/spmd/decomposition/pca.py +21 -0
  244. sklearnex/spmd/decomposition/tests/test_incremental_pca_spmd.py +269 -0
  245. sklearnex/spmd/decomposition/tests/test_pca_spmd.py +128 -0
  246. sklearnex/spmd/ensemble/__init__.py +19 -0
  247. sklearnex/spmd/ensemble/forest.py +71 -0
  248. sklearnex/spmd/ensemble/tests/test_forest_spmd.py +265 -0
  249. sklearnex/spmd/linear_model/__init__.py +21 -0
  250. sklearnex/spmd/linear_model/incremental_linear_model.py +35 -0
  251. sklearnex/spmd/linear_model/linear_model.py +21 -0
  252. sklearnex/spmd/linear_model/logistic_regression.py +21 -0
  253. sklearnex/spmd/linear_model/tests/test_incremental_linear_spmd.py +331 -0
  254. sklearnex/spmd/linear_model/tests/test_linear_regression_spmd.py +145 -0
  255. sklearnex/spmd/linear_model/tests/test_logistic_regression_spmd.py +162 -0
  256. sklearnex/spmd/neighbors/__init__.py +19 -0
  257. sklearnex/spmd/neighbors/neighbors.py +25 -0
  258. sklearnex/spmd/neighbors/tests/test_neighbors_spmd.py +288 -0
  259. sklearnex/svm/__init__.py +29 -0
  260. sklearnex/svm/_common.py +339 -0
  261. sklearnex/svm/nusvc.py +371 -0
  262. sklearnex/svm/nusvr.py +170 -0
  263. sklearnex/svm/svc.py +399 -0
  264. sklearnex/svm/svr.py +167 -0
  265. sklearnex/svm/tests/test_svm.py +93 -0
  266. sklearnex/tests/test_common.py +491 -0
  267. sklearnex/tests/test_config.py +123 -0
  268. sklearnex/tests/test_hyperparameters.py +43 -0
  269. sklearnex/tests/test_memory_usage.py +347 -0
  270. sklearnex/tests/test_monkeypatch.py +269 -0
  271. sklearnex/tests/test_n_jobs_support.py +108 -0
  272. sklearnex/tests/test_parallel.py +48 -0
  273. sklearnex/tests/test_patching.py +377 -0
  274. sklearnex/tests/test_run_to_run_stability.py +326 -0
  275. sklearnex/tests/utils/__init__.py +48 -0
  276. sklearnex/tests/utils/base.py +436 -0
  277. sklearnex/tests/utils/spmd.py +198 -0
  278. sklearnex/utils/__init__.py +19 -0
  279. sklearnex/utils/_array_api.py +82 -0
  280. sklearnex/utils/parallel.py +59 -0
  281. sklearnex/utils/tests/test_validation.py +238 -0
  282. sklearnex/utils/validation.py +208 -0
@@ -0,0 +1,1026 @@
1
+ # ==============================================================================
2
+ # Copyright 2014 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
+ import scipy.optimize as optimize
21
+ import scipy.sparse as sparse
22
+ import sklearn.linear_model._logistic as logistic_module
23
+ from sklearn.linear_model._sag import sag_solver
24
+ from sklearn.utils import (
25
+ check_array,
26
+ check_consistent_length,
27
+ check_random_state,
28
+ compute_class_weight,
29
+ )
30
+ from sklearn.utils.optimize import _check_optimize_result, _newton_cg
31
+ from sklearn.utils.validation import _check_sample_weight, check_is_fitted
32
+
33
+ import daal4py as d4p
34
+
35
+ from .._n_jobs_support import control_n_jobs
36
+ from .._utils import PatchingConditionsChain, getFPType, sklearn_check_version
37
+ from .logistic_loss import (
38
+ _daal4py_cross_entropy_loss_extra_args,
39
+ _daal4py_grad_,
40
+ _daal4py_grad_hess_,
41
+ _daal4py_logistic_loss_extra_args,
42
+ _daal4py_loss_,
43
+ _daal4py_loss_and_grad,
44
+ )
45
+
46
+ if sklearn_check_version("1.1"):
47
+ from sklearn._loss.loss import HalfBinomialLoss, HalfMultinomialLoss
48
+ from sklearn.linear_model._linear_loss import LinearModelLoss
49
+ from sklearn.linear_model._logistic import _LOGISTIC_SOLVER_CONVERGENCE_MSG
50
+ from sklearn.linear_model._logistic import (
51
+ LogisticRegression as LogisticRegression_original,
52
+ )
53
+ from sklearn.linear_model._logistic import (
54
+ _check_multi_class,
55
+ _check_solver,
56
+ _fit_liblinear,
57
+ )
58
+ else:
59
+ from sklearn.linear_model._logistic import (
60
+ _check_solver,
61
+ _check_multi_class,
62
+ _fit_liblinear,
63
+ _logistic_loss_and_grad,
64
+ _logistic_loss,
65
+ _logistic_grad_hess,
66
+ _multinomial_loss,
67
+ _multinomial_loss_grad,
68
+ _multinomial_grad_hess,
69
+ _LOGISTIC_SOLVER_CONVERGENCE_MSG,
70
+ LogisticRegression as LogisticRegression_original,
71
+ )
72
+
73
+ from sklearn.linear_model._logistic import _logistic_regression_path as lr_path_original
74
+ from sklearn.preprocessing import LabelBinarizer, LabelEncoder
75
+
76
+
77
+ # Code adapted from sklearn.linear_model.logistic version 0.21
78
+ def __logistic_regression_path(
79
+ X,
80
+ y,
81
+ pos_class=None,
82
+ Cs=10,
83
+ fit_intercept=True,
84
+ max_iter=100,
85
+ tol=1e-4,
86
+ verbose=0,
87
+ solver="lbfgs",
88
+ coef=None,
89
+ class_weight=None,
90
+ dual=False,
91
+ penalty="l2",
92
+ intercept_scaling=1.0,
93
+ multi_class="warn",
94
+ random_state=None,
95
+ check_input=True,
96
+ max_squared_sum=None,
97
+ sample_weight=None,
98
+ l1_ratio=None,
99
+ n_threads=1,
100
+ ):
101
+ """Compute a Logistic Regression model for a list of regularization
102
+ parameters.
103
+
104
+ This is an implementation that uses the result of the previous model
105
+ to speed up computations along the set of solutions, making it faster
106
+ than sequentially calling LogisticRegression for the different parameters.
107
+ Note that there will be no speedup with liblinear solver, since it does
108
+ not handle warm-starting.
109
+
110
+ Read more in the :ref:`User Guide <logistic_regression>`.
111
+
112
+ Parameters
113
+ ----------
114
+ X : array-like or sparse matrix, shape (n_samples, n_features)
115
+ Input data.
116
+
117
+ y : array-like, shape (n_samples,) or (n_samples, n_targets)
118
+ Input data, target values.
119
+
120
+ pos_class : int, None
121
+ The class with respect to which we perform a one-vs-all fit.
122
+ If None, then it is assumed that the given problem is binary.
123
+
124
+ Cs : int | array-like, shape (n_cs,)
125
+ List of values for the regularization parameter or integer specifying
126
+ the number of regularization parameters that should be used. In this
127
+ case, the parameters will be chosen in a logarithmic scale between
128
+ 1e-4 and 1e4.
129
+
130
+ fit_intercept : bool
131
+ Whether to fit an intercept for the model. In this case the shape of
132
+ the returned array is (n_cs, n_features + 1).
133
+
134
+ max_iter : int
135
+ Maximum number of iterations for the solver.
136
+
137
+ tol : float
138
+ Stopping criterion. For the newton-cg and lbfgs solvers, the iteration
139
+ will stop when ``max{|g_i | i = 1, ..., n} <= tol``
140
+ where ``g_i`` is the i-th component of the gradient.
141
+
142
+ verbose : int
143
+ For the liblinear and lbfgs solvers set verbose to any positive
144
+ number for verbosity.
145
+
146
+ solver : {'lbfgs', 'newton-cg', 'liblinear', 'sag', 'saga'}
147
+ Numerical solver to use.
148
+
149
+ coef : array-like, shape (n_features,), default None
150
+ Initialization value for coefficients of logistic regression.
151
+ Useless for liblinear solver.
152
+
153
+ class_weight : dict or 'balanced', optional
154
+ Weights associated with classes in the form ``{class_label: weight}``.
155
+ If not given, all classes are supposed to have weight one.
156
+
157
+ The "balanced" mode uses the values of y to automatically adjust
158
+ weights inversely proportional to class frequencies in the input data
159
+ as ``n_samples / (n_classes * np.bincount(y))``.
160
+
161
+ Note that these weights will be multiplied with sample_weight (passed
162
+ through the fit method) if sample_weight is specified.
163
+
164
+ dual : bool
165
+ Dual or primal formulation. Dual formulation is only implemented for
166
+ l2 penalty with liblinear solver. Prefer dual=False when
167
+ n_samples > n_features.
168
+
169
+ penalty : str, 'l1', 'l2', or 'elasticnet'
170
+ Used to specify the norm used in the penalization. The 'newton-cg',
171
+ 'sag' and 'lbfgs' solvers support only l2 penalties. 'elasticnet' is
172
+ only supported by the 'saga' solver.
173
+
174
+ intercept_scaling : float, default 1.
175
+ Useful only when the solver 'liblinear' is used
176
+ and self.fit_intercept is set to True. In this case, x becomes
177
+ [x, self.intercept_scaling],
178
+ i.e. a "synthetic" feature with constant value equal to
179
+ intercept_scaling is appended to the instance vector.
180
+ The intercept becomes ``intercept_scaling * synthetic_feature_weight``.
181
+
182
+ Note! the synthetic feature weight is subject to l1/l2 regularization
183
+ as all other features.
184
+ To lessen the effect of regularization on synthetic feature weight
185
+ (and therefore on the intercept) intercept_scaling has to be increased.
186
+
187
+ multi_class : str, {'ovr', 'multinomial', 'auto'}, default: 'ovr'
188
+ If the option chosen is 'ovr', then a binary problem is fit for each
189
+ label. For 'multinomial' the loss minimised is the multinomial loss fit
190
+ across the entire probability distribution, *even when the data is
191
+ binary*. 'multinomial' is unavailable when solver='liblinear'.
192
+ 'auto' selects 'ovr' if the data is binary, or if solver='liblinear',
193
+ and otherwise selects 'multinomial'.
194
+
195
+ .. versionadded:: 0.18
196
+ Stochastic Average Gradient descent solver for 'multinomial' case.
197
+ .. versionchanged:: 0.20
198
+ Default will change from 'ovr' to 'auto' in 0.22.
199
+
200
+ random_state : int, RandomState instance or None, optional, default None
201
+ The seed of the pseudo random number generator to use when shuffling
202
+ the data. If int, random_state is the seed used by the random number
203
+ generator; If RandomState instance, random_state is the random number
204
+ generator; If None, the random number generator is the RandomState
205
+ instance used by `np.random`. Used when ``solver`` == 'sag' or
206
+ 'liblinear'.
207
+
208
+ check_input : bool, default True
209
+ If False, the input arrays X and y will not be checked.
210
+
211
+ max_squared_sum : float, default None
212
+ Maximum squared sum of X over samples. Used only in SAG solver.
213
+ If None, it will be computed, going through all the samples.
214
+ The value should be precomputed to speed up cross validation.
215
+
216
+ sample_weight : array-like, shape(n_samples,) optional
217
+ Array of weights that are assigned to individual samples.
218
+ If not provided, then each sample is given unit weight.
219
+
220
+ l1_ratio : float or None, optional (default=None)
221
+ The Elastic-Net mixing parameter, with ``0 <= l1_ratio <= 1``. Only
222
+ used if ``penalty='elasticnet'``. Setting ``l1_ratio=0`` is equivalent
223
+ to using ``penalty='l2'``, while setting ``l1_ratio=1`` is equivalent
224
+ to using ``penalty='l1'``. For ``0 < l1_ratio <1``, the penalty is a
225
+ combination of L1 and L2.
226
+
227
+ Returns
228
+ -------
229
+ coefs : ndarray, shape (n_cs, n_features) or (n_cs, n_features + 1)
230
+ List of coefficients for the Logistic Regression model. If
231
+ fit_intercept is set to True then the second dimension will be
232
+ n_features + 1, where the last item represents the intercept. For
233
+ ``multiclass='multinomial'``, the shape is (n_classes, n_cs,
234
+ n_features) or (n_classes, n_cs, n_features + 1).
235
+
236
+ Cs : ndarray
237
+ Grid of Cs used for cross-validation.
238
+
239
+ n_iter : array, shape (n_cs,)
240
+ Actual number of iteration for each Cs.
241
+
242
+ Notes
243
+ -----
244
+ You might get slightly different results with the solver liblinear than
245
+ with the others since this uses LIBLINEAR which penalizes the intercept.
246
+
247
+ .. versionchanged:: 0.19
248
+ The "copy" parameter was removed.
249
+ """
250
+ _patching_status = PatchingConditionsChain(
251
+ "sklearn.linear_model.LogisticRegression.fit"
252
+ )
253
+ # TODO: remove this fallback workaround after
254
+ # logistic path is reworked to align with sklearn 1.2
255
+ _dal_ready = _patching_status.and_conditions(
256
+ [
257
+ (
258
+ not (sklearn_check_version("1.2") and solver == "newton-cholesky"),
259
+ f"'{solver}' solver is not supported. "
260
+ "Only 'lbfgs' and 'newton-cg' solvers are supported.",
261
+ )
262
+ ]
263
+ )
264
+ if not _dal_ready:
265
+ _patching_status.write_log()
266
+ return lr_path_original(
267
+ X,
268
+ y,
269
+ pos_class=pos_class,
270
+ Cs=Cs,
271
+ fit_intercept=fit_intercept,
272
+ max_iter=max_iter,
273
+ tol=tol,
274
+ verbose=verbose,
275
+ solver=solver,
276
+ coef=coef,
277
+ class_weight=class_weight,
278
+ dual=dual,
279
+ penalty=penalty,
280
+ intercept_scaling=intercept_scaling,
281
+ multi_class=multi_class,
282
+ random_state=random_state,
283
+ check_input=check_input,
284
+ max_squared_sum=max_squared_sum,
285
+ sample_weight=sample_weight,
286
+ l1_ratio=l1_ratio,
287
+ n_threads=n_threads,
288
+ )
289
+
290
+ if isinstance(Cs, numbers.Integral):
291
+ Cs = np.logspace(-4, 4, Cs)
292
+
293
+ solver = _check_solver(solver, penalty, dual)
294
+
295
+ # Preprocessing.
296
+ if check_input:
297
+ if sklearn_check_version("1.1"):
298
+ X = check_array(
299
+ X,
300
+ accept_sparse="csr",
301
+ dtype=np.float64,
302
+ accept_large_sparse=solver not in ["liblinear", "sag", "saga"],
303
+ )
304
+ else:
305
+ X = check_array(
306
+ X,
307
+ accept_sparse="csr",
308
+ dtype=np.float64,
309
+ accept_large_sparse=solver != "liblinear",
310
+ )
311
+ y = check_array(y, ensure_2d=False, dtype=None)
312
+ check_consistent_length(X, y)
313
+ _, n_features = X.shape
314
+
315
+ classes = np.unique(y)
316
+ random_state = check_random_state(random_state)
317
+
318
+ multi_class = _check_multi_class(multi_class, solver, len(classes))
319
+ if pos_class is None and multi_class != "multinomial":
320
+ if classes.size > 2:
321
+ raise ValueError("To fit OvR, use the pos_class argument")
322
+ # np.unique(y) gives labels in sorted order.
323
+ pos_class = classes[1]
324
+
325
+ _dal_ready = _patching_status.and_conditions(
326
+ [
327
+ (
328
+ solver in ["lbfgs", "newton-cg"],
329
+ f"'{solver}' solver is not supported. "
330
+ "Only 'lbfgs' and 'newton-cg' solvers are supported.",
331
+ ),
332
+ (not sparse.issparse(X), "X is sparse. Sparse input is not supported."),
333
+ (sample_weight is None, "Sample weights are not supported."),
334
+ (class_weight is None, "Class weights are not supported."),
335
+ ]
336
+ )
337
+
338
+ if not _dal_ready:
339
+ sample_weight = _check_sample_weight(sample_weight, X, dtype=X.dtype, copy=True)
340
+ # If class_weights is a dict (provided by the user), the weights
341
+ # are assigned to the original labels. If it is "balanced", then
342
+ # the class_weights are assigned after masking the labels with a OvR.
343
+ le = LabelEncoder()
344
+ if (
345
+ isinstance(class_weight, dict) or multi_class == "multinomial"
346
+ ) and not _dal_ready:
347
+ class_weight_ = compute_class_weight(class_weight, classes=classes, y=y)
348
+ if not np.allclose(class_weight_, np.ones_like(class_weight_)):
349
+ sample_weight *= class_weight_[le.fit_transform(y)]
350
+
351
+ # For doing a ovr, we need to mask the labels first. for the
352
+ # multinomial case this is not necessary.
353
+ if multi_class == "ovr":
354
+ y_bin = np.ones(y.shape, dtype=X.dtype)
355
+
356
+ if sklearn_check_version("1.1"):
357
+ mask = y == pos_class
358
+ y_bin = np.ones(y.shape, dtype=X.dtype)
359
+ # for compute_class_weight
360
+
361
+ if solver in ["lbfgs", "newton-cg"]:
362
+ # HalfBinomialLoss, used for those solvers, represents y in [0, 1] instead
363
+ # of in [-1, 1].
364
+ mask_classes = np.array([0, 1])
365
+ y_bin[~mask] = 0.0
366
+ else:
367
+ mask_classes = np.array([-1, 1])
368
+ y_bin[~mask] = -1.0
369
+ else:
370
+ mask_classes = np.array([-1, 1])
371
+ mask = y == pos_class
372
+ y_bin[~mask] = -1.0
373
+ # for compute_class_weight
374
+
375
+ if class_weight == "balanced" and not _dal_ready:
376
+ class_weight_ = compute_class_weight(
377
+ class_weight, classes=mask_classes, y=y_bin
378
+ )
379
+ if not np.allclose(class_weight_, np.ones_like(class_weight_)):
380
+ sample_weight *= class_weight_[le.fit_transform(y_bin)]
381
+
382
+ if _dal_ready:
383
+ w0 = np.zeros(n_features + 1, dtype=X.dtype)
384
+ y_bin[~mask] = 0.0
385
+ else:
386
+ w0 = np.zeros(n_features + int(fit_intercept), dtype=X.dtype)
387
+
388
+ else:
389
+ if sklearn_check_version("1.1"):
390
+ if solver in ["sag", "saga", "lbfgs", "newton-cg"]:
391
+ # SAG, lbfgs and newton-cg multinomial solvers need LabelEncoder,
392
+ # not LabelBinarizer, i.e. y as a 1d-array of integers.
393
+ # LabelEncoder also saves memory compared to LabelBinarizer, especially
394
+ # when n_classes is large.
395
+ if _dal_ready:
396
+ Y_multi = le.fit_transform(y).astype(X.dtype, copy=False)
397
+ else:
398
+ le = LabelEncoder()
399
+ Y_multi = le.fit_transform(y).astype(X.dtype, copy=False)
400
+ else:
401
+ # For liblinear solver, apply LabelBinarizer, i.e. y is one-hot encoded.
402
+ lbin = LabelBinarizer()
403
+ Y_multi = lbin.fit_transform(y)
404
+ if Y_multi.shape[1] == 1:
405
+ Y_multi = np.hstack([1 - Y_multi, Y_multi])
406
+ else:
407
+ if solver not in ["sag", "saga"]:
408
+ if _dal_ready:
409
+ Y_multi = le.fit_transform(y).astype(X.dtype, copy=False)
410
+ else:
411
+ lbin = LabelBinarizer()
412
+ Y_multi = lbin.fit_transform(y)
413
+ if Y_multi.shape[1] == 1:
414
+ Y_multi = np.hstack([1 - Y_multi, Y_multi])
415
+ else:
416
+ # SAG multinomial solver needs LabelEncoder, not LabelBinarizer
417
+ le = LabelEncoder()
418
+ Y_multi = le.fit_transform(y).astype(X.dtype, copy=False)
419
+
420
+ if _dal_ready:
421
+ w0 = np.zeros((classes.size, n_features + 1), order="C", dtype=X.dtype)
422
+ else:
423
+ w0 = np.zeros(
424
+ (classes.size, n_features + int(fit_intercept)), order="F", dtype=X.dtype
425
+ )
426
+
427
+ # Adoption of https://github.com/scikit-learn/scikit-learn/pull/26721
428
+ if solver in ["lbfgs", "newton-cg", "newton-cholesky"]:
429
+ sw_sum = len(X) if sample_weight is None else np.sum(sample_weight)
430
+
431
+ if coef is not None:
432
+ # it must work both giving the bias term and not
433
+ if multi_class == "ovr":
434
+ if coef.size not in (n_features, w0.size):
435
+ raise ValueError(
436
+ "Initialization coef is of shape %d, expected shape "
437
+ "%d or %d" % (coef.size, n_features, w0.size)
438
+ )
439
+ if _dal_ready:
440
+ w0[-coef.size :] = (
441
+ np.roll(coef, 1, -1) if coef.size != n_features else coef
442
+ )
443
+ else:
444
+ w0[: coef.size] = coef
445
+ else:
446
+ # For binary problems coef.shape[0] should be 1, otherwise it
447
+ # should be classes.size.
448
+ n_classes = classes.size
449
+ if n_classes == 2:
450
+ n_classes = 1
451
+
452
+ if coef.shape[0] != n_classes or coef.shape[1] not in (
453
+ n_features,
454
+ n_features + 1,
455
+ ):
456
+ raise ValueError(
457
+ "Initialization coef is of shape (%d, %d), expected "
458
+ "shape (%d, %d) or (%d, %d)"
459
+ % (
460
+ coef.shape[0],
461
+ coef.shape[1],
462
+ classes.size,
463
+ n_features,
464
+ classes.size,
465
+ n_features + 1,
466
+ )
467
+ )
468
+
469
+ if _dal_ready:
470
+ w0[:, -coef.shape[1] :] = (
471
+ np.roll(coef, 1, -1) if coef.shape[1] != n_features else coef
472
+ )
473
+ else:
474
+ if n_classes == 1:
475
+ w0[0, : coef.shape[1]] = -coef
476
+ w0[1, : coef.shape[1]] = coef
477
+ else:
478
+ w0[:, : coef.shape[1]] = coef
479
+
480
+ C_daal_multiplier = 1
481
+ # commented out because this is Py3 feature
482
+ # def _map_to_binary_logistic_regression():
483
+ # nonlocal C_daal_multiplier
484
+ # nonlocal w0
485
+ # C_daal_multiplier = 2
486
+ # w0 *= 2
487
+
488
+ if multi_class == "multinomial":
489
+ # fmin_l_bfgs_b and newton-cg accepts only ravelled parameters.
490
+ if solver in ["lbfgs", "newton-cg"]:
491
+ if _dal_ready and classes.size == 2:
492
+ w0 = w0[-1:, :]
493
+ if sklearn_check_version("1.1"):
494
+ w0 = w0.ravel(order="F")
495
+ else:
496
+ w0 = w0.ravel()
497
+ target = Y_multi
498
+ loss = None
499
+ if sklearn_check_version("1.1"):
500
+ loss = LinearModelLoss(
501
+ base_loss=HalfMultinomialLoss(n_classes=classes.size),
502
+ fit_intercept=fit_intercept,
503
+ )
504
+ if solver == "lbfgs":
505
+ if _dal_ready:
506
+ if classes.size == 2:
507
+ # _map_to_binary_logistic_regression()
508
+ C_daal_multiplier = 2
509
+ w0 *= 2
510
+ daal_extra_args_func = _daal4py_logistic_loss_extra_args
511
+ else:
512
+ daal_extra_args_func = _daal4py_cross_entropy_loss_extra_args
513
+ func = _daal4py_loss_and_grad
514
+ else:
515
+ if sklearn_check_version("1.1") and loss is not None:
516
+ func = loss.loss_gradient
517
+ else:
518
+
519
+ def func(x, *args):
520
+ return _multinomial_loss_grad(x, *args)[0:2]
521
+
522
+ elif solver == "newton-cg":
523
+ if _dal_ready:
524
+ if classes.size == 2:
525
+ # _map_to_binary_logistic_regression()
526
+ C_daal_multiplier = 2
527
+ w0 *= 2
528
+ daal_extra_args_func = _daal4py_logistic_loss_extra_args
529
+ else:
530
+ daal_extra_args_func = _daal4py_cross_entropy_loss_extra_args
531
+ func = _daal4py_loss_
532
+ grad = _daal4py_grad_
533
+ hess = _daal4py_grad_hess_
534
+ else:
535
+ if sklearn_check_version("1.1") and loss is not None:
536
+ func = loss.loss
537
+ grad = loss.gradient
538
+ hess = loss.gradient_hessian_product # hess = [gradient, hessp]
539
+ else:
540
+
541
+ def func(x, *args):
542
+ return _multinomial_loss(x, *args)[0]
543
+
544
+ def grad(x, *args):
545
+ return _multinomial_loss_grad(x, *args)[1]
546
+
547
+ hess = _multinomial_grad_hess
548
+ warm_start_sag = {"coef": w0.T}
549
+ else:
550
+ target = y_bin
551
+ if solver == "lbfgs":
552
+ if _dal_ready:
553
+ func = _daal4py_loss_and_grad
554
+ daal_extra_args_func = _daal4py_logistic_loss_extra_args
555
+ else:
556
+ if sklearn_check_version("1.1"):
557
+ loss = LinearModelLoss(
558
+ base_loss=HalfBinomialLoss(), fit_intercept=fit_intercept
559
+ )
560
+ func = loss.loss_gradient
561
+ else:
562
+ func = _logistic_loss_and_grad
563
+ elif solver == "newton-cg":
564
+ if _dal_ready:
565
+ daal_extra_args_func = _daal4py_logistic_loss_extra_args
566
+ func = _daal4py_loss_
567
+ grad = _daal4py_grad_
568
+ hess = _daal4py_grad_hess_
569
+ else:
570
+ if sklearn_check_version("1.1"):
571
+ loss = LinearModelLoss(
572
+ base_loss=HalfBinomialLoss(), fit_intercept=fit_intercept
573
+ )
574
+ func = loss.loss
575
+ grad = loss.gradient
576
+ hess = loss.gradient_hessian_product # hess = [gradient, hessp]
577
+ else:
578
+ func = _logistic_loss
579
+
580
+ def grad(x, *args):
581
+ return _logistic_loss_and_grad(x, *args)[1]
582
+
583
+ hess = _logistic_grad_hess
584
+ warm_start_sag = {"coef": np.expand_dims(w0, axis=1)}
585
+
586
+ coefs = list()
587
+ n_iter = np.zeros(len(Cs), dtype=np.int32)
588
+ for i, C in enumerate(Cs):
589
+ if solver == "lbfgs":
590
+ if _dal_ready:
591
+ extra_args = daal_extra_args_func(
592
+ classes.size,
593
+ w0,
594
+ X,
595
+ target,
596
+ 0.0,
597
+ 1.0 / (2 * C * C_daal_multiplier * sw_sum),
598
+ fit_intercept,
599
+ value=True,
600
+ gradient=True,
601
+ hessian=False,
602
+ )
603
+ else:
604
+ if sklearn_check_version("1.1"):
605
+ l2_reg_strength = 1.0 / (C * sw_sum)
606
+ extra_args = (X, target, sample_weight, l2_reg_strength, n_threads)
607
+ else:
608
+ extra_args = (X, target, 1.0 / (C * sw_sum), sample_weight)
609
+
610
+ iprint = [-1, 50, 1, 100, 101][
611
+ np.searchsorted(np.array([0, 1, 2, 3]), verbose)
612
+ ]
613
+ opt_res = optimize.minimize(
614
+ func,
615
+ w0,
616
+ method="L-BFGS-B",
617
+ jac=True,
618
+ args=extra_args,
619
+ options={
620
+ "maxiter": max_iter,
621
+ "maxls": 50,
622
+ "iprint": iprint,
623
+ "gtol": tol,
624
+ "ftol": 64 * np.finfo(float).eps,
625
+ },
626
+ )
627
+ n_iter_i = _check_optimize_result(
628
+ solver,
629
+ opt_res,
630
+ max_iter,
631
+ extra_warning_msg=_LOGISTIC_SOLVER_CONVERGENCE_MSG,
632
+ )
633
+ w0, loss = opt_res.x, opt_res.fun
634
+ if _dal_ready and C_daal_multiplier == 2:
635
+ w0 /= 2
636
+ elif solver == "newton-cg":
637
+ if _dal_ready:
638
+
639
+ def make_ncg_funcs(f, value=False, gradient=False, hessian=False):
640
+ daal_penaltyL2 = 1.0 / (2 * C * C_daal_multiplier * sw_sum)
641
+ _obj_, X_, y_, n_samples = daal_extra_args_func(
642
+ classes.size,
643
+ w0,
644
+ X,
645
+ target,
646
+ 0.0,
647
+ daal_penaltyL2,
648
+ fit_intercept,
649
+ value=value,
650
+ gradient=gradient,
651
+ hessian=hessian,
652
+ )
653
+
654
+ def _func_(x, *args):
655
+ return f(x, _obj_, *args)
656
+
657
+ return _func_, (X_, y_, n_samples, daal_penaltyL2)
658
+
659
+ loss_func, extra_args = make_ncg_funcs(func, value=True)
660
+ grad_func, _ = make_ncg_funcs(grad, gradient=True)
661
+ grad_hess_func, _ = make_ncg_funcs(hess, gradient=True)
662
+ w0, n_iter_i = _newton_cg(
663
+ grad_hess_func,
664
+ loss_func,
665
+ grad_func,
666
+ w0,
667
+ args=extra_args,
668
+ maxiter=max_iter,
669
+ tol=tol,
670
+ )
671
+ else:
672
+ if sklearn_check_version("1.1"):
673
+ l2_reg_strength = 1.0 / (C * sw_sum)
674
+ args = (X, target, sample_weight, l2_reg_strength, n_threads)
675
+ else:
676
+ args = (X, target, 1.0 / (C * sw_sum), sample_weight)
677
+
678
+ w0, n_iter_i = _newton_cg(
679
+ hess, func, grad, w0, args=args, maxiter=max_iter, tol=tol
680
+ )
681
+ elif solver == "liblinear":
682
+ (
683
+ coef_,
684
+ intercept_,
685
+ n_iter_i,
686
+ ) = _fit_liblinear(
687
+ X,
688
+ target,
689
+ C,
690
+ fit_intercept,
691
+ intercept_scaling,
692
+ None,
693
+ penalty,
694
+ dual,
695
+ verbose,
696
+ max_iter,
697
+ tol,
698
+ random_state,
699
+ sample_weight=sample_weight,
700
+ )
701
+ if fit_intercept:
702
+ w0 = np.concatenate([coef_.ravel(), intercept_])
703
+ else:
704
+ w0 = coef_.ravel()
705
+
706
+ elif solver in ["sag", "saga"]:
707
+ if multi_class == "multinomial":
708
+ target = target.astype(X.dtype, copy=False)
709
+ loss = "multinomial"
710
+ else:
711
+ loss = "log"
712
+ # alpha is for L2-norm, beta is for L1-norm
713
+ if penalty == "l1":
714
+ alpha = 0.0
715
+ beta = 1.0 / C
716
+ elif penalty == "l2":
717
+ alpha = 1.0 / C
718
+ beta = 0.0
719
+ else: # Elastic-Net penalty
720
+ alpha = (1.0 / C) * (1 - l1_ratio)
721
+ beta = (1.0 / C) * l1_ratio
722
+
723
+ w0, n_iter_i, warm_start_sag = sag_solver(
724
+ X,
725
+ target,
726
+ sample_weight,
727
+ loss,
728
+ alpha,
729
+ beta,
730
+ max_iter,
731
+ tol,
732
+ verbose,
733
+ random_state,
734
+ False,
735
+ max_squared_sum,
736
+ warm_start_sag,
737
+ is_saga=(solver == "saga"),
738
+ )
739
+
740
+ else:
741
+ raise ValueError(
742
+ "solver must be one of {'liblinear', 'lbfgs', "
743
+ "'newton-cg', 'sag'}, got '%s' instead" % solver
744
+ )
745
+
746
+ if multi_class == "multinomial":
747
+ if _dal_ready:
748
+ if classes.size == 2:
749
+ multi_w0 = w0[np.newaxis, :]
750
+ else:
751
+ multi_w0 = np.reshape(w0, (classes.size, -1))
752
+ else:
753
+ n_classes = max(2, classes.size)
754
+ if sklearn_check_version("1.1"):
755
+ if solver in ["lbfgs", "newton-cg"]:
756
+ multi_w0 = np.reshape(w0, (n_classes, -1), order="F")
757
+ else:
758
+ multi_w0 = w0
759
+ else:
760
+ multi_w0 = np.reshape(w0, (n_classes, -1))
761
+ if n_classes == 2:
762
+ multi_w0 = multi_w0[1][np.newaxis, :]
763
+ coefs.append(multi_w0.copy())
764
+ else:
765
+ coefs.append(w0.copy())
766
+
767
+ n_iter[i] = n_iter_i
768
+
769
+ if _dal_ready:
770
+ if fit_intercept:
771
+ for i, ci in enumerate(coefs):
772
+ coefs[i] = np.roll(ci, -1, -1)
773
+ else:
774
+ for i, ci in enumerate(coefs):
775
+ coefs[i] = np.delete(ci, 0, axis=-1)
776
+
777
+ _patching_status.write_log()
778
+
779
+ return np.array(coefs), np.array(Cs), n_iter
780
+
781
+
782
+ def daal4py_fit(self, X, y, sample_weight=None):
783
+ which, what = logistic_module, "_logistic_regression_path"
784
+ replacer = logistic_regression_path
785
+ descriptor = getattr(which, what, None)
786
+ setattr(which, what, replacer)
787
+ try:
788
+ clf = LogisticRegression_original.fit(self, X, y, sample_weight)
789
+ finally:
790
+ setattr(which, what, descriptor)
791
+ return clf
792
+
793
+
794
+ def daal4py_predict(self, X, resultsToEvaluate):
795
+ check_is_fitted(self)
796
+ if sklearn_check_version("1.0"):
797
+ self._check_feature_names(X, reset=False)
798
+ X = check_array(X, accept_sparse="csr", dtype=[np.float64, np.float32])
799
+ try:
800
+ fptype = getFPType(X)
801
+ except ValueError:
802
+ fptype = None
803
+
804
+ if resultsToEvaluate == "computeClassLabels":
805
+ _function_name = "predict"
806
+ elif resultsToEvaluate == "computeClassProbabilities":
807
+ _function_name = "predict_proba"
808
+ elif resultsToEvaluate == "computeClassLogProbabilities":
809
+ _function_name = "predict_log_proba"
810
+ else:
811
+ raise ValueError(
812
+ "resultsToEvaluate must be in [computeClassLabels, \
813
+ computeClassProbabilities, computeClassLogProbabilities]"
814
+ )
815
+
816
+ _patching_status = PatchingConditionsChain(
817
+ f"sklearn.linear_model.LogisticRegression.{_function_name}"
818
+ )
819
+ if _function_name != "predict":
820
+ _patching_status.and_conditions(
821
+ [
822
+ (
823
+ self.classes_.size == 2
824
+ or logistic_module._check_multi_class(
825
+ self.multi_class if self.multi_class != "deprecated" else "auto",
826
+ self.solver,
827
+ self.classes_.size,
828
+ )
829
+ != "ovr",
830
+ f"selected multiclass option is not supported for n_classes > 2.",
831
+ ),
832
+ ],
833
+ )
834
+
835
+ _dal_ready = _patching_status.and_conditions(
836
+ [
837
+ (not sparse.issparse(X), "X is sparse. Sparse input is not supported."),
838
+ (
839
+ not sparse.issparse(self.coef_),
840
+ "self.coef_ is sparse. Sparse coefficients are not supported.",
841
+ ),
842
+ (fptype is not None, "Unable to get dtype."),
843
+ ]
844
+ )
845
+
846
+ _patching_status.write_log()
847
+ if _dal_ready:
848
+ n_features = self.coef_.shape[1]
849
+ if X.shape[1] != n_features:
850
+ raise ValueError(
851
+ f"X has {X.shape[1]} features, "
852
+ f"but LogisticRegression is expecting {n_features} features as input"
853
+ )
854
+ builder = d4p.logistic_regression_model_builder(X.shape[1], len(self.classes_))
855
+ builder.set_beta(self.coef_, self.intercept_)
856
+ predict = d4p.logistic_regression_prediction(
857
+ nClasses=len(self.classes_),
858
+ fptype=fptype,
859
+ method="defaultDense",
860
+ resultsToEvaluate=resultsToEvaluate,
861
+ )
862
+ res = predict.compute(X, builder.model)
863
+ if resultsToEvaluate == "computeClassLabels":
864
+ res = res.prediction
865
+ if (
866
+ not np.array_equal(self.classes_, np.arange(0, len(self.classes_)))
867
+ or self.classes_.dtype != X.dtype
868
+ ):
869
+ res = self.classes_.take(np.asarray(res, dtype=np.intp))
870
+ elif resultsToEvaluate == "computeClassProbabilities":
871
+ res = res.probabilities
872
+ elif resultsToEvaluate == "computeClassLogProbabilities":
873
+ res = res.logProbabilities
874
+ else:
875
+ raise ValueError(
876
+ "resultsToEvaluate must be in [computeClassLabels, \
877
+ computeClassProbabilities, computeClassLogProbabilities]"
878
+ )
879
+ if res.shape[1] == 1:
880
+ res = np.ravel(res)
881
+ return res
882
+
883
+ if resultsToEvaluate == "computeClassLabels":
884
+ return LogisticRegression_original.predict(self, X)
885
+ if resultsToEvaluate == "computeClassProbabilities":
886
+ return LogisticRegression_original.predict_proba(self, X)
887
+ if resultsToEvaluate == "computeClassLogProbabilities":
888
+ return LogisticRegression_original.predict_log_proba(self, X)
889
+
890
+
891
+ def logistic_regression_path(
892
+ X,
893
+ y,
894
+ pos_class=None,
895
+ Cs=10,
896
+ fit_intercept=True,
897
+ max_iter=100,
898
+ tol=1e-4,
899
+ verbose=0,
900
+ solver="lbfgs",
901
+ coef=None,
902
+ class_weight=None,
903
+ dual=False,
904
+ penalty="l2",
905
+ intercept_scaling=1.0,
906
+ multi_class="auto",
907
+ random_state=None,
908
+ check_input=True,
909
+ max_squared_sum=None,
910
+ sample_weight=None,
911
+ l1_ratio=None,
912
+ n_threads=1,
913
+ ):
914
+ if sklearn_check_version("1.1"):
915
+ return __logistic_regression_path(
916
+ X,
917
+ y,
918
+ pos_class=pos_class,
919
+ Cs=Cs,
920
+ fit_intercept=fit_intercept,
921
+ max_iter=max_iter,
922
+ tol=tol,
923
+ verbose=verbose,
924
+ solver=solver,
925
+ coef=coef,
926
+ class_weight=class_weight,
927
+ dual=dual,
928
+ penalty=penalty,
929
+ intercept_scaling=intercept_scaling,
930
+ multi_class=multi_class,
931
+ random_state=random_state,
932
+ check_input=check_input,
933
+ max_squared_sum=max_squared_sum,
934
+ sample_weight=sample_weight,
935
+ l1_ratio=l1_ratio,
936
+ n_threads=n_threads,
937
+ )
938
+ return __logistic_regression_path(
939
+ X,
940
+ y,
941
+ pos_class=pos_class,
942
+ Cs=Cs,
943
+ fit_intercept=fit_intercept,
944
+ max_iter=max_iter,
945
+ tol=tol,
946
+ verbose=verbose,
947
+ solver=solver,
948
+ coef=coef,
949
+ class_weight=class_weight,
950
+ dual=dual,
951
+ penalty=penalty,
952
+ intercept_scaling=intercept_scaling,
953
+ multi_class=multi_class,
954
+ random_state=random_state,
955
+ check_input=check_input,
956
+ max_squared_sum=max_squared_sum,
957
+ sample_weight=sample_weight,
958
+ l1_ratio=l1_ratio,
959
+ )
960
+
961
+
962
+ @control_n_jobs(
963
+ decorated_methods=["fit", "predict", "predict_proba", "predict_log_proba"]
964
+ )
965
+ class LogisticRegression(LogisticRegression_original):
966
+ __doc__ = LogisticRegression_original.__doc__
967
+
968
+ if sklearn_check_version("1.2"):
969
+ _parameter_constraints: dict = {
970
+ **LogisticRegression_original._parameter_constraints
971
+ }
972
+
973
+ def __init__(
974
+ self,
975
+ penalty="l2",
976
+ dual=False,
977
+ tol=1e-4,
978
+ C=1.0,
979
+ fit_intercept=True,
980
+ intercept_scaling=1,
981
+ class_weight=None,
982
+ random_state=None,
983
+ solver="lbfgs",
984
+ max_iter=100,
985
+ multi_class="auto",
986
+ verbose=0,
987
+ warm_start=False,
988
+ n_jobs=None,
989
+ l1_ratio=None,
990
+ ):
991
+ self.penalty = penalty
992
+ self.dual = dual
993
+ self.tol = tol
994
+ self.C = C
995
+ self.fit_intercept = fit_intercept
996
+ self.intercept_scaling = intercept_scaling
997
+ self.class_weight = class_weight
998
+ self.random_state = random_state
999
+ self.solver = solver
1000
+ self.max_iter = max_iter
1001
+ self.multi_class = multi_class
1002
+ self.verbose = verbose
1003
+ self.warm_start = warm_start
1004
+ self.n_jobs = n_jobs
1005
+ self.l1_ratio = l1_ratio
1006
+
1007
+ def fit(self, X, y, sample_weight=None):
1008
+ if sklearn_check_version("1.0"):
1009
+ self._check_feature_names(X, reset=True)
1010
+ if sklearn_check_version("1.2"):
1011
+ self._validate_params()
1012
+ return daal4py_fit(self, X, y, sample_weight)
1013
+
1014
+ def predict(self, X):
1015
+ return daal4py_predict(self, X, "computeClassLabels")
1016
+
1017
+ def predict_log_proba(self, X):
1018
+ return daal4py_predict(self, X, "computeClassLogProbabilities")
1019
+
1020
+ def predict_proba(self, X):
1021
+ return daal4py_predict(self, X, "computeClassProbabilities")
1022
+
1023
+ fit.__doc__ = LogisticRegression_original.fit.__doc__
1024
+ predict.__doc__ = LogisticRegression_original.predict.__doc__
1025
+ predict_log_proba.__doc__ = LogisticRegression_original.predict_log_proba.__doc__
1026
+ predict_proba.__doc__ = LogisticRegression_original.predict_proba.__doc__