scikit-learn-intelex 2025.4.0__py313-none-win_amd64.whl → 2025.6.0__py313-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.
Potentially problematic release.
This version of scikit-learn-intelex might be problematic. Click here for more details.
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/__main__.py +1 -1
- scikit_learn_intelex-2025.6.0.data/data/Lib/site-packages/daal4py/_daal4py.cp313-win_amd64.pyd +0 -0
- scikit_learn_intelex-2025.6.0.data/data/Lib/site-packages/daal4py/mb/__init__.py +83 -0
- scikit_learn_intelex-2025.6.0.data/data/Lib/site-packages/daal4py/mb/gbt_convertors.py +922 -0
- scikit_learn_intelex-2025.6.0.data/data/Lib/site-packages/daal4py/mb/logistic_regression_builders.py +217 -0
- scikit_learn_intelex-2025.4.0.data/data/Lib/site-packages/daal4py/mb/model_builders.py → scikit_learn_intelex-2025.6.0.data/data/Lib/site-packages/daal4py/mb/tree_based_builders.py +129 -106
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/mpi_transceiver.cp313-win_amd64.pyd +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/_n_jobs_support.py +6 -2
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/_utils.py +1 -1
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/cluster/dbscan.py +2 -2
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/cluster/k_means.py +6 -38
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/decomposition/_pca.py +12 -8
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/ensemble/AdaBoostClassifier.py +2 -6
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/ensemble/GBTDAAL.py +3 -7
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/ensemble/_forest.py +41 -153
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/linear_model/_coordinate_descent.py +13 -15
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/linear_model/_linear.py +7 -10
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/linear_model/_ridge.py +22 -57
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/linear_model/logistic_path.py +3 -4
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/manifold/_t_sne.py +8 -3
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/metrics/_pairwise.py +30 -7
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/monkeypatch/dispatcher.py +3 -3
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/neighbors/_base.py +6 -16
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/neighbors/_classification.py +4 -7
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/neighbors/_regression.py +3 -5
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/svm/svm.py +4 -2
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/utils/base.py +8 -3
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/utils/validation.py +82 -5
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/__init__.py +125 -83
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/_config.py +27 -2
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/_device_offload.py +86 -82
- scikit_learn_intelex-2025.6.0.data/data/Lib/site-packages/onedal/_onedal_py_dpc.cp313-win_amd64.pyd +0 -0
- scikit_learn_intelex-2025.6.0.data/data/Lib/site-packages/onedal/_onedal_py_host.cp313-win_amd64.pyd +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/basic_statistics/basic_statistics.py +21 -17
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/basic_statistics/incremental_basic_statistics.py +44 -39
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/cluster/dbscan.py +35 -42
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/cluster/kmeans.py +83 -74
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/cluster/kmeans_init.py +57 -24
- scikit_learn_intelex-2025.6.0.data/data/Lib/site-packages/onedal/common/_backend.py +233 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/common/hyperparameters.py +4 -4
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/common/tests/test_sycl.py +27 -12
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/covariance/covariance.py +27 -19
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/covariance/incremental_covariance.py +35 -32
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/datatypes/_data_conversion.py +6 -10
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/datatypes/tests/test_data.py +179 -78
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/decomposition/incremental_pca.py +39 -25
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/decomposition/pca.py +28 -16
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/decomposition/tests/test_incremental_pca.py +2 -2
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/ensemble/forest.py +130 -93
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/linear_model/incremental_linear_model.py +76 -57
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/linear_model/linear_model.py +63 -37
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/linear_model/logistic_regression.py +96 -68
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/neighbors/neighbors.py +156 -119
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/primitives/get_tree.py +5 -3
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/primitives/kernel_functions.py +21 -18
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/primitives/tests/test_kernel_functions.py +4 -4
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/svm/svm.py +80 -32
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/svm/tests/test_csr_svm.py +10 -9
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/svm/tests/test_nusvc.py +10 -10
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/svm/tests/test_nusvr.py +8 -8
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/svm/tests/test_svc.py +5 -5
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/svm/tests/test_svr.py +10 -10
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/tests/utils/_device_selection.py +3 -13
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/utils/_array_api.py +14 -2
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/utils/_dpep_helpers.py +16 -1
- scikit_learn_intelex-2025.6.0.data/data/Lib/site-packages/onedal/utils/_sycl_queue_manager.py +161 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/utils/tests/test_validation.py +3 -3
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/utils/validation.py +47 -16
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/__init__.py +3 -2
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/__main__.py +2 -2
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/_config.py +48 -6
- scikit_learn_intelex-2025.6.0.data/data/Lib/site-packages/sklearnex/_device_offload.py +194 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/_utils.py +36 -43
- scikit_learn_intelex-2025.6.0.data/data/Lib/site-packages/sklearnex/base.py +109 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/basic_statistics/basic_statistics.py +14 -20
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/basic_statistics/incremental_basic_statistics.py +31 -40
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/cluster/dbscan.py +10 -11
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/cluster/k_means.py +20 -19
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/covariance/incremental_covariance.py +49 -62
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/decomposition/pca.py +9 -20
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/dispatcher.py +4 -4
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/doc/third-party-programs.txt +207 -2
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/ensemble/_forest.py +111 -366
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/glob/__main__.py +1 -1
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/glob/dispatcher.py +1 -1
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/linear_model/coordinate_descent.py +18 -6
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/linear_model/incremental_linear.py +41 -126
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/linear_model/incremental_ridge.py +37 -85
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/linear_model/linear.py +52 -47
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/linear_model/logistic_regression.py +45 -84
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/linear_model/ridge.py +17 -20
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/linear_model/tests/test_linear.py +60 -1
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/linear_model/tests/test_logreg.py +2 -2
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/manifold/t_sne.py +8 -6
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/metrics/pairwise.py +1 -3
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/metrics/ranking.py +1 -1
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/model_selection/split.py +1 -3
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/neighbors/_lof.py +7 -54
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/neighbors/common.py +6 -5
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/neighbors/knn_classification.py +31 -73
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/neighbors/knn_regression.py +30 -70
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/neighbors/knn_unsupervised.py +5 -13
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/preview/covariance/covariance.py +6 -19
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/preview/decomposition/incremental_pca.py +45 -62
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/basic_statistics/tests/test_basic_statistics_spmd.py +10 -3
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/basic_statistics/tests/test_incremental_basic_statistics_spmd.py +8 -4
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/cluster/tests/test_dbscan_spmd.py +13 -2
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/cluster/tests/test_kmeans_spmd.py +10 -3
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/covariance/tests/test_covariance_spmd.py +7 -4
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/covariance/tests/test_incremental_covariance_spmd.py +13 -2
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/decomposition/tests/test_incremental_pca_spmd.py +9 -2
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/decomposition/tests/test_pca_spmd.py +7 -2
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/ensemble/tests/test_forest_spmd.py +25 -8
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/linear_model/tests/test_incremental_linear_spmd.py +6 -2
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/linear_model/tests/test_linear_regression_spmd.py +12 -3
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/linear_model/tests/test_logistic_regression_spmd.py +12 -5
- {scikit_learn_intelex-2025.4.0.data/data/Lib/site-packages/daal4py/mb → scikit_learn_intelex-2025.6.0.data/data/Lib/site-packages/sklearnex/spmd/neighbors}/__init__.py +2 -2
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/neighbors/tests/test_neighbors_spmd.py +27 -5
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/svm/_common.py +15 -28
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/svm/nusvc.py +36 -129
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/svm/nusvr.py +10 -22
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/svm/svc.py +34 -127
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/svm/svr.py +10 -22
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/tests/test_common.py +51 -11
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/tests/test_config.py +62 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/tests/test_memory_usage.py +18 -24
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/tests/test_monkeypatch.py +4 -4
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/tests/test_patching.py +89 -60
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/tests/test_run_to_run_stability.py +7 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/tests/utils/base.py +2 -2
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/utils/validation.py +8 -22
- {scikit_learn_intelex-2025.4.0.dist-info → scikit_learn_intelex-2025.6.0.dist-info}/METADATA +2 -3
- scikit_learn_intelex-2025.6.0.dist-info/RECORD +257 -0
- scikit_learn_intelex-2025.4.0.data/data/Lib/site-packages/daal4py/_daal4py.cp313-win_amd64.pyd +0 -0
- scikit_learn_intelex-2025.4.0.data/data/Lib/site-packages/daal4py/doc/third-party-programs.txt +0 -424
- scikit_learn_intelex-2025.4.0.data/data/Lib/site-packages/onedal/_onedal_py_dpc.cp313-win_amd64.pyd +0 -0
- scikit_learn_intelex-2025.4.0.data/data/Lib/site-packages/onedal/_onedal_py_host.cp313-win_amd64.pyd +0 -0
- scikit_learn_intelex-2025.4.0.data/data/Lib/site-packages/onedal/common/_base.py +0 -38
- scikit_learn_intelex-2025.4.0.data/data/Lib/site-packages/onedal/common/_policy.py +0 -55
- scikit_learn_intelex-2025.4.0.data/data/Lib/site-packages/onedal/common/_spmd_policy.py +0 -30
- scikit_learn_intelex-2025.4.0.data/data/Lib/site-packages/onedal/common/tests/test_policy.py +0 -76
- scikit_learn_intelex-2025.4.0.data/data/Lib/site-packages/onedal/utils/__init__.py +0 -49
- scikit_learn_intelex-2025.4.0.data/data/Lib/site-packages/sklearnex/_device_offload.py +0 -126
- scikit_learn_intelex-2025.4.0.data/data/Lib/site-packages/sklearnex/spmd/neighbors/__init__.py +0 -19
- scikit_learn_intelex-2025.4.0.data/data/Lib/site-packages/sklearnex/spmd/neighbors/neighbors.py +0 -25
- scikit_learn_intelex-2025.4.0.dist-info/RECORD +0 -259
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/cluster/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/cluster/tests/test_dbscan.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/decomposition/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/ensemble/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/ensemble/tests/test_decision_forest.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/linear_model/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/linear_model/coordinate_descent.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/linear_model/linear.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/linear_model/logistic_loss.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/linear_model/ridge.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/linear_model/tests/test_linear.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/linear_model/tests/test_ridge.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/manifold/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/metrics/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/metrics/_ranking.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/model_selection/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/model_selection/_split.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/model_selection/tests/test_split.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/monkeypatch/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/monkeypatch/tests/_models_info.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/monkeypatch/tests/test_monkeypatch.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/monkeypatch/tests/test_patching.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/monkeypatch/tests/utils/_launch_algorithms.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/neighbors/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/neighbors/_unsupervised.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/neighbors/tests/test_kneighbors.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/svm/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/utils/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/daal4py/sklearn/utils/tests/test_utils.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/basic_statistics/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/basic_statistics/tests/test_basic_statistics.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/basic_statistics/tests/test_incremental_basic_statistics.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/basic_statistics/tests/utils.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/cluster/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/cluster/tests/test_dbscan.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/cluster/tests/test_kmeans.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/cluster/tests/test_kmeans_init.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/common/_estimator_checks.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/common/_mixin.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/covariance/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/covariance/tests/test_covariance.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/covariance/tests/test_incremental_covariance.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/datatypes/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/datatypes/tests/common.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/decomposition/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/ensemble/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/ensemble/tests/test_random_forest.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/linear_model/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/linear_model/tests/test_incremental_linear_regression.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/linear_model/tests/test_incremental_ridge_regression.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/linear_model/tests/test_linear_regression.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/linear_model/tests/test_logistic_regression.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/linear_model/tests/test_ridge.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/neighbors/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/neighbors/tests/test_knn_classification.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/primitives/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/svm/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/tests/test_common.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/onedal/tests/utils/_dataframes_support.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/basic_statistics/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/basic_statistics/tests/test_basic_statistics.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/basic_statistics/tests/test_incremental_basic_statistics.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/cluster/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/cluster/tests/test_dbscan.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/cluster/tests/test_kmeans.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/conftest.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/covariance/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/covariance/tests/test_incremental_covariance.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/decomposition/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/decomposition/tests/test_pca.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/ensemble/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/ensemble/tests/test_forest.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/linear_model/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/linear_model/tests/test_incremental_linear.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/linear_model/tests/test_incremental_ridge.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/linear_model/tests/test_ridge.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/manifold/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/manifold/tests/test_tsne.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/metrics/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/metrics/tests/test_metrics.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/model_selection/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/model_selection/tests/test_model_selection.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/neighbors/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/neighbors/tests/test_neighbors.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/preview/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/preview/covariance/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/preview/covariance/tests/test_covariance.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/preview/decomposition/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/preview/decomposition/tests/test_incremental_pca.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/basic_statistics/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/basic_statistics/basic_statistics.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/basic_statistics/incremental_basic_statistics.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/cluster/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/cluster/dbscan.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/cluster/kmeans.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/covariance/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/covariance/covariance.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/covariance/incremental_covariance.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/decomposition/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/decomposition/incremental_pca.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/decomposition/pca.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/ensemble/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/ensemble/forest.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/linear_model/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/linear_model/incremental_linear_model.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/linear_model/linear_model.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/spmd/linear_model/logistic_regression.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/svm/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/svm/tests/test_svm.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/tests/test_hyperparameters.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/tests/test_n_jobs_support.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/tests/test_parallel.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/tests/utils/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/tests/utils/spmd.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/utils/__init__.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/utils/_array_api.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/utils/parallel.py +0 -0
- {scikit_learn_intelex-2025.4.0.data → scikit_learn_intelex-2025.6.0.data}/data/Lib/site-packages/sklearnex/utils/tests/test_validation.py +0 -0
- {scikit_learn_intelex-2025.4.0.dist-info → scikit_learn_intelex-2025.6.0.dist-info}/LICENSE.txt +0 -0
- {scikit_learn_intelex-2025.4.0.dist-info → scikit_learn_intelex-2025.6.0.dist-info}/WHEEL +0 -0
- {scikit_learn_intelex-2025.4.0.dist-info → scikit_learn_intelex-2025.6.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,922 @@
|
|
|
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 json
|
|
18
|
+
from collections import deque
|
|
19
|
+
from copy import deepcopy
|
|
20
|
+
from tempfile import NamedTemporaryFile
|
|
21
|
+
from typing import Any, Deque, Dict, List, Optional, Tuple
|
|
22
|
+
|
|
23
|
+
import numpy as np
|
|
24
|
+
|
|
25
|
+
from .. import gbt_clf_model_builder, gbt_reg_model_builder
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class CatBoostNode:
|
|
29
|
+
def __init__(
|
|
30
|
+
self,
|
|
31
|
+
split: Optional[Dict] = None,
|
|
32
|
+
value: Optional[List[float]] = None,
|
|
33
|
+
right: Optional[int] = None,
|
|
34
|
+
left: Optional[float] = None,
|
|
35
|
+
cover: Optional[float] = None,
|
|
36
|
+
) -> None:
|
|
37
|
+
self.split = split
|
|
38
|
+
self.value = value
|
|
39
|
+
self.right = right
|
|
40
|
+
self.left = left
|
|
41
|
+
self.cover = cover
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class CatBoostModelData:
|
|
45
|
+
"""Wrapper around the CatBoost model dump for easier access to properties"""
|
|
46
|
+
|
|
47
|
+
def __init__(self, data):
|
|
48
|
+
self.__data = data
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def n_features(self):
|
|
52
|
+
return len(self.__data["features_info"]["float_features"])
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def grow_policy(self):
|
|
56
|
+
return self.__data["model_info"]["params"]["tree_learner_options"]["grow_policy"]
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def oblivious_trees(self):
|
|
60
|
+
return self.__data["oblivious_trees"]
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def trees(self):
|
|
64
|
+
return self.__data["trees"]
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def n_classes(self):
|
|
68
|
+
"""Number of classes, returns -1 if it's not a classification model"""
|
|
69
|
+
if "class_params" in self.__data["model_info"]:
|
|
70
|
+
return len(self.__data["model_info"]["class_params"]["class_to_label"])
|
|
71
|
+
return -1
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def is_classification(self):
|
|
75
|
+
return "class_params" in self.__data["model_info"]
|
|
76
|
+
|
|
77
|
+
@property
|
|
78
|
+
def has_categorical_features(self):
|
|
79
|
+
return "categorical_features" in self.__data["features_info"]
|
|
80
|
+
|
|
81
|
+
@property
|
|
82
|
+
def is_symmetric_tree(self):
|
|
83
|
+
return self.grow_policy == "SymmetricTree"
|
|
84
|
+
|
|
85
|
+
@property
|
|
86
|
+
def float_features(self):
|
|
87
|
+
return self.__data["features_info"]["float_features"]
|
|
88
|
+
|
|
89
|
+
@property
|
|
90
|
+
def n_iterations(self):
|
|
91
|
+
if self.is_symmetric_tree:
|
|
92
|
+
return len(self.oblivious_trees)
|
|
93
|
+
else:
|
|
94
|
+
return len(self.trees)
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def scale(self):
|
|
98
|
+
return self.__data["scale_and_bias"][0]
|
|
99
|
+
|
|
100
|
+
@property
|
|
101
|
+
def default_left(self):
|
|
102
|
+
dpo = self.__data["model_info"]["params"]["data_processing_options"]
|
|
103
|
+
nan_mode = dpo["float_features_binarization"]["nan_mode"]
|
|
104
|
+
return int(nan_mode.lower() == "min")
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class Node:
|
|
108
|
+
"""Helper class holding Tree Node information"""
|
|
109
|
+
|
|
110
|
+
def __init__(
|
|
111
|
+
self,
|
|
112
|
+
cover: float,
|
|
113
|
+
is_leaf: bool,
|
|
114
|
+
default_left: bool,
|
|
115
|
+
feature: int,
|
|
116
|
+
value: float,
|
|
117
|
+
n_children: int = 0,
|
|
118
|
+
left_child: "Optional[Node]" = None,
|
|
119
|
+
right_child: "Optional[Node]" = None,
|
|
120
|
+
parent_id: Optional[int] = -1,
|
|
121
|
+
position: Optional[int] = -1,
|
|
122
|
+
) -> None:
|
|
123
|
+
self.cover = cover
|
|
124
|
+
self.is_leaf = is_leaf
|
|
125
|
+
self.default_left = default_left
|
|
126
|
+
self.__feature = feature
|
|
127
|
+
self.value = value
|
|
128
|
+
self.n_children = n_children
|
|
129
|
+
self.left_child = left_child
|
|
130
|
+
self.right_child = right_child
|
|
131
|
+
self.parent_id = parent_id
|
|
132
|
+
self.position = position
|
|
133
|
+
|
|
134
|
+
@staticmethod
|
|
135
|
+
def from_xgb_dict(
|
|
136
|
+
input_dict: Dict[str, Any], feature_names_to_indices: dict[str, int]
|
|
137
|
+
) -> "Node":
|
|
138
|
+
if "children" in input_dict:
|
|
139
|
+
left_child = Node.from_xgb_dict(
|
|
140
|
+
input_dict["children"][0], feature_names_to_indices
|
|
141
|
+
)
|
|
142
|
+
right_child = Node.from_xgb_dict(
|
|
143
|
+
input_dict["children"][1], feature_names_to_indices
|
|
144
|
+
)
|
|
145
|
+
n_children = 2 + left_child.n_children + right_child.n_children
|
|
146
|
+
else:
|
|
147
|
+
left_child = None
|
|
148
|
+
right_child = None
|
|
149
|
+
n_children = 0
|
|
150
|
+
is_leaf = "leaf" in input_dict
|
|
151
|
+
default_left = "yes" in input_dict and input_dict["yes"] == input_dict["missing"]
|
|
152
|
+
feature = input_dict.get("split")
|
|
153
|
+
if feature:
|
|
154
|
+
feature = feature_names_to_indices[feature]
|
|
155
|
+
return Node(
|
|
156
|
+
cover=input_dict["cover"],
|
|
157
|
+
is_leaf=is_leaf,
|
|
158
|
+
default_left=default_left,
|
|
159
|
+
feature=feature,
|
|
160
|
+
value=input_dict["leaf"] if is_leaf else input_dict["split_condition"],
|
|
161
|
+
n_children=n_children,
|
|
162
|
+
left_child=left_child,
|
|
163
|
+
right_child=right_child,
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
@staticmethod
|
|
167
|
+
def from_lightgbm_dict(input_dict: Dict[str, Any]) -> "Node":
|
|
168
|
+
if "tree_structure" in input_dict:
|
|
169
|
+
tree = input_dict["tree_structure"]
|
|
170
|
+
else:
|
|
171
|
+
tree = input_dict
|
|
172
|
+
|
|
173
|
+
n_children = 0
|
|
174
|
+
if "left_child" in tree:
|
|
175
|
+
left_child = Node.from_lightgbm_dict(tree["left_child"])
|
|
176
|
+
n_children += 1 + left_child.n_children
|
|
177
|
+
else:
|
|
178
|
+
left_child = None
|
|
179
|
+
if "right_child" in tree:
|
|
180
|
+
right_child = Node.from_lightgbm_dict(tree["right_child"])
|
|
181
|
+
n_children += 1 + right_child.n_children
|
|
182
|
+
else:
|
|
183
|
+
right_child = None
|
|
184
|
+
|
|
185
|
+
is_leaf = "leaf_value" in tree
|
|
186
|
+
# get cover and value for leaf nodes or internal nodes
|
|
187
|
+
cover = tree.get("leaf_count", 0) or tree.get("internal_count", 0)
|
|
188
|
+
value = tree.get("leaf_value", 0) or tree.get("threshold", 0)
|
|
189
|
+
return Node(
|
|
190
|
+
cover=cover,
|
|
191
|
+
is_leaf=is_leaf,
|
|
192
|
+
default_left=tree.get("default_left", 0),
|
|
193
|
+
feature=tree.get("split_feature"),
|
|
194
|
+
value=value,
|
|
195
|
+
n_children=n_children,
|
|
196
|
+
left_child=left_child,
|
|
197
|
+
right_child=right_child,
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
def get_value_closest_float_downward(self) -> np.float64:
|
|
201
|
+
"""Get the closest exact fp value smaller than self.value"""
|
|
202
|
+
return np.nextafter(np.single(self.value), np.single(-np.inf))
|
|
203
|
+
|
|
204
|
+
def get_children(self) -> "Optional[Tuple[Node, Node]]":
|
|
205
|
+
if not self.left_child or not self.right_child:
|
|
206
|
+
assert self.is_leaf
|
|
207
|
+
else:
|
|
208
|
+
return (self.left_child, self.right_child)
|
|
209
|
+
|
|
210
|
+
@property
|
|
211
|
+
def feature(self) -> int:
|
|
212
|
+
if isinstance(self.__feature, int):
|
|
213
|
+
return self.__feature
|
|
214
|
+
if isinstance(self.__feature, str) and self.__feature.isnumeric():
|
|
215
|
+
return int(self.__feature)
|
|
216
|
+
raise AttributeError(
|
|
217
|
+
f"Feature names must be integers (got ({type(self.__feature)}){self.__feature})"
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
class TreeView:
|
|
222
|
+
"""Helper class, treating a list of nodes as one tree"""
|
|
223
|
+
|
|
224
|
+
def __init__(self, tree_id: int, root_node: Node) -> None:
|
|
225
|
+
self.tree_id = tree_id
|
|
226
|
+
self.root_node = root_node
|
|
227
|
+
|
|
228
|
+
@property
|
|
229
|
+
def is_leaf(self) -> bool:
|
|
230
|
+
return self.root_node.is_leaf
|
|
231
|
+
|
|
232
|
+
@property
|
|
233
|
+
def value(self) -> float:
|
|
234
|
+
if not self.is_leaf:
|
|
235
|
+
raise AttributeError("Tree is not a leaf-only tree")
|
|
236
|
+
if self.root_node.value is None:
|
|
237
|
+
raise AttributeError("Tree is leaf-only but leaf node has no value")
|
|
238
|
+
return self.root_node.value
|
|
239
|
+
|
|
240
|
+
@property
|
|
241
|
+
def cover(self) -> float:
|
|
242
|
+
if not self.is_leaf:
|
|
243
|
+
raise AttributeError("Tree is not a leaf-only tree")
|
|
244
|
+
return self.root_node.cover
|
|
245
|
+
|
|
246
|
+
@property
|
|
247
|
+
def n_nodes(self) -> int:
|
|
248
|
+
return self.root_node.n_children + 1
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
class TreeList(list):
|
|
252
|
+
"""Helper class that is able to extract all information required by the
|
|
253
|
+
model builders from various objects"""
|
|
254
|
+
|
|
255
|
+
@staticmethod
|
|
256
|
+
def from_xgb_booster(
|
|
257
|
+
booster, max_trees: int, feature_names_to_indices: dict[str, int]
|
|
258
|
+
) -> "TreeList":
|
|
259
|
+
"""
|
|
260
|
+
Load a TreeList from an xgb.Booster object
|
|
261
|
+
Note: We cannot type-hint the xgb.Booster without loading xgb as dependency in pyx code,
|
|
262
|
+
therefore not type hint is added.
|
|
263
|
+
"""
|
|
264
|
+
|
|
265
|
+
# Note: in XGBoost, it's possible to use 'int' type for features that contain
|
|
266
|
+
# non-integer floating points. In such case, the training procedure and JSON
|
|
267
|
+
# export from XGBoost will not treat them any differently from 'q'-type
|
|
268
|
+
# (numeric) features, but the per-tree JSON text dumps used here will output
|
|
269
|
+
# a split threshold rounded to the nearest integer for those 'int' features,
|
|
270
|
+
# even if the booster internally has thresholds with decimal points and outputs
|
|
271
|
+
# them as such in the full-model JSON dumps. Hence the need for this override
|
|
272
|
+
# mechanism. If this behavior changes in XGBoost, then this conversion and
|
|
273
|
+
# override can be removed.
|
|
274
|
+
orig_feature_types = None
|
|
275
|
+
try:
|
|
276
|
+
if hasattr(booster, "feature_types"):
|
|
277
|
+
feature_types = booster.feature_types
|
|
278
|
+
orig_feature_types = deepcopy(feature_types)
|
|
279
|
+
if feature_types:
|
|
280
|
+
for i in range(len(feature_types)):
|
|
281
|
+
if feature_types[i] == "int":
|
|
282
|
+
feature_types[i] = "float"
|
|
283
|
+
booster.feature_types = feature_types
|
|
284
|
+
|
|
285
|
+
tl = TreeList()
|
|
286
|
+
dump = booster.get_dump(dump_format="json", with_stats=True)
|
|
287
|
+
finally:
|
|
288
|
+
if orig_feature_types:
|
|
289
|
+
booster.feature_types = orig_feature_types
|
|
290
|
+
for tree_id, raw_tree in enumerate(dump):
|
|
291
|
+
if max_trees > 0 and tree_id == max_trees:
|
|
292
|
+
break
|
|
293
|
+
raw_tree_parsed = json.loads(raw_tree)
|
|
294
|
+
root_node = Node.from_xgb_dict(raw_tree_parsed, feature_names_to_indices)
|
|
295
|
+
tl.append(TreeView(tree_id=tree_id, root_node=root_node))
|
|
296
|
+
|
|
297
|
+
return tl
|
|
298
|
+
|
|
299
|
+
@staticmethod
|
|
300
|
+
def from_lightgbm_booster_dump(dump: Dict[str, Any]) -> "TreeList":
|
|
301
|
+
"""
|
|
302
|
+
Load a TreeList from a lgbm Booster dump
|
|
303
|
+
Note: We cannot type-hint the the Model without loading lightgbm as dependency in pyx code,
|
|
304
|
+
therefore not type hint is added.
|
|
305
|
+
"""
|
|
306
|
+
tl = TreeList()
|
|
307
|
+
for tree_id, tree_dict in enumerate(dump["tree_info"]):
|
|
308
|
+
root_node = Node.from_lightgbm_dict(tree_dict)
|
|
309
|
+
tl.append(TreeView(tree_id=tree_id, root_node=root_node))
|
|
310
|
+
|
|
311
|
+
return tl
|
|
312
|
+
|
|
313
|
+
def __setitem__(self):
|
|
314
|
+
raise NotImplementedError(
|
|
315
|
+
"Use TreeList.from_*() methods to initialize a TreeList"
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
def get_lightgbm_params(booster):
|
|
320
|
+
return booster.dump_model()
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
def get_xgboost_params(booster):
|
|
324
|
+
return json.loads(booster.save_config())
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
def get_catboost_params(booster):
|
|
328
|
+
with NamedTemporaryFile() as fp:
|
|
329
|
+
booster.save_model(fp.name, "json")
|
|
330
|
+
fp.seek(0)
|
|
331
|
+
model_data = json.load(fp)
|
|
332
|
+
return model_data
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def get_gbt_model_from_tree_list(
|
|
336
|
+
tree_list: TreeList,
|
|
337
|
+
n_iterations: int,
|
|
338
|
+
is_regression: bool,
|
|
339
|
+
n_features: int,
|
|
340
|
+
n_classes: int,
|
|
341
|
+
base_score: Optional[float] = None,
|
|
342
|
+
):
|
|
343
|
+
"""Return a GBT Model from TreeList"""
|
|
344
|
+
|
|
345
|
+
if is_regression:
|
|
346
|
+
mb = gbt_reg_model_builder(n_features=n_features, n_iterations=n_iterations)
|
|
347
|
+
else:
|
|
348
|
+
mb = gbt_clf_model_builder(
|
|
349
|
+
n_features=n_features, n_iterations=n_iterations, n_classes=n_classes
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
class_label = 0
|
|
353
|
+
for counter, tree in enumerate(tree_list, start=1):
|
|
354
|
+
# find out the number of nodes in the tree
|
|
355
|
+
if is_regression:
|
|
356
|
+
tree_id = mb.create_tree(tree.n_nodes)
|
|
357
|
+
else:
|
|
358
|
+
tree_id = mb.create_tree(n_nodes=tree.n_nodes, class_label=class_label)
|
|
359
|
+
|
|
360
|
+
if counter % n_iterations == 0:
|
|
361
|
+
class_label += 1
|
|
362
|
+
|
|
363
|
+
if tree.is_leaf:
|
|
364
|
+
mb.add_leaf(tree_id=tree_id, response=tree.value, cover=tree.cover)
|
|
365
|
+
continue
|
|
366
|
+
|
|
367
|
+
root_node = tree.root_node
|
|
368
|
+
parent_id = mb.add_split(
|
|
369
|
+
tree_id=tree_id,
|
|
370
|
+
feature_index=root_node.feature,
|
|
371
|
+
feature_value=root_node.get_value_closest_float_downward(),
|
|
372
|
+
cover=root_node.cover,
|
|
373
|
+
default_left=root_node.default_left,
|
|
374
|
+
)
|
|
375
|
+
|
|
376
|
+
# create queue
|
|
377
|
+
node_queue: Deque[Node] = deque()
|
|
378
|
+
children = root_node.get_children()
|
|
379
|
+
assert children is not None
|
|
380
|
+
for position, child in enumerate(children):
|
|
381
|
+
child.parent_id = parent_id
|
|
382
|
+
child.position = position
|
|
383
|
+
node_queue.append(child)
|
|
384
|
+
|
|
385
|
+
while node_queue:
|
|
386
|
+
node = node_queue.popleft()
|
|
387
|
+
assert node.parent_id != -1, "node.parent_id must not be -1"
|
|
388
|
+
assert node.position != -1, "node.position must not be -1"
|
|
389
|
+
|
|
390
|
+
if node.is_leaf:
|
|
391
|
+
mb.add_leaf(
|
|
392
|
+
tree_id=tree_id,
|
|
393
|
+
response=node.value,
|
|
394
|
+
cover=node.cover,
|
|
395
|
+
parent_id=node.parent_id,
|
|
396
|
+
position=node.position,
|
|
397
|
+
)
|
|
398
|
+
else:
|
|
399
|
+
parent_id = mb.add_split(
|
|
400
|
+
tree_id=tree_id,
|
|
401
|
+
feature_index=node.feature,
|
|
402
|
+
feature_value=node.get_value_closest_float_downward(),
|
|
403
|
+
cover=node.cover,
|
|
404
|
+
default_left=node.default_left,
|
|
405
|
+
parent_id=node.parent_id,
|
|
406
|
+
position=node.position,
|
|
407
|
+
)
|
|
408
|
+
|
|
409
|
+
children = node.get_children()
|
|
410
|
+
assert children is not None
|
|
411
|
+
for position, child in enumerate(children):
|
|
412
|
+
child.parent_id = parent_id
|
|
413
|
+
child.position = position
|
|
414
|
+
node_queue.append(child)
|
|
415
|
+
|
|
416
|
+
return mb.model(base_score=base_score)
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
def get_gbt_model_from_lightgbm(model: Any, booster=None) -> Any:
|
|
420
|
+
model_str = model.model_to_string()
|
|
421
|
+
if "is_linear=1" in model_str:
|
|
422
|
+
raise TypeError("Linear trees are not supported.")
|
|
423
|
+
if "[boosting: dart]" in model_str:
|
|
424
|
+
raise TypeError("'Dart' booster is not supported.")
|
|
425
|
+
if "[boosting: rf]" in model_str:
|
|
426
|
+
raise TypeError("Random forest boosters are not supported.")
|
|
427
|
+
if ("[objective: lambdarank]" in model_str) or (
|
|
428
|
+
"[objective: rank_xendcg]" in model_str
|
|
429
|
+
):
|
|
430
|
+
raise TypeError("Ranking objectives are not supported.")
|
|
431
|
+
|
|
432
|
+
if booster is None:
|
|
433
|
+
booster = model.dump_model()
|
|
434
|
+
|
|
435
|
+
n_features = booster["max_feature_idx"] + 1
|
|
436
|
+
n_iterations = len(booster["tree_info"]) / booster["num_tree_per_iteration"]
|
|
437
|
+
n_classes = booster["num_tree_per_iteration"]
|
|
438
|
+
|
|
439
|
+
is_regression = False
|
|
440
|
+
objective_fun = booster["objective"]
|
|
441
|
+
if n_classes > 2:
|
|
442
|
+
if ("ova" in objective_fun) or ("ovr" in objective_fun):
|
|
443
|
+
raise TypeError(
|
|
444
|
+
"Only multiclass (softmax) objective is supported for multiclass classification"
|
|
445
|
+
)
|
|
446
|
+
elif "binary" in objective_fun: # nClasses == 1
|
|
447
|
+
n_classes = 2
|
|
448
|
+
else:
|
|
449
|
+
is_regression = True
|
|
450
|
+
|
|
451
|
+
tree_list = TreeList.from_lightgbm_booster_dump(booster)
|
|
452
|
+
|
|
453
|
+
return get_gbt_model_from_tree_list(
|
|
454
|
+
tree_list,
|
|
455
|
+
n_iterations=n_iterations,
|
|
456
|
+
is_regression=is_regression,
|
|
457
|
+
n_features=n_features,
|
|
458
|
+
n_classes=n_classes,
|
|
459
|
+
)
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
def get_gbt_model_from_xgboost(booster: Any, xgb_config=None) -> Any:
|
|
463
|
+
# Note: in the absence of any feature names, XGBoost will generate
|
|
464
|
+
# tree json dumps where features are named 'f0..N'. While the JSONs
|
|
465
|
+
# of the whole model will have feature indices, the per-tree JSONs
|
|
466
|
+
# used here always use string names instead, hence the need for this.
|
|
467
|
+
feature_names = booster.feature_names
|
|
468
|
+
if feature_names:
|
|
469
|
+
feature_names_to_indices = {fname: ind for ind, fname in enumerate(feature_names)}
|
|
470
|
+
else:
|
|
471
|
+
feature_names_to_indices = {
|
|
472
|
+
f"f{ind}": ind for ind in range(booster.num_features())
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
if xgb_config is None:
|
|
476
|
+
xgb_config = get_xgboost_params(booster)
|
|
477
|
+
|
|
478
|
+
if xgb_config["learner"]["learner_train_param"]["booster"] != "gbtree":
|
|
479
|
+
raise TypeError("Only 'gbtree' booster type is supported.")
|
|
480
|
+
|
|
481
|
+
n_targets = xgb_config["learner"]["learner_model_param"].get("num_target")
|
|
482
|
+
if n_targets is not None and int(n_targets) > 1:
|
|
483
|
+
raise TypeError("Multi-target boosters are not supported.")
|
|
484
|
+
|
|
485
|
+
n_features = int(xgb_config["learner"]["learner_model_param"]["num_feature"])
|
|
486
|
+
n_classes = int(xgb_config["learner"]["learner_model_param"]["num_class"])
|
|
487
|
+
base_score = float(xgb_config["learner"]["learner_model_param"]["base_score"])
|
|
488
|
+
|
|
489
|
+
is_regression = False
|
|
490
|
+
objective_fun = xgb_config["learner"]["learner_train_param"]["objective"]
|
|
491
|
+
|
|
492
|
+
# Note: the base score from XGBoost is in the response scale, but the predictions
|
|
493
|
+
# are calculated in the link scale, so when there is a non-identity link function,
|
|
494
|
+
# it needs to be converted to the link scale.
|
|
495
|
+
if objective_fun in ["count:poisson", "reg:gamma", "reg:tweedie", "survival:aft"]:
|
|
496
|
+
base_score = float(np.log(base_score))
|
|
497
|
+
elif objective_fun == "reg:logistic":
|
|
498
|
+
base_score = float(np.log(base_score / (1 - base_score)))
|
|
499
|
+
elif objective_fun.startswith("rank"):
|
|
500
|
+
raise TypeError("Ranking objectives are not supported.")
|
|
501
|
+
|
|
502
|
+
if n_classes > 2:
|
|
503
|
+
if objective_fun not in ["multi:softprob", "multi:softmax"]:
|
|
504
|
+
raise TypeError(
|
|
505
|
+
"multi:softprob and multi:softmax are only supported for multiclass classification"
|
|
506
|
+
)
|
|
507
|
+
elif objective_fun.startswith("binary:"):
|
|
508
|
+
if objective_fun not in ["binary:logistic", "binary:logitraw"]:
|
|
509
|
+
raise TypeError(
|
|
510
|
+
"only binary:logistic and binary:logitraw are supported for binary classification"
|
|
511
|
+
)
|
|
512
|
+
n_classes = 2
|
|
513
|
+
if objective_fun == "binary:logitraw":
|
|
514
|
+
# daal4py always applies a sigmoid for pred_proba, wheres XGBoost
|
|
515
|
+
# returns raw predictions with logitraw
|
|
516
|
+
base_score = float(1 / (1 + np.exp(-base_score)))
|
|
517
|
+
else:
|
|
518
|
+
is_regression = True
|
|
519
|
+
|
|
520
|
+
# max_trees=0 if best_iteration does not exist
|
|
521
|
+
max_trees = getattr(booster, "best_iteration", -1) + 1
|
|
522
|
+
if n_classes > 2:
|
|
523
|
+
max_trees *= n_classes
|
|
524
|
+
tree_list = TreeList.from_xgb_booster(booster, max_trees, feature_names_to_indices)
|
|
525
|
+
|
|
526
|
+
if hasattr(booster, "best_iteration"):
|
|
527
|
+
n_iterations = booster.best_iteration + 1
|
|
528
|
+
else:
|
|
529
|
+
n_iterations = len(tree_list) // (n_classes if n_classes > 2 else 1)
|
|
530
|
+
|
|
531
|
+
return get_gbt_model_from_tree_list(
|
|
532
|
+
tree_list,
|
|
533
|
+
n_iterations=n_iterations,
|
|
534
|
+
is_regression=is_regression,
|
|
535
|
+
n_features=n_features,
|
|
536
|
+
n_classes=n_classes,
|
|
537
|
+
base_score=base_score,
|
|
538
|
+
)
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
def __get_value_as_list(node):
|
|
542
|
+
"""Make sure the values are a list"""
|
|
543
|
+
values = node["value"]
|
|
544
|
+
if isinstance(values, (list, tuple)):
|
|
545
|
+
return values
|
|
546
|
+
else:
|
|
547
|
+
return [values]
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
def __calc_node_weights_from_leaf_weights(weights):
|
|
551
|
+
def sum_pairs(values):
|
|
552
|
+
assert len(values) % 2 == 0, "Length of values must be even"
|
|
553
|
+
return [values[i] + values[i + 1] for i in range(0, len(values), 2)]
|
|
554
|
+
|
|
555
|
+
level_weights = sum_pairs(weights)
|
|
556
|
+
result = [level_weights]
|
|
557
|
+
while len(level_weights) > 1:
|
|
558
|
+
level_weights = sum_pairs(level_weights)
|
|
559
|
+
result.append(level_weights)
|
|
560
|
+
return result[::-1]
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
def get_gbt_model_from_catboost(booster: Any) -> Any:
|
|
564
|
+
if not booster.is_fitted():
|
|
565
|
+
raise RuntimeError("Model should be fitted before exporting to daal4py.")
|
|
566
|
+
|
|
567
|
+
model = CatBoostModelData(get_catboost_params(booster))
|
|
568
|
+
|
|
569
|
+
if model.has_categorical_features:
|
|
570
|
+
raise NotImplementedError(
|
|
571
|
+
"Categorical features are not supported in daal4py Gradient Boosting Trees"
|
|
572
|
+
)
|
|
573
|
+
|
|
574
|
+
objective = booster.get_params().get("objective", "")
|
|
575
|
+
if (
|
|
576
|
+
"Rank" in objective
|
|
577
|
+
or "Query" in objective
|
|
578
|
+
or "Pair" in objective
|
|
579
|
+
or objective in ["LambdaMart", "StochasticFilter", "GroupQuantile"]
|
|
580
|
+
):
|
|
581
|
+
raise TypeError("Ranking objectives are not supported.")
|
|
582
|
+
if "Multi" in objective and objective != "MultiClass":
|
|
583
|
+
if model.is_classification:
|
|
584
|
+
raise TypeError(
|
|
585
|
+
"Only 'MultiClass' loss is supported for multi-class classification."
|
|
586
|
+
)
|
|
587
|
+
else:
|
|
588
|
+
raise TypeError("Multi-output models are not supported.")
|
|
589
|
+
|
|
590
|
+
if model.is_classification:
|
|
591
|
+
mb = gbt_clf_model_builder(
|
|
592
|
+
n_features=model.n_features,
|
|
593
|
+
n_iterations=model.n_iterations,
|
|
594
|
+
n_classes=model.n_classes,
|
|
595
|
+
)
|
|
596
|
+
else:
|
|
597
|
+
mb = gbt_reg_model_builder(
|
|
598
|
+
n_features=model.n_features, n_iterations=model.n_iterations
|
|
599
|
+
)
|
|
600
|
+
|
|
601
|
+
# Create splits array (all splits are placed sequentially)
|
|
602
|
+
splits = []
|
|
603
|
+
for feature in model.float_features:
|
|
604
|
+
if feature["borders"]:
|
|
605
|
+
for feature_border in feature["borders"]:
|
|
606
|
+
splits.append(
|
|
607
|
+
{"feature_index": feature["feature_index"], "value": feature_border}
|
|
608
|
+
)
|
|
609
|
+
|
|
610
|
+
# Note: catboost models might have a 'bias' (intercept) which gets added
|
|
611
|
+
# to all predictions. In the case of single-output models, this is a scalar,
|
|
612
|
+
# but in the case of multi-output models such as multinomial logistic, it
|
|
613
|
+
# is a vector. Since daal4py doesn't support vector-valued intercepts, this
|
|
614
|
+
# adds the intercept to every terminal node instead, by dividing it equally
|
|
615
|
+
# among all trees. Usually, catboost would anyway set them to zero, but it
|
|
616
|
+
# still allows setting custom intercepts.
|
|
617
|
+
cb_bias = booster.get_scale_and_bias()[1]
|
|
618
|
+
add_intercept_to_each_node = isinstance(cb_bias, list)
|
|
619
|
+
if add_intercept_to_each_node:
|
|
620
|
+
cb_bias = np.array(cb_bias) / model.n_iterations
|
|
621
|
+
if not model.is_classification:
|
|
622
|
+
raise TypeError("Multi-output regression models are not supported.")
|
|
623
|
+
|
|
624
|
+
def add_vector_bias(values: list[float]) -> list[float]:
|
|
625
|
+
return list(np.array(values) + cb_bias)
|
|
626
|
+
|
|
627
|
+
trees_explicit = []
|
|
628
|
+
tree_symmetric = []
|
|
629
|
+
|
|
630
|
+
all_trees_are_empty = True
|
|
631
|
+
|
|
632
|
+
if model.is_symmetric_tree:
|
|
633
|
+
for tree in model.oblivious_trees:
|
|
634
|
+
tree_splits = tree.get("splits", [])
|
|
635
|
+
cur_tree_depth = len(tree_splits) if tree_splits is not None else 0
|
|
636
|
+
tree_symmetric.append((tree, cur_tree_depth))
|
|
637
|
+
else:
|
|
638
|
+
for tree in model.trees:
|
|
639
|
+
n_nodes = 1
|
|
640
|
+
|
|
641
|
+
# Check if node is a leaf (in case of stump)
|
|
642
|
+
if "split" in tree:
|
|
643
|
+
# Get number of trees and splits info via BFS
|
|
644
|
+
# Create queue
|
|
645
|
+
nodes_queue = []
|
|
646
|
+
root_node = CatBoostNode(split=splits[tree["split"]["split_index"]])
|
|
647
|
+
nodes_queue.append((tree, root_node))
|
|
648
|
+
while nodes_queue:
|
|
649
|
+
cur_node_data, cur_node = nodes_queue.pop(0)
|
|
650
|
+
if "value" in cur_node_data:
|
|
651
|
+
cur_node.value = __get_value_as_list(cur_node_data)
|
|
652
|
+
else:
|
|
653
|
+
cur_node.split = splits[cur_node_data["split"]["split_index"]]
|
|
654
|
+
left_node = CatBoostNode()
|
|
655
|
+
right_node = CatBoostNode()
|
|
656
|
+
cur_node.left = left_node
|
|
657
|
+
cur_node.right = right_node
|
|
658
|
+
nodes_queue.append((cur_node_data["left"], left_node))
|
|
659
|
+
nodes_queue.append((cur_node_data["right"], right_node))
|
|
660
|
+
n_nodes += 2
|
|
661
|
+
all_trees_are_empty = False
|
|
662
|
+
else:
|
|
663
|
+
root_node = CatBoostNode()
|
|
664
|
+
if model.is_classification and model.n_classes > 2:
|
|
665
|
+
root_node.value = [value * model.scale for value in tree["value"]]
|
|
666
|
+
if add_intercept_to_each_node:
|
|
667
|
+
root_node.value = add_vector_bias(root_node.value)
|
|
668
|
+
else:
|
|
669
|
+
root_node.value = [tree["value"] * model.scale]
|
|
670
|
+
trees_explicit.append((root_node, n_nodes))
|
|
671
|
+
|
|
672
|
+
tree_id = []
|
|
673
|
+
class_label = 0
|
|
674
|
+
count = 0
|
|
675
|
+
|
|
676
|
+
# Only 1 tree for each iteration in case of regression or binary classification
|
|
677
|
+
if not model.is_classification or model.n_classes == 2:
|
|
678
|
+
n_tree_each_iter = 1
|
|
679
|
+
else:
|
|
680
|
+
n_tree_each_iter = model.n_classes
|
|
681
|
+
|
|
682
|
+
shap_ready = False
|
|
683
|
+
|
|
684
|
+
# Create id for trees (for the right order in model builder)
|
|
685
|
+
for i in range(model.n_iterations):
|
|
686
|
+
for _ in range(n_tree_each_iter):
|
|
687
|
+
if model.is_symmetric_tree:
|
|
688
|
+
if not len(tree_symmetric):
|
|
689
|
+
n_nodes = 1
|
|
690
|
+
else:
|
|
691
|
+
n_nodes = 2 ** (tree_symmetric[i][1] + 1) - 1
|
|
692
|
+
else:
|
|
693
|
+
if not len(trees_explicit):
|
|
694
|
+
n_nodes = 1
|
|
695
|
+
else:
|
|
696
|
+
n_nodes = trees_explicit[i][1]
|
|
697
|
+
|
|
698
|
+
if model.is_classification and model.n_classes > 2:
|
|
699
|
+
tree_id.append(mb.create_tree(n_nodes, class_label))
|
|
700
|
+
count += 1
|
|
701
|
+
if count == model.n_iterations:
|
|
702
|
+
class_label += 1
|
|
703
|
+
count = 0
|
|
704
|
+
|
|
705
|
+
elif model.is_classification:
|
|
706
|
+
tree_id.append(mb.create_tree(n_nodes, 0))
|
|
707
|
+
else:
|
|
708
|
+
tree_id.append(mb.create_tree(n_nodes))
|
|
709
|
+
|
|
710
|
+
if model.is_symmetric_tree:
|
|
711
|
+
shap_ready = True # this code branch provides all info for SHAP values
|
|
712
|
+
for class_label in range(n_tree_each_iter):
|
|
713
|
+
for i in range(model.n_iterations):
|
|
714
|
+
cur_tree_info = tree_symmetric[i][0]
|
|
715
|
+
cur_tree_id = tree_id[i * n_tree_each_iter + class_label]
|
|
716
|
+
cur_tree_leaf_val = cur_tree_info["leaf_values"]
|
|
717
|
+
cur_tree_leaf_weights = cur_tree_info["leaf_weights"]
|
|
718
|
+
cur_tree_depth = tree_symmetric[i][1]
|
|
719
|
+
if cur_tree_depth == 0:
|
|
720
|
+
mb.add_leaf(
|
|
721
|
+
tree_id=cur_tree_id,
|
|
722
|
+
response=cur_tree_leaf_val[class_label] * model.scale
|
|
723
|
+
+ (cb_bias[class_label] if add_intercept_to_each_node else 0),
|
|
724
|
+
cover=cur_tree_leaf_weights[0],
|
|
725
|
+
)
|
|
726
|
+
else:
|
|
727
|
+
# One split used for the whole level
|
|
728
|
+
cur_level_split = splits[
|
|
729
|
+
cur_tree_info["splits"][cur_tree_depth - 1]["split_index"]
|
|
730
|
+
]
|
|
731
|
+
cur_tree_weights_per_level = __calc_node_weights_from_leaf_weights(
|
|
732
|
+
cur_tree_leaf_weights
|
|
733
|
+
)
|
|
734
|
+
root_weight = cur_tree_weights_per_level[0][0]
|
|
735
|
+
|
|
736
|
+
root_id = mb.add_split(
|
|
737
|
+
tree_id=cur_tree_id,
|
|
738
|
+
feature_index=cur_level_split["feature_index"],
|
|
739
|
+
feature_value=cur_level_split["value"],
|
|
740
|
+
default_left=model.default_left,
|
|
741
|
+
cover=root_weight,
|
|
742
|
+
)
|
|
743
|
+
prev_level_nodes = [root_id]
|
|
744
|
+
|
|
745
|
+
# Iterate over levels, splits in json are reversed (root split is the last)
|
|
746
|
+
for cur_level in range(cur_tree_depth - 2, -1, -1):
|
|
747
|
+
cur_level_nodes = []
|
|
748
|
+
next_level_weights = cur_tree_weights_per_level[cur_level + 1]
|
|
749
|
+
cur_level_node_index = 0
|
|
750
|
+
for cur_parent in prev_level_nodes:
|
|
751
|
+
cur_level_split = splits[
|
|
752
|
+
cur_tree_info["splits"][cur_level]["split_index"]
|
|
753
|
+
]
|
|
754
|
+
cover_nodes = next_level_weights[cur_level_node_index]
|
|
755
|
+
if cover_nodes == 0:
|
|
756
|
+
shap_ready = False
|
|
757
|
+
cur_left_node = mb.add_split(
|
|
758
|
+
tree_id=cur_tree_id,
|
|
759
|
+
parent_id=cur_parent,
|
|
760
|
+
position=0,
|
|
761
|
+
feature_index=cur_level_split["feature_index"],
|
|
762
|
+
feature_value=cur_level_split["value"],
|
|
763
|
+
default_left=model.default_left,
|
|
764
|
+
cover=cover_nodes,
|
|
765
|
+
)
|
|
766
|
+
# cur_level_node_index += 1
|
|
767
|
+
cur_right_node = mb.add_split(
|
|
768
|
+
tree_id=cur_tree_id,
|
|
769
|
+
parent_id=cur_parent,
|
|
770
|
+
position=1,
|
|
771
|
+
feature_index=cur_level_split["feature_index"],
|
|
772
|
+
feature_value=cur_level_split["value"],
|
|
773
|
+
default_left=model.default_left,
|
|
774
|
+
cover=cover_nodes,
|
|
775
|
+
)
|
|
776
|
+
# cur_level_node_index += 1
|
|
777
|
+
cur_level_nodes.append(cur_left_node)
|
|
778
|
+
cur_level_nodes.append(cur_right_node)
|
|
779
|
+
prev_level_nodes = cur_level_nodes
|
|
780
|
+
|
|
781
|
+
# Different storing format for leaves
|
|
782
|
+
if not model.is_classification or model.n_classes == 2:
|
|
783
|
+
for last_level_node_num in range(len(prev_level_nodes)):
|
|
784
|
+
mb.add_leaf(
|
|
785
|
+
tree_id=cur_tree_id,
|
|
786
|
+
response=cur_tree_leaf_val[2 * last_level_node_num]
|
|
787
|
+
* model.scale,
|
|
788
|
+
parent_id=prev_level_nodes[last_level_node_num],
|
|
789
|
+
position=0,
|
|
790
|
+
cover=cur_tree_leaf_weights[2 * last_level_node_num],
|
|
791
|
+
)
|
|
792
|
+
mb.add_leaf(
|
|
793
|
+
tree_id=cur_tree_id,
|
|
794
|
+
response=cur_tree_leaf_val[2 * last_level_node_num + 1]
|
|
795
|
+
* model.scale,
|
|
796
|
+
parent_id=prev_level_nodes[last_level_node_num],
|
|
797
|
+
position=1,
|
|
798
|
+
cover=cur_tree_leaf_weights[2 * last_level_node_num + 1],
|
|
799
|
+
)
|
|
800
|
+
else:
|
|
801
|
+
shap_ready = False
|
|
802
|
+
for last_level_node_num in range(len(prev_level_nodes)):
|
|
803
|
+
left_index = (
|
|
804
|
+
2 * last_level_node_num * n_tree_each_iter + class_label
|
|
805
|
+
)
|
|
806
|
+
right_index = (
|
|
807
|
+
2 * last_level_node_num + 1
|
|
808
|
+
) * n_tree_each_iter + class_label
|
|
809
|
+
mb.add_leaf(
|
|
810
|
+
tree_id=cur_tree_id,
|
|
811
|
+
response=cur_tree_leaf_val[left_index] * model.scale
|
|
812
|
+
+ (
|
|
813
|
+
cb_bias[class_label]
|
|
814
|
+
if add_intercept_to_each_node
|
|
815
|
+
else 0
|
|
816
|
+
),
|
|
817
|
+
parent_id=prev_level_nodes[last_level_node_num],
|
|
818
|
+
position=0,
|
|
819
|
+
cover=0.0,
|
|
820
|
+
)
|
|
821
|
+
mb.add_leaf(
|
|
822
|
+
tree_id=cur_tree_id,
|
|
823
|
+
response=cur_tree_leaf_val[right_index] * model.scale
|
|
824
|
+
+ (
|
|
825
|
+
cb_bias[class_label]
|
|
826
|
+
if add_intercept_to_each_node
|
|
827
|
+
else 0
|
|
828
|
+
),
|
|
829
|
+
parent_id=prev_level_nodes[last_level_node_num],
|
|
830
|
+
position=1,
|
|
831
|
+
cover=0.0,
|
|
832
|
+
)
|
|
833
|
+
else:
|
|
834
|
+
shap_ready = False
|
|
835
|
+
scale = booster.get_scale_and_bias()[0]
|
|
836
|
+
for class_label in range(n_tree_each_iter):
|
|
837
|
+
for i in range(model.n_iterations):
|
|
838
|
+
root_node = trees_explicit[i][0]
|
|
839
|
+
|
|
840
|
+
cur_tree_id = tree_id[i * n_tree_each_iter + class_label]
|
|
841
|
+
# Traverse tree via BFS and build tree with modelbuilder
|
|
842
|
+
if root_node.value is None:
|
|
843
|
+
root_id = mb.add_split(
|
|
844
|
+
tree_id=cur_tree_id,
|
|
845
|
+
feature_index=root_node.split["feature_index"],
|
|
846
|
+
feature_value=root_node.split["value"],
|
|
847
|
+
default_left=model.default_left,
|
|
848
|
+
cover=0.0,
|
|
849
|
+
)
|
|
850
|
+
nodes_queue = [(root_node, root_id)]
|
|
851
|
+
while nodes_queue:
|
|
852
|
+
cur_node, cur_node_id = nodes_queue.pop(0)
|
|
853
|
+
left_node = cur_node.left
|
|
854
|
+
# Check if node is a leaf
|
|
855
|
+
if left_node.value is None:
|
|
856
|
+
left_node_id = mb.add_split(
|
|
857
|
+
tree_id=cur_tree_id,
|
|
858
|
+
parent_id=cur_node_id,
|
|
859
|
+
position=0,
|
|
860
|
+
feature_index=left_node.split["feature_index"],
|
|
861
|
+
feature_value=left_node.split["value"],
|
|
862
|
+
default_left=model.default_left,
|
|
863
|
+
cover=0.0,
|
|
864
|
+
)
|
|
865
|
+
nodes_queue.append((left_node, left_node_id))
|
|
866
|
+
else:
|
|
867
|
+
mb.add_leaf(
|
|
868
|
+
tree_id=cur_tree_id,
|
|
869
|
+
response=scale * left_node.value[class_label]
|
|
870
|
+
+ (
|
|
871
|
+
cb_bias[class_label]
|
|
872
|
+
if add_intercept_to_each_node
|
|
873
|
+
else 0
|
|
874
|
+
),
|
|
875
|
+
parent_id=cur_node_id,
|
|
876
|
+
position=0,
|
|
877
|
+
cover=0.0,
|
|
878
|
+
)
|
|
879
|
+
right_node = cur_node.right
|
|
880
|
+
# Check if node is a leaf
|
|
881
|
+
if right_node.value is None:
|
|
882
|
+
right_node_id = mb.add_split(
|
|
883
|
+
tree_id=cur_tree_id,
|
|
884
|
+
parent_id=cur_node_id,
|
|
885
|
+
position=1,
|
|
886
|
+
feature_index=right_node.split["feature_index"],
|
|
887
|
+
feature_value=right_node.split["value"],
|
|
888
|
+
default_left=model.default_left,
|
|
889
|
+
cover=0.0,
|
|
890
|
+
)
|
|
891
|
+
nodes_queue.append((right_node, right_node_id))
|
|
892
|
+
else:
|
|
893
|
+
mb.add_leaf(
|
|
894
|
+
tree_id=cur_tree_id,
|
|
895
|
+
response=scale * cur_node.right.value[class_label]
|
|
896
|
+
+ (
|
|
897
|
+
cb_bias[class_label]
|
|
898
|
+
if add_intercept_to_each_node
|
|
899
|
+
else 0
|
|
900
|
+
),
|
|
901
|
+
parent_id=cur_node_id,
|
|
902
|
+
position=1,
|
|
903
|
+
cover=0.0,
|
|
904
|
+
)
|
|
905
|
+
|
|
906
|
+
else:
|
|
907
|
+
# Tree has only one node
|
|
908
|
+
# Note: the root node already has scale and bias added to it,
|
|
909
|
+
# so no need to add them again here like it is done for the leafs.
|
|
910
|
+
mb.add_leaf(
|
|
911
|
+
tree_id=cur_tree_id,
|
|
912
|
+
response=root_node.value[class_label],
|
|
913
|
+
cover=0.0,
|
|
914
|
+
)
|
|
915
|
+
|
|
916
|
+
if all_trees_are_empty and not model.is_symmetric_tree:
|
|
917
|
+
shap_ready = True
|
|
918
|
+
|
|
919
|
+
intercept = 0.0
|
|
920
|
+
if not add_intercept_to_each_node:
|
|
921
|
+
intercept = booster.get_scale_and_bias()[1]
|
|
922
|
+
return mb.model(base_score=intercept), shap_ready
|