nestkit 0.1.0__tar.gz

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.
Files changed (49) hide show
  1. nestkit-0.1.0/LICENSE +21 -0
  2. nestkit-0.1.0/PKG-INFO +207 -0
  3. nestkit-0.1.0/README.md +160 -0
  4. nestkit-0.1.0/pyproject.toml +80 -0
  5. nestkit-0.1.0/requirements.txt +5 -0
  6. nestkit-0.1.0/setup.cfg +4 -0
  7. nestkit-0.1.0/src/nestkit/__init__.py +49 -0
  8. nestkit-0.1.0/src/nestkit/_base.py +398 -0
  9. nestkit-0.1.0/src/nestkit/_validation.py +113 -0
  10. nestkit-0.1.0/src/nestkit/calibration/__init__.py +12 -0
  11. nestkit-0.1.0/src/nestkit/calibration/calibrators.py +162 -0
  12. nestkit-0.1.0/src/nestkit/calibration/diagnostics.py +513 -0
  13. nestkit-0.1.0/src/nestkit/callbacks.py +235 -0
  14. nestkit-0.1.0/src/nestkit/classifier.py +559 -0
  15. nestkit-0.1.0/src/nestkit/comparison/__init__.py +10 -0
  16. nestkit-0.1.0/src/nestkit/comparison/comparator.py +391 -0
  17. nestkit-0.1.0/src/nestkit/comparison/statistical_tests.py +327 -0
  18. nestkit-0.1.0/src/nestkit/diagnostics/__init__.py +9 -0
  19. nestkit-0.1.0/src/nestkit/diagnostics/stability.py +201 -0
  20. nestkit-0.1.0/src/nestkit/importance/__init__.py +11 -0
  21. nestkit-0.1.0/src/nestkit/importance/aggregator.py +319 -0
  22. nestkit-0.1.0/src/nestkit/importance/extractors.py +180 -0
  23. nestkit-0.1.0/src/nestkit/importance/stability.py +106 -0
  24. nestkit-0.1.0/src/nestkit/inner/__init__.py +9 -0
  25. nestkit-0.1.0/src/nestkit/inner/search.py +151 -0
  26. nestkit-0.1.0/src/nestkit/inner/tuning_report.py +209 -0
  27. nestkit-0.1.0/src/nestkit/plotting/__init__.py +66 -0
  28. nestkit-0.1.0/src/nestkit/plotting/_style.py +38 -0
  29. nestkit-0.1.0/src/nestkit/plotting/calibration.py +220 -0
  30. nestkit-0.1.0/src/nestkit/plotting/comparison.py +302 -0
  31. nestkit-0.1.0/src/nestkit/plotting/folds.py +199 -0
  32. nestkit-0.1.0/src/nestkit/plotting/importance.py +242 -0
  33. nestkit-0.1.0/src/nestkit/plotting/summary.py +479 -0
  34. nestkit-0.1.0/src/nestkit/plotting/threshold.py +186 -0
  35. nestkit-0.1.0/src/nestkit/plotting/tuning.py +121 -0
  36. nestkit-0.1.0/src/nestkit/regressor.py +251 -0
  37. nestkit-0.1.0/src/nestkit/results/__init__.py +19 -0
  38. nestkit-0.1.0/src/nestkit/results/_base.py +283 -0
  39. nestkit-0.1.0/src/nestkit/results/classifier_results.py +279 -0
  40. nestkit-0.1.0/src/nestkit/results/regressor_results.py +146 -0
  41. nestkit-0.1.0/src/nestkit/thresholding/__init__.py +28 -0
  42. nestkit-0.1.0/src/nestkit/thresholding/criteria.py +288 -0
  43. nestkit-0.1.0/src/nestkit/thresholding/results.py +73 -0
  44. nestkit-0.1.0/src/nestkit/thresholding/strategies.py +300 -0
  45. nestkit-0.1.0/src/nestkit.egg-info/PKG-INFO +207 -0
  46. nestkit-0.1.0/src/nestkit.egg-info/SOURCES.txt +47 -0
  47. nestkit-0.1.0/src/nestkit.egg-info/dependency_links.txt +1 -0
  48. nestkit-0.1.0/src/nestkit.egg-info/requires.txt +31 -0
  49. nestkit-0.1.0/src/nestkit.egg-info/top_level.txt +1 -0
