scikit-learn-intelex 2024.3.0__py312-none-win_amd64.whl → 2024.4.0__py312-none-win_amd64.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.
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/_device_offload.py +31 -4
- {scikit_learn_intelex-2024.3.0.data/data/Lib/site-packages/sklearnex/spmd → scikit_learn_intelex-2024.4.0.data/data/Lib/site-packages/sklearnex}/basic_statistics/__init__.py +2 -1
- scikit_learn_intelex-2024.4.0.data/data/Lib/site-packages/sklearnex/basic_statistics/incremental_basic_statistics.py +288 -0
- scikit_learn_intelex-2024.4.0.data/data/Lib/site-packages/sklearnex/basic_statistics/tests/test_incremental_basic_statistics.py +386 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/decomposition/pca.py +3 -6
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/dispatcher.py +2 -2
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/ensemble/_forest.py +68 -75
- scikit_learn_intelex-2024.4.0.data/data/Lib/site-packages/sklearnex/linear_model/linear.py +316 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/linear_model/logistic_regression.py +50 -9
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/linear_model/tests/test_linear.py +40 -5
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/neighbors/_lof.py +53 -36
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/neighbors/common.py +4 -1
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/neighbors/knn_classification.py +37 -122
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/neighbors/knn_regression.py +10 -117
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/neighbors/knn_unsupervised.py +6 -78
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/preview/cluster/k_means.py +5 -73
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/preview/covariance/covariance.py +6 -5
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/preview/covariance/tests/test_covariance.py +18 -5
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/svm/_common.py +4 -7
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/svm/nusvc.py +66 -50
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/svm/nusvr.py +3 -49
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/svm/svc.py +66 -51
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/svm/svr.py +3 -49
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/tests/_utils.py +14 -5
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/tests/test_n_jobs_support.py +8 -2
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/tests/test_patching.py +64 -54
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/utils/__init__.py +2 -1
- scikit_learn_intelex-2024.4.0.data/data/Lib/site-packages/sklearnex/utils/_namespace.py +97 -0
- {scikit_learn_intelex-2024.3.0.dist-info → scikit_learn_intelex-2024.4.0.dist-info}/METADATA +2 -2
- scikit_learn_intelex-2024.4.0.dist-info/RECORD +101 -0
- scikit_learn_intelex-2024.3.0.data/data/Lib/site-packages/sklearnex/linear_model/linear.py +0 -381
- scikit_learn_intelex-2024.3.0.dist-info/RECORD +0 -98
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/__init__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/__main__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/_config.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/_utils.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/basic_statistics/basic_statistics.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/cluster/__init__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/cluster/dbscan.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/cluster/k_means.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/cluster/tests/test_dbscan.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/cluster/tests/test_kmeans.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/conftest.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/covariance/__init__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/covariance/incremental_covariance.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/covariance/tests/test_incremental_covariance.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/decomposition/__init__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/decomposition/tests/test_pca.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/doc/third-party-programs.txt +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/ensemble/__init__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/ensemble/tests/test_forest.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/glob/__main__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/glob/dispatcher.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/linear_model/__init__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/linear_model/coordinate_descent.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/linear_model/logistic_path.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/linear_model/ridge.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/linear_model/tests/test_logreg.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/manifold/__init__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/manifold/t_sne.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/manifold/tests/test_tsne.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/metrics/__init__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/metrics/pairwise.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/metrics/ranking.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/metrics/tests/test_metrics.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/model_selection/__init__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/model_selection/split.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/model_selection/tests/test_model_selection.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/neighbors/__init__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/neighbors/tests/test_neighbors.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/preview/__init__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/preview/cluster/__init__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/preview/cluster/_common.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/preview/covariance/__init__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/spmd/__init__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data/data/Lib/site-packages/sklearnex → scikit_learn_intelex-2024.4.0.data/data/Lib/site-packages/sklearnex/spmd}/basic_statistics/__init__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/spmd/basic_statistics/basic_statistics.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/spmd/cluster/__init__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/spmd/cluster/dbscan.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/spmd/cluster/kmeans.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/spmd/covariance/__init__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/spmd/covariance/covariance.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/spmd/decomposition/__init__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/spmd/decomposition/pca.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/spmd/ensemble/__init__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/spmd/ensemble/forest.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/spmd/linear_model/__init__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/spmd/linear_model/linear_model.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/spmd/linear_model/logistic_regression.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/spmd/neighbors/__init__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/spmd/neighbors/neighbors.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/svm/__init__.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/svm/tests/test_svm.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/tests/test_config.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/tests/test_memory_usage.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/tests/test_monkeypatch.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/tests/test_parallel.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/tests/test_run_to_run_stability_tests.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/utils/parallel.py +0 -0
- {scikit_learn_intelex-2024.3.0.data → scikit_learn_intelex-2024.4.0.data}/data/Lib/site-packages/sklearnex/utils/validation.py +0 -0
- {scikit_learn_intelex-2024.3.0.dist-info → scikit_learn_intelex-2024.4.0.dist-info}/LICENSE.txt +0 -0
- {scikit_learn_intelex-2024.3.0.dist-info → scikit_learn_intelex-2024.4.0.dist-info}/WHEEL +0 -0
- {scikit_learn_intelex-2024.3.0.dist-info → scikit_learn_intelex-2024.4.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
# ===============================================================================
|
|
2
|
+
# Copyright 2023 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 logging
|
|
18
|
+
from abc import ABC
|
|
19
|
+
|
|
20
|
+
import numpy as np
|
|
21
|
+
from sklearn.exceptions import NotFittedError
|
|
22
|
+
from sklearn.linear_model import LinearRegression as sklearn_LinearRegression
|
|
23
|
+
|
|
24
|
+
from daal4py.sklearn._n_jobs_support import control_n_jobs
|
|
25
|
+
from daal4py.sklearn._utils import sklearn_check_version
|
|
26
|
+
|
|
27
|
+
from .._device_offload import dispatch, wrap_output_data
|
|
28
|
+
from .._utils import PatchingConditionsChain, get_patch_message, register_hyperparameters
|
|
29
|
+
from ..utils.validation import _assert_all_finite
|
|
30
|
+
|
|
31
|
+
if sklearn_check_version("1.0") and not sklearn_check_version("1.2"):
|
|
32
|
+
from sklearn.linear_model._base import _deprecate_normalize
|
|
33
|
+
|
|
34
|
+
from scipy.sparse import issparse
|
|
35
|
+
from sklearn.utils.validation import check_X_y
|
|
36
|
+
|
|
37
|
+
from onedal.common.hyperparameters import get_hyperparameters
|
|
38
|
+
from onedal.linear_model import LinearRegression as onedal_LinearRegression
|
|
39
|
+
from onedal.utils import _num_features, _num_samples
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@register_hyperparameters({"fit": get_hyperparameters("linear_regression", "train")})
|
|
43
|
+
@control_n_jobs(decorated_methods=["fit", "predict"])
|
|
44
|
+
class LinearRegression(sklearn_LinearRegression):
|
|
45
|
+
__doc__ = sklearn_LinearRegression.__doc__
|
|
46
|
+
|
|
47
|
+
if sklearn_check_version("1.2"):
|
|
48
|
+
_parameter_constraints: dict = {**sklearn_LinearRegression._parameter_constraints}
|
|
49
|
+
|
|
50
|
+
def __init__(
|
|
51
|
+
self,
|
|
52
|
+
fit_intercept=True,
|
|
53
|
+
copy_X=True,
|
|
54
|
+
n_jobs=None,
|
|
55
|
+
positive=False,
|
|
56
|
+
):
|
|
57
|
+
super().__init__(
|
|
58
|
+
fit_intercept=fit_intercept,
|
|
59
|
+
copy_X=copy_X,
|
|
60
|
+
n_jobs=n_jobs,
|
|
61
|
+
positive=positive,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
else:
|
|
65
|
+
|
|
66
|
+
def __init__(
|
|
67
|
+
self,
|
|
68
|
+
fit_intercept=True,
|
|
69
|
+
normalize="deprecated" if sklearn_check_version("1.0") else False,
|
|
70
|
+
copy_X=True,
|
|
71
|
+
n_jobs=None,
|
|
72
|
+
positive=False,
|
|
73
|
+
):
|
|
74
|
+
super().__init__(
|
|
75
|
+
fit_intercept=fit_intercept,
|
|
76
|
+
normalize=normalize,
|
|
77
|
+
copy_X=copy_X,
|
|
78
|
+
n_jobs=n_jobs,
|
|
79
|
+
positive=positive,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
def fit(self, X, y, sample_weight=None):
|
|
83
|
+
if sklearn_check_version("1.0"):
|
|
84
|
+
self._check_feature_names(X, reset=True)
|
|
85
|
+
if sklearn_check_version("1.2"):
|
|
86
|
+
self._validate_params()
|
|
87
|
+
|
|
88
|
+
# It is necessary to properly update coefs for predict if we
|
|
89
|
+
# fallback to sklearn in dispatch
|
|
90
|
+
if hasattr(self, "_onedal_estimator"):
|
|
91
|
+
del self._onedal_estimator
|
|
92
|
+
|
|
93
|
+
dispatch(
|
|
94
|
+
self,
|
|
95
|
+
"fit",
|
|
96
|
+
{
|
|
97
|
+
"onedal": self.__class__._onedal_fit,
|
|
98
|
+
"sklearn": sklearn_LinearRegression.fit,
|
|
99
|
+
},
|
|
100
|
+
X,
|
|
101
|
+
y,
|
|
102
|
+
sample_weight,
|
|
103
|
+
)
|
|
104
|
+
return self
|
|
105
|
+
|
|
106
|
+
@wrap_output_data
|
|
107
|
+
def predict(self, X):
|
|
108
|
+
|
|
109
|
+
if not hasattr(self, "coef_"):
|
|
110
|
+
msg = (
|
|
111
|
+
"This %(name)s instance is not fitted yet. Call 'fit' with "
|
|
112
|
+
"appropriate arguments before using this estimator."
|
|
113
|
+
)
|
|
114
|
+
raise NotFittedError(msg % {"name": self.__class__.__name__})
|
|
115
|
+
|
|
116
|
+
return dispatch(
|
|
117
|
+
self,
|
|
118
|
+
"predict",
|
|
119
|
+
{
|
|
120
|
+
"onedal": self.__class__._onedal_predict,
|
|
121
|
+
"sklearn": sklearn_LinearRegression.predict,
|
|
122
|
+
},
|
|
123
|
+
X,
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
def _test_type_and_finiteness(self, X_in):
|
|
127
|
+
X = X_in if isinstance(X_in, np.ndarray) else np.asarray(X_in)
|
|
128
|
+
|
|
129
|
+
dtype = X.dtype
|
|
130
|
+
if "complex" in str(type(dtype)):
|
|
131
|
+
return False
|
|
132
|
+
|
|
133
|
+
try:
|
|
134
|
+
_assert_all_finite(X)
|
|
135
|
+
except BaseException:
|
|
136
|
+
return False
|
|
137
|
+
return True
|
|
138
|
+
|
|
139
|
+
def _onedal_fit_supported(self, method_name, *data):
|
|
140
|
+
assert method_name == "fit"
|
|
141
|
+
assert len(data) == 3
|
|
142
|
+
X, y, sample_weight = data
|
|
143
|
+
|
|
144
|
+
class_name = self.__class__.__name__
|
|
145
|
+
patching_status = PatchingConditionsChain(
|
|
146
|
+
f"sklearn.linear_model.{class_name}.fit"
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
normalize_is_set = (
|
|
150
|
+
hasattr(self, "normalize")
|
|
151
|
+
and self.normalize
|
|
152
|
+
and self.normalize != "deprecated"
|
|
153
|
+
)
|
|
154
|
+
positive_is_set = hasattr(self, "positive") and self.positive
|
|
155
|
+
|
|
156
|
+
n_samples = _num_samples(X)
|
|
157
|
+
n_features = _num_features(X, fallback_1d=True)
|
|
158
|
+
|
|
159
|
+
# Check if equations are well defined
|
|
160
|
+
is_good_for_onedal = n_samples >= (n_features + int(self.fit_intercept))
|
|
161
|
+
|
|
162
|
+
dal_ready = patching_status.and_conditions(
|
|
163
|
+
[
|
|
164
|
+
(sample_weight is None, "Sample weight is not supported."),
|
|
165
|
+
(
|
|
166
|
+
not issparse(X) and not issparse(y),
|
|
167
|
+
"Sparse input is not supported.",
|
|
168
|
+
),
|
|
169
|
+
(not normalize_is_set, "Normalization is not supported."),
|
|
170
|
+
(
|
|
171
|
+
not positive_is_set,
|
|
172
|
+
"Forced positive coefficients are not supported.",
|
|
173
|
+
),
|
|
174
|
+
(
|
|
175
|
+
is_good_for_onedal,
|
|
176
|
+
"The shape of X (fitting) does not satisfy oneDAL requirements:"
|
|
177
|
+
"Number of features + 1 >= number of samples.",
|
|
178
|
+
),
|
|
179
|
+
]
|
|
180
|
+
)
|
|
181
|
+
if not dal_ready:
|
|
182
|
+
return patching_status
|
|
183
|
+
|
|
184
|
+
if not patching_status.and_condition(
|
|
185
|
+
self._test_type_and_finiteness(X), "Input X is not supported."
|
|
186
|
+
):
|
|
187
|
+
return patching_status
|
|
188
|
+
|
|
189
|
+
patching_status.and_condition(
|
|
190
|
+
self._test_type_and_finiteness(y), "Input y is not supported."
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
return patching_status
|
|
194
|
+
|
|
195
|
+
def _onedal_predict_supported(self, method_name, *data):
|
|
196
|
+
assert method_name == "predict"
|
|
197
|
+
assert len(data) == 1
|
|
198
|
+
|
|
199
|
+
class_name = self.__class__.__name__
|
|
200
|
+
patching_status = PatchingConditionsChain(
|
|
201
|
+
f"sklearn.linear_model.{class_name}.predict"
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
n_samples = _num_samples(*data)
|
|
205
|
+
model_is_sparse = issparse(self.coef_) or (
|
|
206
|
+
self.fit_intercept and issparse(self.intercept_)
|
|
207
|
+
)
|
|
208
|
+
dal_ready = patching_status.and_conditions(
|
|
209
|
+
[
|
|
210
|
+
(n_samples > 0, "Number of samples is less than 1."),
|
|
211
|
+
(not issparse(*data), "Sparse input is not supported."),
|
|
212
|
+
(not model_is_sparse, "Sparse coefficients are not supported."),
|
|
213
|
+
]
|
|
214
|
+
)
|
|
215
|
+
if not dal_ready:
|
|
216
|
+
return patching_status
|
|
217
|
+
|
|
218
|
+
patching_status.and_condition(
|
|
219
|
+
self._test_type_and_finiteness(*data), "Input X is not supported."
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
return patching_status
|
|
223
|
+
|
|
224
|
+
def _onedal_supported(self, method_name, *data):
|
|
225
|
+
if method_name == "fit":
|
|
226
|
+
return self._onedal_fit_supported(method_name, *data)
|
|
227
|
+
if method_name == "predict":
|
|
228
|
+
return self._onedal_predict_supported(method_name, *data)
|
|
229
|
+
raise RuntimeError(f"Unknown method {method_name} in {self.__class__.__name__}")
|
|
230
|
+
|
|
231
|
+
_onedal_gpu_supported = _onedal_supported
|
|
232
|
+
_onedal_cpu_supported = _onedal_supported
|
|
233
|
+
|
|
234
|
+
def _initialize_onedal_estimator(self):
|
|
235
|
+
onedal_params = {"fit_intercept": self.fit_intercept, "copy_X": self.copy_X}
|
|
236
|
+
self._onedal_estimator = onedal_LinearRegression(**onedal_params)
|
|
237
|
+
|
|
238
|
+
def _onedal_fit(self, X, y, sample_weight, queue=None):
|
|
239
|
+
assert sample_weight is None
|
|
240
|
+
|
|
241
|
+
check_params = {
|
|
242
|
+
"X": X,
|
|
243
|
+
"y": y,
|
|
244
|
+
"dtype": [np.float64, np.float32],
|
|
245
|
+
"accept_sparse": ["csr", "csc", "coo"],
|
|
246
|
+
"y_numeric": True,
|
|
247
|
+
"multi_output": True,
|
|
248
|
+
"force_all_finite": False,
|
|
249
|
+
}
|
|
250
|
+
if sklearn_check_version("1.2"):
|
|
251
|
+
X, y = self._validate_data(**check_params)
|
|
252
|
+
else:
|
|
253
|
+
X, y = check_X_y(**check_params)
|
|
254
|
+
|
|
255
|
+
if sklearn_check_version("1.0") and not sklearn_check_version("1.2"):
|
|
256
|
+
self._normalize = _deprecate_normalize(
|
|
257
|
+
self.normalize,
|
|
258
|
+
default=False,
|
|
259
|
+
estimator_name=self.__class__.__name__,
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
self._initialize_onedal_estimator()
|
|
263
|
+
try:
|
|
264
|
+
self._onedal_estimator.fit(X, y, queue=queue)
|
|
265
|
+
self._save_attributes()
|
|
266
|
+
|
|
267
|
+
except RuntimeError:
|
|
268
|
+
logging.getLogger("sklearnex").info(
|
|
269
|
+
f"{self.__class__.__name__}.fit "
|
|
270
|
+
+ get_patch_message("sklearn_after_onedal")
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
del self._onedal_estimator
|
|
274
|
+
super().fit(X, y)
|
|
275
|
+
|
|
276
|
+
def _onedal_predict(self, X, queue=None):
|
|
277
|
+
if sklearn_check_version("1.0"):
|
|
278
|
+
self._check_feature_names(X, reset=False)
|
|
279
|
+
|
|
280
|
+
X = self._validate_data(X, accept_sparse=False, reset=False)
|
|
281
|
+
if not hasattr(self, "_onedal_estimator"):
|
|
282
|
+
self._initialize_onedal_estimator()
|
|
283
|
+
self._onedal_estimator.coef_ = self.coef_
|
|
284
|
+
self._onedal_estimator.intercept_ = self.intercept_
|
|
285
|
+
|
|
286
|
+
res = self._onedal_estimator.predict(X, queue=queue)
|
|
287
|
+
return res
|
|
288
|
+
|
|
289
|
+
def get_coef_(self):
|
|
290
|
+
return self.coef_
|
|
291
|
+
|
|
292
|
+
def set_coef_(self, value):
|
|
293
|
+
self.__dict__["coef_"] = value
|
|
294
|
+
if hasattr(self, "_onedal_estimator"):
|
|
295
|
+
self._onedal_estimator.coef_ = value
|
|
296
|
+
del self._onedal_estimator._onedal_model
|
|
297
|
+
|
|
298
|
+
def get_intercept_(self):
|
|
299
|
+
return self.intercept_
|
|
300
|
+
|
|
301
|
+
def set_intercept_(self, value):
|
|
302
|
+
self.__dict__["intercept_"] = value
|
|
303
|
+
if hasattr(self, "_onedal_estimator"):
|
|
304
|
+
self._onedal_estimator.intercept_ = value
|
|
305
|
+
del self._onedal_estimator._onedal_model
|
|
306
|
+
|
|
307
|
+
def _save_attributes(self):
|
|
308
|
+
self.coef_ = property(self.get_coef_, self.set_coef_)
|
|
309
|
+
self.intercept_ = property(self.get_intercept_, self.set_intercept_)
|
|
310
|
+
self.n_features_in_ = self._onedal_estimator.n_features_in_
|
|
311
|
+
self._sparse = False
|
|
312
|
+
self.__dict__["coef_"] = self._onedal_estimator.coef_
|
|
313
|
+
self.__dict__["intercept_"] = self._onedal_estimator.intercept_
|
|
314
|
+
|
|
315
|
+
fit.__doc__ = sklearn_LinearRegression.fit.__doc__
|
|
316
|
+
predict.__doc__ = sklearn_LinearRegression.predict.__doc__
|
|
@@ -38,19 +38,27 @@ if daal_check_version((2024, "P", 1)):
|
|
|
38
38
|
import numpy as np
|
|
39
39
|
from scipy.sparse import issparse
|
|
40
40
|
from sklearn.linear_model import LogisticRegression as sklearn_LogisticRegression
|
|
41
|
+
from sklearn.metrics import accuracy_score
|
|
42
|
+
from sklearn.utils.multiclass import type_of_target
|
|
41
43
|
from sklearn.utils.validation import check_X_y
|
|
42
44
|
|
|
43
45
|
from daal4py.sklearn._n_jobs_support import control_n_jobs
|
|
44
46
|
from daal4py.sklearn._utils import sklearn_check_version
|
|
45
47
|
from onedal.linear_model import LogisticRegression as onedal_LogisticRegression
|
|
46
|
-
from onedal.utils import
|
|
48
|
+
from onedal.utils import _num_samples
|
|
47
49
|
|
|
48
50
|
from .._device_offload import dispatch, wrap_output_data
|
|
49
51
|
from .._utils import PatchingConditionsChain, get_patch_message
|
|
50
52
|
from ..utils.validation import _assert_all_finite
|
|
51
53
|
|
|
52
54
|
@control_n_jobs(
|
|
53
|
-
decorated_methods=[
|
|
55
|
+
decorated_methods=[
|
|
56
|
+
"fit",
|
|
57
|
+
"predict",
|
|
58
|
+
"predict_proba",
|
|
59
|
+
"predict_log_proba",
|
|
60
|
+
"score",
|
|
61
|
+
]
|
|
54
62
|
)
|
|
55
63
|
class LogisticRegression(sklearn_LogisticRegression, BaseLogisticRegression):
|
|
56
64
|
__doc__ = sklearn_LogisticRegression.__doc__
|
|
@@ -72,9 +80,9 @@ if daal_check_version((2024, "P", 1)):
|
|
|
72
80
|
intercept_scaling=1,
|
|
73
81
|
class_weight=None,
|
|
74
82
|
random_state=None,
|
|
75
|
-
solver="lbfgs"
|
|
83
|
+
solver="lbfgs",
|
|
76
84
|
max_iter=100,
|
|
77
|
-
multi_class="auto"
|
|
85
|
+
multi_class="auto",
|
|
78
86
|
verbose=0,
|
|
79
87
|
warm_start=False,
|
|
80
88
|
n_jobs=None,
|
|
@@ -160,6 +168,27 @@ if daal_check_version((2024, "P", 1)):
|
|
|
160
168
|
X,
|
|
161
169
|
)
|
|
162
170
|
|
|
171
|
+
@wrap_output_data
|
|
172
|
+
def score(self, X, y, sample_weight=None):
|
|
173
|
+
if sklearn_check_version("1.0"):
|
|
174
|
+
self._check_feature_names(X, reset=False)
|
|
175
|
+
return dispatch(
|
|
176
|
+
self,
|
|
177
|
+
"score",
|
|
178
|
+
{
|
|
179
|
+
"onedal": self.__class__._onedal_score,
|
|
180
|
+
"sklearn": sklearn_LogisticRegression.score,
|
|
181
|
+
},
|
|
182
|
+
X,
|
|
183
|
+
y,
|
|
184
|
+
sample_weight=sample_weight,
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
def _onedal_score(self, X, y, sample_weight=None, queue=None):
|
|
188
|
+
return accuracy_score(
|
|
189
|
+
y, self._onedal_predict(X, queue=queue), sample_weight=sample_weight
|
|
190
|
+
)
|
|
191
|
+
|
|
163
192
|
def _test_type_and_finiteness(self, X_in):
|
|
164
193
|
X = np.asarray(X_in)
|
|
165
194
|
|
|
@@ -198,6 +227,10 @@ if daal_check_version((2024, "P", 1)):
|
|
|
198
227
|
(self.warm_start == False, "Warm start is not supported."),
|
|
199
228
|
(self.l1_ratio is None, "l1 ratio is not supported."),
|
|
200
229
|
(sample_weight is None, "Sample weight is not supported."),
|
|
230
|
+
(
|
|
231
|
+
type_of_target(y) == "binary",
|
|
232
|
+
"Only binary classification is supported",
|
|
233
|
+
),
|
|
201
234
|
]
|
|
202
235
|
)
|
|
203
236
|
|
|
@@ -216,22 +249,29 @@ if daal_check_version((2024, "P", 1)):
|
|
|
216
249
|
return patching_status
|
|
217
250
|
|
|
218
251
|
def _onedal_gpu_predict_supported(self, method_name, *data):
|
|
219
|
-
assert method_name in [
|
|
220
|
-
|
|
252
|
+
assert method_name in [
|
|
253
|
+
"predict",
|
|
254
|
+
"predict_proba",
|
|
255
|
+
"predict_log_proba",
|
|
256
|
+
"score",
|
|
257
|
+
]
|
|
221
258
|
|
|
222
259
|
class_name = self.__class__.__name__
|
|
223
260
|
patching_status = PatchingConditionsChain(
|
|
224
261
|
f"sklearn.linear_model.{class_name}.{method_name}"
|
|
225
262
|
)
|
|
226
263
|
|
|
227
|
-
n_samples = _num_samples(
|
|
264
|
+
n_samples = _num_samples(data[0])
|
|
228
265
|
model_is_sparse = issparse(self.coef_) or (
|
|
229
266
|
self.fit_intercept and issparse(self.intercept_)
|
|
230
267
|
)
|
|
231
268
|
dal_ready = patching_status.and_conditions(
|
|
232
269
|
[
|
|
233
270
|
(n_samples > 0, "Number of samples is less than 1."),
|
|
234
|
-
(
|
|
271
|
+
(
|
|
272
|
+
not any([issparse(i) for i in data]),
|
|
273
|
+
"Sparse input is not supported.",
|
|
274
|
+
),
|
|
235
275
|
(not model_is_sparse, "Sparse coefficients are not supported."),
|
|
236
276
|
(
|
|
237
277
|
hasattr(self, "_onedal_estimator"),
|
|
@@ -251,7 +291,7 @@ if daal_check_version((2024, "P", 1)):
|
|
|
251
291
|
def _onedal_gpu_supported(self, method_name, *data):
|
|
252
292
|
if method_name == "fit":
|
|
253
293
|
return self._onedal_gpu_fit_supported(method_name, *data)
|
|
254
|
-
if method_name in ["predict", "predict_proba", "predict_log_proba"]:
|
|
294
|
+
if method_name in ["predict", "predict_proba", "predict_log_proba", "score"]:
|
|
255
295
|
return self._onedal_gpu_predict_supported(method_name, *data)
|
|
256
296
|
raise RuntimeError(
|
|
257
297
|
f"Unknown method {method_name} in {self.__class__.__name__}"
|
|
@@ -334,6 +374,7 @@ if daal_check_version((2024, "P", 1)):
|
|
|
334
374
|
predict.__doc__ = sklearn_LogisticRegression.predict.__doc__
|
|
335
375
|
predict_proba.__doc__ = sklearn_LogisticRegression.predict_proba.__doc__
|
|
336
376
|
predict_log_proba.__doc__ = sklearn_LogisticRegression.predict_log_proba.__doc__
|
|
377
|
+
score.__doc__ = sklearn_LogisticRegression.score.__doc__
|
|
337
378
|
|
|
338
379
|
else:
|
|
339
380
|
LogisticRegression = LogisticRegression_daal4py
|
|
@@ -28,26 +28,33 @@ from onedal.tests.utils._dataframes_support import (
|
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
@pytest.mark.parametrize("dataframe,queue", get_dataframes_and_queues())
|
|
31
|
+
@pytest.mark.parametrize("dtype", [np.float32, np.float64])
|
|
31
32
|
@pytest.mark.parametrize("macro_block", [None, 1024])
|
|
32
|
-
def test_sklearnex_import_linear(dataframe, queue, macro_block):
|
|
33
|
+
def test_sklearnex_import_linear(dataframe, queue, dtype, macro_block):
|
|
33
34
|
from sklearnex.linear_model import LinearRegression
|
|
34
35
|
|
|
35
36
|
X = np.array([[1, 1], [1, 2], [2, 2], [2, 3]])
|
|
36
37
|
y = np.dot(X, np.array([1, 2])) + 3
|
|
38
|
+
X = X.astype(dtype=dtype)
|
|
39
|
+
y = y.astype(dtype=dtype)
|
|
37
40
|
X = _convert_to_dataframe(X, sycl_queue=queue, target_df=dataframe)
|
|
38
41
|
y = _convert_to_dataframe(y, sycl_queue=queue, target_df=dataframe)
|
|
42
|
+
|
|
39
43
|
linreg = LinearRegression()
|
|
40
44
|
if daal_check_version((2024, "P", 0)) and macro_block is not None:
|
|
41
45
|
hparams = linreg.get_hyperparameters("fit")
|
|
42
46
|
hparams.cpu_macro_block = macro_block
|
|
43
47
|
hparams.gpu_macro_block = macro_block
|
|
48
|
+
|
|
44
49
|
linreg.fit(X, y)
|
|
45
|
-
|
|
46
|
-
|
|
50
|
+
|
|
51
|
+
assert hasattr(linreg, "_onedal_estimator")
|
|
47
52
|
assert "sklearnex" in linreg.__module__
|
|
48
53
|
assert linreg.n_features_in_ == 2
|
|
49
|
-
|
|
50
|
-
|
|
54
|
+
|
|
55
|
+
tol = 1e-5 if X.dtype == np.float32 else 1e-7
|
|
56
|
+
assert_allclose(_as_numpy(linreg.intercept_), 3.0, rtol=tol)
|
|
57
|
+
assert_allclose(_as_numpy(linreg.coef_), [1.0, 2.0], rtol=tol)
|
|
51
58
|
|
|
52
59
|
|
|
53
60
|
def test_sklearnex_import_ridge():
|
|
@@ -80,3 +87,31 @@ def test_sklearnex_import_elastic():
|
|
|
80
87
|
assert "daal4py" in elasticnet.__module__
|
|
81
88
|
assert_allclose(elasticnet.intercept_, 1.451, atol=1e-3)
|
|
82
89
|
assert_allclose(elasticnet.coef_, [18.838, 64.559], atol=1e-3)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@pytest.mark.parametrize("dataframe,queue", get_dataframes_and_queues())
|
|
93
|
+
@pytest.mark.parametrize("dtype", [np.float32, np.float64])
|
|
94
|
+
def test_sklearnex_reconstruct_model(dataframe, queue, dtype):
|
|
95
|
+
from sklearnex.linear_model import LinearRegression
|
|
96
|
+
|
|
97
|
+
seed = 42
|
|
98
|
+
num_samples = 3500
|
|
99
|
+
num_features, num_targets = 14, 9
|
|
100
|
+
|
|
101
|
+
gen = np.random.default_rng(seed)
|
|
102
|
+
intercept = gen.random(size=num_targets, dtype=dtype)
|
|
103
|
+
coef = gen.random(size=(num_targets, num_features), dtype=dtype).T
|
|
104
|
+
|
|
105
|
+
X = gen.random(size=(num_samples, num_features), dtype=dtype)
|
|
106
|
+
gtr = X @ coef + intercept[np.newaxis, :]
|
|
107
|
+
|
|
108
|
+
X = _convert_to_dataframe(X, sycl_queue=queue, target_df=dataframe)
|
|
109
|
+
|
|
110
|
+
linreg = LinearRegression(fit_intercept=True)
|
|
111
|
+
linreg.coef_ = coef.T
|
|
112
|
+
linreg.intercept_ = intercept
|
|
113
|
+
|
|
114
|
+
y_pred = linreg.predict(X)
|
|
115
|
+
|
|
116
|
+
tol = 1e-5 if X.dtype == np.float32 else 1e-7
|
|
117
|
+
assert_allclose(gtr, _as_numpy(y_pred), rtol=tol)
|
|
@@ -23,13 +23,13 @@ from sklearn.utils.validation import check_is_fitted
|
|
|
23
23
|
|
|
24
24
|
from daal4py.sklearn._n_jobs_support import control_n_jobs
|
|
25
25
|
from daal4py.sklearn._utils import sklearn_check_version
|
|
26
|
+
from sklearnex._device_offload import dispatch, wrap_output_data
|
|
27
|
+
from sklearnex.neighbors.common import KNeighborsDispatchingBase
|
|
28
|
+
from sklearnex.neighbors.knn_unsupervised import NearestNeighbors
|
|
29
|
+
from sklearnex.utils import get_namespace
|
|
26
30
|
|
|
27
|
-
from .._device_offload import dispatch, wrap_output_data
|
|
28
|
-
from .common import KNeighborsDispatchingBase
|
|
29
|
-
from .knn_unsupervised import NearestNeighbors
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
@control_n_jobs(decorated_methods=["fit", "kneighbors"])
|
|
32
|
+
@control_n_jobs(decorated_methods=["fit", "_kneighbors"])
|
|
33
33
|
class LocalOutlierFactor(KNeighborsDispatchingBase, sklearn_LocalOutlierFactor):
|
|
34
34
|
__doc__ = (
|
|
35
35
|
sklearn_LocalOutlierFactor.__doc__
|
|
@@ -100,7 +100,6 @@ class LocalOutlierFactor(KNeighborsDispatchingBase, sklearn_LocalOutlierFactor):
|
|
|
100
100
|
return self
|
|
101
101
|
|
|
102
102
|
def fit(self, X, y=None):
|
|
103
|
-
self._fit_validation(X, y)
|
|
104
103
|
result = dispatch(
|
|
105
104
|
self,
|
|
106
105
|
"fit",
|
|
@@ -113,16 +112,13 @@ class LocalOutlierFactor(KNeighborsDispatchingBase, sklearn_LocalOutlierFactor):
|
|
|
113
112
|
)
|
|
114
113
|
return result
|
|
115
114
|
|
|
116
|
-
# Subtle order change to remove check_array and preserve dpnp and
|
|
117
|
-
# dpctl conformance. decision_function will return a dpnp or dpctl
|
|
118
|
-
# instance via kneighbors and an equivalent check_array exists in
|
|
119
|
-
# that call already in sklearn so no loss of functionality occurs
|
|
120
115
|
def _predict(self, X=None):
|
|
121
116
|
check_is_fitted(self)
|
|
122
117
|
|
|
123
118
|
if X is not None:
|
|
119
|
+
xp, _ = get_namespace(X)
|
|
124
120
|
output = self.decision_function(X) < 0
|
|
125
|
-
is_inlier =
|
|
121
|
+
is_inlier = xp.ones_like(output, dtype=int)
|
|
126
122
|
is_inlier[output] = -1
|
|
127
123
|
else:
|
|
128
124
|
is_inlier = np.ones(self.n_samples_fit_, dtype=int)
|
|
@@ -159,16 +155,40 @@ class LocalOutlierFactor(KNeighborsDispatchingBase, sklearn_LocalOutlierFactor):
|
|
|
159
155
|
"""
|
|
160
156
|
return self.fit(X)._predict()
|
|
161
157
|
|
|
162
|
-
|
|
158
|
+
def _kneighbors(self, X=None, n_neighbors=None, return_distance=True):
|
|
159
|
+
check_is_fitted(self)
|
|
160
|
+
if sklearn_check_version("1.0") and X is not None:
|
|
161
|
+
self._check_feature_names(X, reset=False)
|
|
162
|
+
return dispatch(
|
|
163
|
+
self,
|
|
164
|
+
"kneighbors",
|
|
165
|
+
{
|
|
166
|
+
"onedal": self.__class__._onedal_kneighbors,
|
|
167
|
+
"sklearn": sklearn_LocalOutlierFactor.kneighbors,
|
|
168
|
+
},
|
|
169
|
+
X,
|
|
170
|
+
n_neighbors=n_neighbors,
|
|
171
|
+
return_distance=return_distance,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
kneighbors = wrap_output_data(_kneighbors)
|
|
175
|
+
|
|
176
|
+
@available_if(sklearn_LocalOutlierFactor._check_novelty_score_samples)
|
|
163
177
|
@wrap_output_data
|
|
164
|
-
def
|
|
165
|
-
"""
|
|
178
|
+
def score_samples(self, X):
|
|
179
|
+
"""Opposite of the Local Outlier Factor of X.
|
|
180
|
+
|
|
181
|
+
It is the opposite as bigger is better, i.e. large values correspond
|
|
182
|
+
to inliers.
|
|
166
183
|
|
|
167
184
|
**Only available for novelty detection (when novelty is set to True).**
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
obtained
|
|
185
|
+
The argument X is supposed to contain *new data*: if X contains a
|
|
186
|
+
point from training, it considers the later in its own neighborhood.
|
|
187
|
+
Also, the samples in X are not considered in the neighborhood of any
|
|
188
|
+
point. Because of this, the scores obtained via ``score_samples`` may
|
|
189
|
+
differ from the standard LOF scores.
|
|
190
|
+
The standard LOF scores for the training data is available via the
|
|
191
|
+
``negative_outlier_factor_`` attribute.
|
|
172
192
|
|
|
173
193
|
Parameters
|
|
174
194
|
----------
|
|
@@ -178,27 +198,24 @@ class LocalOutlierFactor(KNeighborsDispatchingBase, sklearn_LocalOutlierFactor):
|
|
|
178
198
|
|
|
179
199
|
Returns
|
|
180
200
|
-------
|
|
181
|
-
|
|
182
|
-
|
|
201
|
+
opposite_lof_scores : ndarray of shape (n_samples,)
|
|
202
|
+
The opposite of the Local Outlier Factor of each input samples.
|
|
203
|
+
The lower, the more abnormal.
|
|
183
204
|
"""
|
|
184
|
-
return self._predict(X)
|
|
185
|
-
|
|
186
|
-
@wrap_output_data
|
|
187
|
-
def kneighbors(self, X=None, n_neighbors=None, return_distance=True):
|
|
188
205
|
check_is_fitted(self)
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
self,
|
|
193
|
-
"kneighbors",
|
|
194
|
-
{
|
|
195
|
-
"onedal": self.__class__._onedal_kneighbors,
|
|
196
|
-
"sklearn": sklearn_LocalOutlierFactor.kneighbors,
|
|
197
|
-
},
|
|
198
|
-
X,
|
|
199
|
-
n_neighbors=n_neighbors,
|
|
200
|
-
return_distance=return_distance,
|
|
206
|
+
|
|
207
|
+
distances_X, neighbors_indices_X = self._kneighbors(
|
|
208
|
+
X, n_neighbors=self.n_neighbors_
|
|
201
209
|
)
|
|
202
210
|
|
|
211
|
+
X_lrd = self._local_reachability_density(
|
|
212
|
+
distances_X,
|
|
213
|
+
neighbors_indices_X,
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
lrd_ratios_array = self._lrd[neighbors_indices_X] / X_lrd[:, np.newaxis]
|
|
217
|
+
|
|
218
|
+
return -np.mean(lrd_ratios_array, axis=1)
|
|
219
|
+
|
|
203
220
|
fit.__doc__ = sklearn_LocalOutlierFactor.fit.__doc__
|
|
204
221
|
kneighbors.__doc__ = sklearn_LocalOutlierFactor.kneighbors.__doc__
|
|
@@ -137,6 +137,9 @@ class KNeighborsDispatchingBase:
|
|
|
137
137
|
self.n_features_in_ = X.data.shape[1]
|
|
138
138
|
|
|
139
139
|
def _onedal_supported(self, device, method_name, *data):
|
|
140
|
+
if method_name == "fit":
|
|
141
|
+
self._fit_validation(data[0], data[1])
|
|
142
|
+
|
|
140
143
|
class_name = self.__class__.__name__
|
|
141
144
|
is_classifier = "Classifier" in class_name
|
|
142
145
|
is_regressor = "Regressor" in class_name
|
|
@@ -249,7 +252,7 @@ class KNeighborsDispatchingBase:
|
|
|
249
252
|
class_count >= 2, "One-class case is not supported."
|
|
250
253
|
)
|
|
251
254
|
return patching_status
|
|
252
|
-
if method_name in ["predict", "predict_proba", "kneighbors"]:
|
|
255
|
+
if method_name in ["predict", "predict_proba", "kneighbors", "score"]:
|
|
253
256
|
patching_status.and_condition(
|
|
254
257
|
hasattr(self, "_onedal_estimator"), "oneDAL model was not trained."
|
|
255
258
|
)
|