nestkit-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ettore Rocchi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
nestkit-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,207 @@
1
+ Metadata-Version: 2.4
2
+ Name: nestkit
3
+ Version: 0.1.0
4
+ Summary: Nested cross-validation toolkit with optional probability calibration, threshold optimization, and comprehensive diagnostics
5
+ Author: Ettore Rocchi
6
+ License: MIT
7
+ Classifier: Development Status :: 4 - Beta
8
+ Classifier: Intended Audience :: Science/Research
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
16
+ Requires-Python: >=3.10
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: scikit-learn>=1.2
20
+ Requires-Dist: numpy>=1.22
21
+ Requires-Dist: pandas>=1.4
22
+ Requires-Dist: joblib>=1.2
23
+ Requires-Dist: scipy>=1.9
24
+ Provides-Extra: plotting
25
+ Requires-Dist: matplotlib>=3.5; extra == "plotting"
26
+ Requires-Dist: seaborn>=0.12; extra == "plotting"
27
+ Provides-Extra: full
28
+ Requires-Dist: matplotlib>=3.5; extra == "full"
29
+ Requires-Dist: seaborn>=0.12; extra == "full"
30
+ Requires-Dist: shap>=0.42; extra == "full"
31
+ Provides-Extra: dev
32
+ Requires-Dist: pytest>=7; extra == "dev"
33
+ Requires-Dist: pytest-cov; extra == "dev"
34
+ Requires-Dist: hypothesis>=6.0; extra == "dev"
35
+ Requires-Dist: ruff; extra == "dev"
36
+ Requires-Dist: pre-commit; extra == "dev"
37
+ Provides-Extra: docs
38
+ Requires-Dist: sphinx>=7.0; extra == "docs"
39
+ Requires-Dist: pydata-sphinx-theme>=0.14; extra == "docs"
40
+ Requires-Dist: sphinx-copybutton; extra == "docs"
41
+ Requires-Dist: myst-parser>=2.0; extra == "docs"
42
+ Requires-Dist: numpydoc; extra == "docs"
43
+ Requires-Dist: nbsphinx; extra == "docs"
44
+ Requires-Dist: ipykernel; extra == "docs"
45
+ Requires-Dist: sphinx-design; extra == "docs"
46
+ Dynamic: license-file
47
+
48
+ <p align="center">
49
+ <img src="docs/_static/nestkit_logo.png" alt="nestkit" width="300">
50
+ </p>
51
+
52
+ <p align="center">
53
+ <em>A nested cross-validation toolkit for scikit-learn</em>
54
+ </p>
55
+
56
+ <p align="center">
57
+ <a href="https://pypi.org/project/nestkit/"><img src="https://img.shields.io/pypi/v/nestkit" alt="PyPI"></a>
58
+ <a href="https://pypi.org/project/nestkit/"><img src="https://img.shields.io/pypi/pyversions/nestkit" alt="Python"></a>
59
+ <a href="https://github.com/ettorerocchi/nestkit/blob/main/LICENSE"><img src="https://img.shields.io/github/license/ettorerocchi/nestkit" alt="License"></a>
60
+ </p>
61
+
62
+ ---
63
+
64
+ ## Motivation
65
+
66
+ Standard cross-validation conflates model selection with performance estimation, producing optimistically biased scores. When the same data that guides hyperparameter tuning is also used to report performance, the resulting estimates no longer reflect true generalization ability - a subtle but pervasive form of data leakage.
67
+
68
+ **Nested cross-validation** (nested CV) addresses this by separating the two concerns into an inner loop for hyperparameter search and an outer loop for unbiased evaluation. While conceptually simple, implementing nested CV correctly - with proper calibration, threshold optimization, and statistical comparison - requires careful engineering that is tedious and error-prone to write from scratch.
69
+
70
+ **nestkit** provides a scikit-learn-compatible implementation that handles the full pipeline: nested CV with integrated probability calibration, decision-threshold optimization, statistical model comparison, hyperparameter stability diagnostics, feature importance aggregation, and visualizations - all through a familiar `fit`/`predict` API.
71
+
72
+ ## Key Features
73
+
74
+ - **Nested cross-validation** for classification and regression with full scikit-learn API compatibility
75
+ - **Post-hoc probability calibration** - Platt scaling, isotonic regression, beta calibration, and Venn-ABERS prediction
76
+ - **Threshold optimization** - Youden's J, F-beta, cost-sensitive, balanced accuracy, and precision-at-recall criteria with pooled or fold-specific strategies
77
+ - **Statistical model comparison** - Nadeau-Bengio corrected t-test, Bayesian correlated t-test with ROPE, and Holm-Bonferroni multi-model correction
78
+ - **Hyperparameter stability diagnostics** - selection frequency analysis, pairwise Jaccard similarity
79
+ - **Feature importance aggregation** - cross-fold importance with Nogueira stability index and consensus feature selection
80
+ - **Callback system** - progress tracking, logging, checkpointing, and custom hooks
81
+ - **25+ plotting functions** - ROC curves, confusion matrices, calibration diagrams, threshold sensitivity, critical difference diagrams, and more
82
+ - **Residual-based prediction intervals** for regression tasks
83
+
84
+ ## Installation
85
+
86
+ ```bash
87
+ pip install nestkit
88
+ ```
89
+
90
+ Optional dependency groups:
91
+
92
+ ```bash
93
+ pip install nestkit[plotting] # matplotlib + seaborn
94
+ pip install nestkit[full] # plotting + SHAP
95
+ pip install nestkit[dev] # testing + linting
96
+ pip install nestkit[docs] # Sphinx documentation
97
+ ```
98
+
99
+ ## Quick Start
100
+
101
+ ### Classification
102
+
103
+ ```python
104
+ from sklearn.datasets import load_breast_cancer
105
+ from sklearn.ensemble import RandomForestClassifier
106
+ from nestkit import NestedCVClassifier
107
+
108
+ X, y = load_breast_cancer(return_X_y=True)
109
+
110
+ ncv = NestedCVClassifier(
111
+ estimator=RandomForestClassifier(random_state=42),
112
+ param_grid={"n_estimators": [50, 100], "max_depth": [3, 5, 10]},
113
+ outer_cv=5,
114
+ inner_cv=3,
115
+ scoring="accuracy",
116
+ random_state=42,
117
+ )
118
+ ncv.fit(X, y)
119
+
120
+ results = ncv.results_
121
+ print(results.summary_default_)
122
+ print(results.best_params_per_fold_)
123
+ ```
124
+
125
+ With calibration and threshold optimization:
126
+
127
+ ```python
128
+ ncv = NestedCVClassifier(
129
+ estimator=RandomForestClassifier(random_state=42),
130
+ param_grid={"n_estimators": [50, 100], "max_depth": [3, 5]},
131
+ outer_cv=5,
132
+ inner_cv=3,
133
+ calibration_method="isotonic",
134
+ threshold_strategy="pooled",
135
+ threshold_criterion="youden",
136
+ random_state=42,
137
+ )
138
+ ncv.fit(X, y)
139
+ print(ncv.results_.threshold_comparison())
140
+ ```
141
+
142
+ ### Regression
143
+
144
+ ```python
145
+ from sklearn.datasets import load_diabetes
146
+ from sklearn.linear_model import Ridge
147
+ from nestkit import NestedCVRegressor
148
+
149
+ X, y = load_diabetes(return_X_y=True)
150
+
151
+ ncv = NestedCVRegressor(
152
+ estimator=Ridge(),
153
+ param_grid={"alpha": [0.01, 0.1, 1.0, 10.0]},
154
+ outer_cv=5,
155
+ inner_cv=3,
156
+ prediction_intervals=True,
157
+ random_state=42,
158
+ )
159
+ ncv.fit(X, y)
160
+
161
+ results = ncv.results_
162
+ print(results.summary_default_)
163
+ print(f"PI coverage: {results.prediction_interval_coverage_['mean']:.3f}")
164
+ ```
165
+
166
+ ## Architecture
167
+
168
+ nestkit's nested CV procedure executes four phases per outer fold:
169
+
170
+ 1. **Inner CV search** - hyperparameter tuning via `GridSearchCV` or `RandomizedSearchCV` on the outer training set
171
+ 2. **Post-inner processing** - probability calibration (classification) or residual collection for prediction intervals (regression)
172
+ 3. **Refit** - the best hyperparameters are used to refit the estimator on the full outer training set
173
+ 4. **Outer evaluation** - the refitted model is scored on the held-out outer test fold
174
+
175
+ **Class hierarchy:**
176
+
177
+ | Class | Purpose |
178
+ |-------|---------|
179
+ | `NestedCVClassifier` | Classification with calibration + thresholding |
180
+ | `NestedCVRegressor` | Regression with prediction intervals |
181
+ | `ClassifierResults` / `RegressorResults` | Rich result containers |
182
+ | `NestedCVComparator` | Statistical model comparison |
183
+ | `FeatureImportanceAggregator` | Cross-fold importance analysis |
184
+ | `HyperparameterStability` | Selection consistency diagnostics |
185
+ | `PostHocCalibrator` | Standalone probability calibration |
186
+ | `InnerCVReport` | Inner CV analysis and reporting |
187
+
188
+ ## Documentation
189
+
190
+ Full documentation is available at the [nestkit documentation site](https://nestkit.readthedocs.io/).
191
+
192
+ ## Citation
193
+
194
+ If you use nestkit in your research, please cite:
195
+
196
+ ```bibtex
197
+ @software{rocchi2026nestkit,
198
+ author = {Rocchi, Ettore},
199
+ title = {nestkit: A Nested Cross-Validation Toolkit for Scikit-Learn},
200
+ year = {2026},
201
+ url = {https://github.com/ettorerocchi/nestkit},
202
+ }
203
+ ```
204
+
205
+ ## License
206
+
207
+ MIT - see [LICENSE](LICENSE) for details.
@@ -0,0 +1,160 @@
1
+ <p align="center">
2
+ <img src="docs/_static/nestkit_logo.png" alt="nestkit" width="300">
3
+ </p>
4
+
5
+ <p align="center">
6
+ <em>A nested cross-validation toolkit for scikit-learn</em>
7
+ </p>
8
+
9
+ <p align="center">
10
+ <a href="https://pypi.org/project/nestkit/"><img src="https://img.shields.io/pypi/v/nestkit" alt="PyPI"></a>
11
+ <a href="https://pypi.org/project/nestkit/"><img src="https://img.shields.io/pypi/pyversions/nestkit" alt="Python"></a>
12
+ <a href="https://github.com/ettorerocchi/nestkit/blob/main/LICENSE"><img src="https://img.shields.io/github/license/ettorerocchi/nestkit" alt="License"></a>
13
+ </p>
14
+
15
+ ---
16
+
17
+ ## Motivation
18
+
19
+ Standard cross-validation conflates model selection with performance estimation, producing optimistically biased scores. When the same data that guides hyperparameter tuning is also used to report performance, the resulting estimates no longer reflect true generalization ability - a subtle but pervasive form of data leakage.
20
+
21
+ **Nested cross-validation** (nested CV) addresses this by separating the two concerns into an inner loop for hyperparameter search and an outer loop for unbiased evaluation. While conceptually simple, implementing nested CV correctly - with proper calibration, threshold optimization, and statistical comparison - requires careful engineering that is tedious and error-prone to write from scratch.
22
+
23
+ **nestkit** provides a scikit-learn-compatible implementation that handles the full pipeline: nested CV with integrated probability calibration, decision-threshold optimization, statistical model comparison, hyperparameter stability diagnostics, feature importance aggregation, and visualizations - all through a familiar `fit`/`predict` API.
24
+
25
+ ## Key Features
26
+
27
+ - **Nested cross-validation** for classification and regression with full scikit-learn API compatibility
28
+ - **Post-hoc probability calibration** - Platt scaling, isotonic regression, beta calibration, and Venn-ABERS prediction
29
+ - **Threshold optimization** - Youden's J, F-beta, cost-sensitive, balanced accuracy, and precision-at-recall criteria with pooled or fold-specific strategies
30
+ - **Statistical model comparison** - Nadeau-Bengio corrected t-test, Bayesian correlated t-test with ROPE, and Holm-Bonferroni multi-model correction
31
+ - **Hyperparameter stability diagnostics** - selection frequency analysis, pairwise Jaccard similarity
32
+ - **Feature importance aggregation** - cross-fold importance with Nogueira stability index and consensus feature selection
33
+ - **Callback system** - progress tracking, logging, checkpointing, and custom hooks
34
+ - **25+ plotting functions** - ROC curves, confusion matrices, calibration diagrams, threshold sensitivity, critical difference diagrams, and more
35
+ - **Residual-based prediction intervals** for regression tasks
36
+
37
+ ## Installation
38
+
39
+ ```bash
40
+ pip install nestkit
41
+ ```
42
+
43
+ Optional dependency groups:
44
+
45
+ ```bash
46
+ pip install nestkit[plotting] # matplotlib + seaborn
47
+ pip install nestkit[full] # plotting + SHAP
48
+ pip install nestkit[dev] # testing + linting
49
+ pip install nestkit[docs] # Sphinx documentation
50
+ ```
51
+
52
+ ## Quick Start
53
+
54
+ ### Classification
55
+
56
+ ```python
57
+ from sklearn.datasets import load_breast_cancer
58
+ from sklearn.ensemble import RandomForestClassifier
59
+ from nestkit import NestedCVClassifier
60
+
61
+ X, y = load_breast_cancer(return_X_y=True)
62
+
63
+ ncv = NestedCVClassifier(
64
+ estimator=RandomForestClassifier(random_state=42),
65
+ param_grid={"n_estimators": [50, 100], "max_depth": [3, 5, 10]},
66
+ outer_cv=5,
67
+ inner_cv=3,
68
+ scoring="accuracy",
69
+ random_state=42,
70
+ )
71
+ ncv.fit(X, y)
72
+
73
+ results = ncv.results_
74
+ print(results.summary_default_)
75
+ print(results.best_params_per_fold_)
76
+ ```
77
+
78
+ With calibration and threshold optimization:
79
+
80
+ ```python
81
+ ncv = NestedCVClassifier(
82
+ estimator=RandomForestClassifier(random_state=42),
83
+ param_grid={"n_estimators": [50, 100], "max_depth": [3, 5]},
84
+ outer_cv=5,
85
+ inner_cv=3,
86
+ calibration_method="isotonic",
87
+ threshold_strategy="pooled",
88
+ threshold_criterion="youden",
89
+ random_state=42,
90
+ )
91
+ ncv.fit(X, y)
92
+ print(ncv.results_.threshold_comparison())
93
+ ```
94
+
95
+ ### Regression
96
+
97
+ ```python
98
+ from sklearn.datasets import load_diabetes
99
+ from sklearn.linear_model import Ridge
100
+ from nestkit import NestedCVRegressor
101
+
102
+ X, y = load_diabetes(return_X_y=True)
103
+
104
+ ncv = NestedCVRegressor(
105
+ estimator=Ridge(),
106
+ param_grid={"alpha": [0.01, 0.1, 1.0, 10.0]},
107
+ outer_cv=5,
108
+ inner_cv=3,
109
+ prediction_intervals=True,
110
+ random_state=42,
111
+ )
112
+ ncv.fit(X, y)
113
+
114
+ results = ncv.results_
115
+ print(results.summary_default_)
116
+ print(f"PI coverage: {results.prediction_interval_coverage_['mean']:.3f}")
117
+ ```
118
+
119
+ ## Architecture
120
+
121
+ nestkit's nested CV procedure executes four phases per outer fold:
122
+
123
+ 1. **Inner CV search** - hyperparameter tuning via `GridSearchCV` or `RandomizedSearchCV` on the outer training set
124
+ 2. **Post-inner processing** - probability calibration (classification) or residual collection for prediction intervals (regression)
125
+ 3. **Refit** - the best hyperparameters are used to refit the estimator on the full outer training set
126
+ 4. **Outer evaluation** - the refitted model is scored on the held-out outer test fold
127
+
128
+ **Class hierarchy:**
129
+
130
+ | Class | Purpose |
131
+ |-------|---------|
132
+ | `NestedCVClassifier` | Classification with calibration + thresholding |
133
+ | `NestedCVRegressor` | Regression with prediction intervals |
134
+ | `ClassifierResults` / `RegressorResults` | Rich result containers |
135
+ | `NestedCVComparator` | Statistical model comparison |
136
+ | `FeatureImportanceAggregator` | Cross-fold importance analysis |
137
+ | `HyperparameterStability` | Selection consistency diagnostics |
138
+ | `PostHocCalibrator` | Standalone probability calibration |
139
+ | `InnerCVReport` | Inner CV analysis and reporting |
140
+
141
+ ## Documentation
142
+
143
+ Full documentation is available at the [nestkit documentation site](https://nestkit.readthedocs.io/).
144
+
145
+ ## Citation
146
+
147
+ If you use nestkit in your research, please cite:
148
+
149
+ ```bibtex
150
+ @software{rocchi2026nestkit,
151
+ author = {Rocchi, Ettore},
152
+ title = {nestkit: A Nested Cross-Validation Toolkit for Scikit-Learn},
153
+ year = {2026},
154
+ url = {https://github.com/ettorerocchi/nestkit},
155
+ }
156
+ ```
157
+
158
+ ## License
159
+
160
+ MIT - see [LICENSE](LICENSE) for details.
@@ -0,0 +1,80 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "nestkit"
7
+ description = "Nested cross-validation toolkit with optional probability calibration, threshold optimization, and comprehensive diagnostics"
8
+ readme = "README.md"
9
+ license = {text = "MIT"}
10
+ authors = [{name = "Ettore Rocchi"}]
11
+ requires-python = ">=3.10"
12
+ dynamic = ["version", "dependencies"]
13
+ classifiers = [
14
+ "Development Status :: 4 - Beta",
15
+ "Intended Audience :: Science/Research",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3.10",
19
+ "Programming Language :: Python :: 3.11",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Programming Language :: Python :: 3.13",
22
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
23
+ ]
24
+
25
+ [project.optional-dependencies]
26
+ plotting = ["matplotlib>=3.5", "seaborn>=0.12"]
27
+ full = ["matplotlib>=3.5", "seaborn>=0.12", "shap>=0.42"]
28
+ dev = [
29
+ "pytest>=7",
30
+ "pytest-cov",
31
+ "hypothesis>=6.0",
32
+ "ruff",
33
+ "pre-commit",
34
+ ]
35
+ docs = [
36
+ "sphinx>=7.0",
37
+ "pydata-sphinx-theme>=0.14",
38
+ "sphinx-copybutton",
39
+ "myst-parser>=2.0",
40
+ "numpydoc",
41
+ "nbsphinx",
42
+ "ipykernel",
43
+ "sphinx-design",
44
+ ]
45
+
46
+ [tool.setuptools.dynamic]
47
+ version = {attr = "nestkit.__version__"}
48
+ dependencies = {file = "requirements.txt"}
49
+
50
+ [tool.setuptools.packages.find]
51
+ where = ["src"]
52
+
53
+ [tool.ruff]
54
+ target-version = "py310"
55
+ line-length = 99
56
+ src = ["src", "tests"]
57
+
58
+ [tool.ruff.lint]
59
+ select = [
60
+ "E", # pycodestyle errors
61
+ "W", # pycodestyle warnings
62
+ "F", # pyflakes
63
+ "I", # isort
64
+ "UP", # pyupgrade
65
+ "B", # flake8-bugbear
66
+ "SIM", # flake8-simplify
67
+ "RUF", # ruff-specific
68
+ ]
69
+ ignore = [
70
+ "E501", # line too long (handled by formatter)
71
+ "B905", # zip strict
72
+ "SIM108", # ternary operator
73
+ ]
74
+
75
+ [tool.ruff.lint.isort]
76
+ known-first-party = ["nestkit"]
77
+
78
+ [tool.pytest.ini_options]
79
+ testpaths = ["tests"]
80
+ addopts = "-ra -q"
@@ -0,0 +1,5 @@
1
+ scikit-learn>=1.2
2
+ numpy>=1.22
3
+ pandas>=1.4
4
+ joblib>=1.2
5
+ scipy>=1.9
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,49 @@
1
+ """nestkit - A rigorous nested cross-validation toolkit for scikit-learn.
2
+
3
+ Core estimators
4
+ ---------------
5
+ - :class:`NestedCVClassifier` - Classification with optional calibration
6
+ and threshold optimization.
7
+ - :class:`NestedCVRegressor` - Regression with optional residual-based
8
+ prediction intervals.
9
+
10
+ Results
11
+ -------
12
+ - :class:`ClassifierResults` / :class:`RegressorResults` - Rich result
13
+ containers with summary statistics, export methods, and plots.
14
+
15
+ Submodules
16
+ ----------
17
+ - :mod:`nestkit.calibration` - Post-hoc probability calibration and
18
+ calibration diagnostics.
19
+ - :mod:`nestkit.callbacks` - Fold-level monitoring (progress, logging,
20
+ checkpointing).
21
+ - :mod:`nestkit.comparison` - Statistical model comparison.
22
+ - :mod:`nestkit.diagnostics` - Hyperparameter stability analysis.
23
+ - :mod:`nestkit.importance` - Cross-fold feature importance aggregation.
24
+ - :mod:`nestkit.inner` - Inner CV tuning reports.
25
+ - :mod:`nestkit.plotting` - 25+ plotting functions for nested CV results.
26
+ - :mod:`nestkit.thresholding` - Decision-threshold optimization criteria.
27
+ """
28
+
29
+ from __future__ import annotations
30
+
31
+ import logging
32
+
33
+ from nestkit.classifier import NestedCVClassifier
34
+ from nestkit.regressor import NestedCVRegressor
35
+ from nestkit.results.classifier_results import ClassifierResults
36
+ from nestkit.results.regressor_results import RegressorResults
37
+
38
+ __version__ = "0.1.0"
39
+
40
+ logger = logging.getLogger("nestkit")
41
+ logger.addHandler(logging.NullHandler())
42
+
43
+ __all__ = [
44
+ "ClassifierResults",
45
+ "NestedCVClassifier",
46
+ "NestedCVRegressor",
47
+ "RegressorResults",
48
+ "__version__",
49
+ ]