model-diagnostics 1.4.2__tar.gz → 1.5.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 (51) hide show
  1. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/.gitignore +1 -1
  2. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/PKG-INFO +16 -15
  3. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/README.md +7 -7
  4. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/docs/gen_ref_pages.py +1 -1
  5. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/docs/index.md +6 -6
  6. model_diagnostics-1.4.2/mkdocs.yml → model_diagnostics-1.5.0/properdocs.yml +2 -0
  7. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/pyproject.toml +37 -38
  8. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/src/model_diagnostics/__about__.py +1 -1
  9. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/src/model_diagnostics/_utils/array.py +109 -37
  10. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/src/model_diagnostics/_utils/binning.py +68 -51
  11. model_diagnostics-1.5.0/src/model_diagnostics/_utils/identification.py +108 -0
  12. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/src/model_diagnostics/_utils/tests/test_array.py +195 -1
  13. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/src/model_diagnostics/_utils/tests/test_binning.py +65 -1
  14. model_diagnostics-1.5.0/src/model_diagnostics/_utils/tests/test_identification.py +45 -0
  15. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/src/model_diagnostics/_utils/tests/test_isotonic.py +1 -1
  16. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/src/model_diagnostics/calibration/__init__.py +4 -2
  17. model_diagnostics-1.4.2/src/model_diagnostics/calibration/identification.py → model_diagnostics-1.5.0/src/model_diagnostics/calibration/_compute.py +8 -109
  18. model_diagnostics-1.4.2/src/model_diagnostics/calibration/plots.py → model_diagnostics-1.5.0/src/model_diagnostics/calibration/_plots.py +4 -2
  19. model_diagnostics-1.4.2/src/model_diagnostics/calibration/tests/test_identification.py → model_diagnostics-1.5.0/src/model_diagnostics/calibration/tests/test_compute.py +10 -45
  20. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/src/model_diagnostics/calibration/tests/test_plots.py +11 -4
  21. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/src/model_diagnostics/scoring/__init__.py +2 -2
  22. model_diagnostics-1.4.2/src/model_diagnostics/scoring/plots.py → model_diagnostics-1.5.0/src/model_diagnostics/scoring/_plots.py +2 -1
  23. model_diagnostics-1.4.2/src/model_diagnostics/scoring/scoring.py → model_diagnostics-1.5.0/src/model_diagnostics/scoring/_scoring.py +30 -28
  24. model_diagnostics-1.5.0/src/model_diagnostics/xai/__init__.py +9 -0
  25. model_diagnostics-1.4.2/src/model_diagnostics/_utils/partial_dependence.py → model_diagnostics-1.5.0/src/model_diagnostics/xai/_partial_dependence.py +34 -13
  26. model_diagnostics-1.5.0/src/model_diagnostics/xai/_permutation_importance.py +291 -0
  27. model_diagnostics-1.5.0/src/model_diagnostics/xai/_plots.py +168 -0
  28. model_diagnostics-1.5.0/src/model_diagnostics/xai/tests/__init__.py +0 -0
  29. {model_diagnostics-1.4.2/src/model_diagnostics/_utils → model_diagnostics-1.5.0/src/model_diagnostics/xai}/tests/test_partial_dependence.py +37 -33
  30. model_diagnostics-1.5.0/src/model_diagnostics/xai/tests/test_permutation_importance.py +216 -0
  31. model_diagnostics-1.5.0/src/model_diagnostics/xai/tests/test_plots.py +71 -0
  32. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/.codecov.yml +0 -0
  33. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/LICENSE +0 -0
  34. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/Untitled.ipynb +0 -0
  35. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/dev_tools/print_package_versions.py +0 -0
  36. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/docs/development.md +0 -0
  37. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/docs/examples/classification.ipynb +0 -0
  38. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/docs/examples/quantile_regression.ipynb +0 -0
  39. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/docs/examples/regression_on_workers_compensation.ipynb +0 -0
  40. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/docs/javascripts/mathjax.js +0 -0
  41. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/src/model_diagnostics/__init__.py +0 -0
  42. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/src/model_diagnostics/_config.py +0 -0
  43. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/src/model_diagnostics/_utils/__init__.py +0 -0
  44. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/src/model_diagnostics/_utils/isotonic.py +0 -0
  45. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/src/model_diagnostics/_utils/plot_helper.py +0 -0
  46. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/src/model_diagnostics/_utils/test_helper.py +0 -0
  47. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/src/model_diagnostics/calibration/tests/__init__.py +0 -0
  48. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/src/model_diagnostics/scoring/tests/__init__.py +0 -0
  49. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/src/model_diagnostics/scoring/tests/test_plots.py +0 -0
  50. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/src/model_diagnostics/scoring/tests/test_scoring.py +0 -0
  51. {model_diagnostics-1.4.2 → model_diagnostics-1.5.0}/src/model_diagnostics/tests/test_config.py +0 -0
@@ -120,7 +120,7 @@ venv.bak/
120
120
  # Rope project settings
121
121
  .ropeproject
122
122
 
123
- # mkdocs documentation
123
+ # properdocs documentation
124
124
  /site
125
125
 
126
126
  # mypy
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: model-diagnostics
3
- Version: 1.4.2
3
+ Version: 1.5.0
4
4
  Summary: Tools for diagnostics and assessment of (machine learning) models
5
5
  Project-URL: Homepage, https://lorentzenchr.github.io/model-diagnostics/
6
6
  Project-URL: Source, https://github.com/lorentzenchr/model-diagnostics
@@ -27,6 +27,7 @@ License: MIT License
27
27
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
28
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
29
  SOFTWARE.
30
+ License-File: LICENSE
30
31
  Keywords: calibration,machine learning,model diagnostics
31
32
  Classifier: Development Status :: 5 - Production/Stable
32
33
  Classifier: Framework :: Hatch
@@ -34,20 +35,20 @@ Classifier: License :: OSI Approved :: MIT License
34
35
  Classifier: Operating System :: OS Independent
35
36
  Classifier: Programming Language :: Python :: 3
36
37
  Classifier: Topic :: Scientific/Engineering
37
- Requires-Python: >=3.9
38
- Requires-Dist: matplotlib>=3.6.1
39
- Requires-Dist: numpy>=1.22
38
+ Requires-Python: >=3.11
39
+ Requires-Dist: matplotlib>=3.8.4
40
+ Requires-Dist: numpy>=2.0.0
40
41
  Requires-Dist: packaging>=23.1
41
- Requires-Dist: polars>=1.0.0
42
- Requires-Dist: scikit-learn>=1.2.0
43
- Requires-Dist: scipy>=1.10
42
+ Requires-Dist: polars>=1.1.0
43
+ Requires-Dist: scikit-learn>=1.4.2
44
+ Requires-Dist: scipy>=1.13.1
44
45
  Description-Content-Type: text/markdown
45
46
 
46
47
  # model-diagnostics
47
48
 
48
49
  | | |
49
50
  | --- | --- |
50
- | CI/CD |[![CI - Test](https://github.com/lorentzenchr/model-diagnostics/actions/workflows/test.yml/badge.svg)](https://github.com/lorentzenchr/model-diagnostics/actions/workflows/test.yml) [![Coverage](https://codecov.io/github/lorentzenchr/model-diagnostics/coverage.svg?branch=main)](https://codecov.io/gh/lorentzenchr/model-diagnostics)
51
+ | CI/CD |[![CI - Test](https://github.com/lorentzenchr/model-diagnostics/actions/workflows/test.yml/badge.svg)](https://github.com/lorentzenchr/model-diagnostics/actions/workflows/test.yml) [![Coverage](https://codecov.io/github/lorentzenchr/model-diagnostics/coverage.svg?branch=main)](https://codecov.io/gh/lorentzenchr/model-diagnostics) [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/lorentzenchr/model-diagnostics/badge)](https://scorecard.dev/viewer/?uri=github.com/lorentzenchr/model-diagnostics)
51
52
  | Docs | [![Docs](https://github.com/lorentzenchr/model-diagnostics/actions/workflows/docs.yml/badge.svg)](https://github.com/lorentzenchr/model-diagnostics/actions/workflows/docs.yml)
52
53
  | Package | [![PyPI - Version](https://img.shields.io/pypi/v/model-diagnostics.svg?logo=pypi&label=PyPI&logoColor=gold)](https://pypi.org/project/model-diagnostics/) [![PyPI - Downloads](https://img.shields.io/pypi/dm/model-diagnostics.svg?color=blue&label=Downloads&logo=pypi&logoColor=gold)](https://pypi.org/project/model-diagnostics/) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/model-diagnostics.svg?logo=python&label=Python&logoColor=gold)](https://pypi.org/project/model-diagnostics/) |
53
54
  | Meta | [![Hatch project](https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg)](https://github.com/pypa/hatch) [![linting - Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![types - Mypy](https://img.shields.io/badge/types-Mypy-blue.svg)](https://github.com/python/mypy) [![License - MIT](https://img.shields.io/badge/license-MIT-9400d3.svg)](https://spdx.org/licenses/)
@@ -57,14 +58,14 @@ Description-Content-Type: text/markdown
57
58
  Highlights:
58
59
 
59
60
  - All common point predictions covered: mean, median, quantiles, expectiles.
60
- - Assess model calibration with [identification functions](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/identification/#model_diagnostics.calibration.identification.identification_function) (generalized residuals), [compute_bias](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/identification/#model_diagnostics.calibration.identification.compute_bias) and [compute_marginal](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/identification/#model_diagnostics.calibration.identification.compute_marginal).
61
+ - Assess model calibration with [identification functions](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/#model_diagnostics.calibration.identification_function) (generalized residuals), [compute_bias](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/#model_diagnostics.calibration.compute_bias) and [compute_marginal](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/#model_diagnostics.calibration.compute_marginal).
61
62
  - Assess calibration and bias graphically
62
- - [reliability diagrams](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/plots/#model_diagnostics.calibration.plots.plot_reliability_diagram) for auto-calibration
63
- - [bias plots](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/plots/#model_diagnostics.calibration.plots.plot_bias) for conditional calibration
64
- - [marginal plots](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/plots/#model_diagnostics.calibration.plots.plot_marginal) for average `y_obs`, `y_pred` and partial dependence for one feature
63
+ - [reliability diagrams](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/#model_diagnostics.calibration.plot_reliability_diagram) for auto-calibration
64
+ - [bias plots](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/#model_diagnostics.calibration.plot_bias) for conditional calibration
65
+ - [marginal plots](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/#model_diagnostics.calibration.plot_marginal) for average `y_obs`, `y_pred` and partial dependence for one feature
65
66
  - Assess the predictive performance of models
66
- - strictly consistent, homogeneous [scoring functions](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/scoring/scoring/)
67
- - [score decomposition](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/scoring/scoring/#model_diagnostics.scoring.scoring.decompose) into miscalibration, discrimination and uncertainty
67
+ - strictly consistent, homogeneous [scoring functions](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/scoring/)
68
+ - [score decomposition](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/scoring/#model_diagnostics.scoring.decompose) into miscalibration, discrimination and uncertainty
68
69
  - Choose your plot backend, either [matplotlib](https://matplotlib.org) or [plotly](https://plotly.com/python/), e.g., via [set_config](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/#model_diagnostics.set_config).
69
70
 
70
71
  :rocket: To our knowledge, this is the first python package to offer reliability diagrams for quantiles and expectiles and a score decomposition, both made available by an internal implementation of isotonic quantile/expectile regression. :rocket:
@@ -2,7 +2,7 @@
2
2
 
3
3
  | | |
4
4
  | --- | --- |
5
- | CI/CD |[![CI - Test](https://github.com/lorentzenchr/model-diagnostics/actions/workflows/test.yml/badge.svg)](https://github.com/lorentzenchr/model-diagnostics/actions/workflows/test.yml) [![Coverage](https://codecov.io/github/lorentzenchr/model-diagnostics/coverage.svg?branch=main)](https://codecov.io/gh/lorentzenchr/model-diagnostics)
5
+ | CI/CD |[![CI - Test](https://github.com/lorentzenchr/model-diagnostics/actions/workflows/test.yml/badge.svg)](https://github.com/lorentzenchr/model-diagnostics/actions/workflows/test.yml) [![Coverage](https://codecov.io/github/lorentzenchr/model-diagnostics/coverage.svg?branch=main)](https://codecov.io/gh/lorentzenchr/model-diagnostics) [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/lorentzenchr/model-diagnostics/badge)](https://scorecard.dev/viewer/?uri=github.com/lorentzenchr/model-diagnostics)
6
6
  | Docs | [![Docs](https://github.com/lorentzenchr/model-diagnostics/actions/workflows/docs.yml/badge.svg)](https://github.com/lorentzenchr/model-diagnostics/actions/workflows/docs.yml)
7
7
  | Package | [![PyPI - Version](https://img.shields.io/pypi/v/model-diagnostics.svg?logo=pypi&label=PyPI&logoColor=gold)](https://pypi.org/project/model-diagnostics/) [![PyPI - Downloads](https://img.shields.io/pypi/dm/model-diagnostics.svg?color=blue&label=Downloads&logo=pypi&logoColor=gold)](https://pypi.org/project/model-diagnostics/) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/model-diagnostics.svg?logo=python&label=Python&logoColor=gold)](https://pypi.org/project/model-diagnostics/) |
8
8
  | Meta | [![Hatch project](https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg)](https://github.com/pypa/hatch) [![linting - Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![types - Mypy](https://img.shields.io/badge/types-Mypy-blue.svg)](https://github.com/python/mypy) [![License - MIT](https://img.shields.io/badge/license-MIT-9400d3.svg)](https://spdx.org/licenses/)
@@ -12,14 +12,14 @@
12
12
  Highlights:
13
13
 
14
14
  - All common point predictions covered: mean, median, quantiles, expectiles.
15
- - Assess model calibration with [identification functions](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/identification/#model_diagnostics.calibration.identification.identification_function) (generalized residuals), [compute_bias](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/identification/#model_diagnostics.calibration.identification.compute_bias) and [compute_marginal](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/identification/#model_diagnostics.calibration.identification.compute_marginal).
15
+ - Assess model calibration with [identification functions](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/#model_diagnostics.calibration.identification_function) (generalized residuals), [compute_bias](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/#model_diagnostics.calibration.compute_bias) and [compute_marginal](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/#model_diagnostics.calibration.compute_marginal).
16
16
  - Assess calibration and bias graphically
17
- - [reliability diagrams](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/plots/#model_diagnostics.calibration.plots.plot_reliability_diagram) for auto-calibration
18
- - [bias plots](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/plots/#model_diagnostics.calibration.plots.plot_bias) for conditional calibration
19
- - [marginal plots](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/plots/#model_diagnostics.calibration.plots.plot_marginal) for average `y_obs`, `y_pred` and partial dependence for one feature
17
+ - [reliability diagrams](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/#model_diagnostics.calibration.plot_reliability_diagram) for auto-calibration
18
+ - [bias plots](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/#model_diagnostics.calibration.plot_bias) for conditional calibration
19
+ - [marginal plots](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/calibration/#model_diagnostics.calibration.plot_marginal) for average `y_obs`, `y_pred` and partial dependence for one feature
20
20
  - Assess the predictive performance of models
21
- - strictly consistent, homogeneous [scoring functions](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/scoring/scoring/)
22
- - [score decomposition](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/scoring/scoring/#model_diagnostics.scoring.scoring.decompose) into miscalibration, discrimination and uncertainty
21
+ - strictly consistent, homogeneous [scoring functions](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/scoring/)
22
+ - [score decomposition](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/scoring/#model_diagnostics.scoring.decompose) into miscalibration, discrimination and uncertainty
23
23
  - Choose your plot backend, either [matplotlib](https://matplotlib.org) or [plotly](https://plotly.com/python/), e.g., via [set_config](https://lorentzenchr.github.io/model-diagnostics/reference/model_diagnostics/#model_diagnostics.set_config).
24
24
 
25
25
  :rocket: To our knowledge, this is the first python package to offer reliability diagrams for quantiles and expectiles and a score decomposition, both made available by an internal implementation of isotonic quantile/expectile regression. :rocket:
@@ -17,7 +17,7 @@ log_msg = ["\n\tAPI tReference:"]
17
17
  for path in sorted(
18
18
  set(src.rglob("*.py"))
19
19
  - set(src.rglob("*tests/*.py"))
20
- # - set(src.rglob("*/_[!_]*.py")) # No single underscore file
20
+ - set(src.rglob("*/_[!_]*.py")) # No single underscore file
21
21
  - set(src.rglob("*/_[!_]*/*.py")) # No single underscore module
22
22
  - set(src.rglob("__about__.py"))
23
23
  ):
@@ -2,7 +2,7 @@
2
2
 
3
3
  | | |
4
4
  | --- | --- |
5
- | CI/CD |[![CI - Test](https://github.com/lorentzenchr/model-diagnostics/actions/workflows/test.yml/badge.svg)](https://github.com/lorentzenchr/model-diagnostics/actions/workflows/test.yml) [![Coverage](https://codecov.io/github/lorentzenchr/model-diagnostics/coverage.svg?branch=main)](https://codecov.io/gh/lorentzenchr/model-diagnostics)
5
+ | CI/CD |[![CI - Test](https://github.com/lorentzenchr/model-diagnostics/actions/workflows/test.yml/badge.svg)](https://github.com/lorentzenchr/model-diagnostics/actions/workflows/test.yml) [![Coverage](https://codecov.io/github/lorentzenchr/model-diagnostics/coverage.svg?branch=main)](https://codecov.io/gh/lorentzenchr/model-diagnostics) [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/lorentzenchr/model-diagnostics/badge)](https://scorecard.dev/viewer/?uri=github.com/lorentzenchr/model-diagnostics)
6
6
  | Docs | [![Docs](https://github.com/lorentzenchr/model-diagnostics/actions/workflows/docs.yml/badge.svg)](https://github.com/lorentzenchr/model-diagnostics/actions/workflows/docs.yml)
7
7
  | Package | [![PyPI - Version](https://img.shields.io/pypi/v/model-diagnostics.svg?logo=pypi&label=PyPI&logoColor=gold)](https://pypi.org/project/model-diagnostics/) [![PyPI - Downloads](https://img.shields.io/pypi/dm/model-diagnostics.svg?color=blue&label=Downloads&logo=pypi&logoColor=gold)](https://pypi.org/project/model-diagnostics/) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/model-diagnostics.svg?logo=python&label=Python&logoColor=gold)](https://pypi.org/project/model-diagnostics/) |
8
8
  | Meta | [![Hatch project](https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg)](https://github.com/pypa/hatch) [![linting - Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![types - Mypy](https://img.shields.io/badge/types-Mypy-blue.svg)](https://github.com/python/mypy) [![License - MIT](https://img.shields.io/badge/license-MIT-9400d3.svg)](https://spdx.org/licenses/)
@@ -12,13 +12,13 @@
12
12
  Highlights:
13
13
 
14
14
  - All common point predictions covered: mean, median, quantiles, expectiles.
15
- - Assess model calibration with [identification functions][model_diagnostics.calibration.identification.identification_function] (generalized residuals), [compute_bias][model_diagnostics.calibration.identification.compute_bias] and [compute_marginal][model_diagnostics.calibration.identification.compute_marginal].
15
+ - Assess model calibration with [identification functions][model_diagnostics.calibration.identification_function] (generalized residuals), [compute_bias][model_diagnostics.calibration.compute_bias] and [compute_marginal][model_diagnostics.calibration.compute_marginal].
16
16
  - Assess calibration and bias graphically
17
- - [reliability diagrams][model_diagnostics.calibration.plots.plot_reliability_diagram] for auto-calibration
18
- - [bias plots][model_diagnostics.calibration.plots.plot_bias] for conditional calibration
19
- - [marginal plots][model_diagnostics.calibration.plots.plot_marginal] for average `y_obs`, `y_pred` and partial dependence for one feature
17
+ - [reliability diagrams][model_diagnostics.calibration.plot_reliability_diagram] for auto-calibration
18
+ - [bias plots][model_diagnostics.calibration.plot_bias] for conditional calibration
19
+ - [marginal plots][model_diagnostics.calibration.plot_marginal] for average `y_obs`, `y_pred` and partial dependence for one feature
20
20
  - Assess the predictive performance of models
21
- - strictly consistent, homogeneous [scoring functions][model_diagnostics.scoring.scoring]
21
+ - strictly consistent, homogeneous [scoring functions][model_diagnostics.scoring]
22
22
  - [score decomposition][model_diagnostics.scoring.decompose] into miscalibration, discrimination and uncertainty
23
23
  - Choose your plot backend, either [matplotlib](https://matplotlib.org) or [plotly](https://plotly.com/python/), e.g., via [set_config][model_diagnostics.set_config].
24
24
 
@@ -53,6 +53,8 @@ nav:
53
53
 
54
54
  watch:
55
55
  - src/model_diagnostics/
56
+ - docs/development.md
57
+ - docs/index.md
56
58
 
57
59
  plugins:
58
60
  # Built-in
@@ -10,7 +10,7 @@ authors = [
10
10
  description = "Tools for diagnostics and assessment of (machine learning) models"
11
11
  readme = "README.md"
12
12
  license = { file="LICENSE" }
13
- requires-python = ">=3.9"
13
+ requires-python = ">=3.11"
14
14
  classifiers = [
15
15
  "Development Status :: 5 - Production/Stable",
16
16
  "Framework :: Hatch",
@@ -21,12 +21,12 @@ classifiers = [
21
21
  ]
22
22
  keywords = ["machine learning", "model diagnostics", "calibration"]
23
23
  dependencies = [
24
- "matplotlib>=3.6.1",
25
- "numpy>=1.22", # type annotations and method arg in quantile
24
+ "matplotlib>=3.8.4", # numpy 2 support
25
+ "numpy>=2.0.0",
26
26
  "packaging>=23.1",
27
- "polars>=1.0.0",
28
- "scikit-learn>=1.2.0", # We rely on the set_output API.
29
- "scipy>=1.10", # scipy.stats.expectile
27
+ "polars>=1.1.0", # numpy 2 support
28
+ "scikit-learn>=1.4.2", # numpy 2 support
29
+ "scipy>=1.13.1", # numpy 2 support
30
30
  ]
31
31
  dynamic = ["version"]
32
32
 
@@ -122,7 +122,6 @@ lint.isort.known-first-party = ["model_diagnostics"]
122
122
  # disallow_untyped_defs = false
123
123
  # follow_imports = "normal"
124
124
  ignore_missing_imports = true
125
- plugins = "numpy.typing.mypy_plugin"
126
125
  pretty = true
127
126
  # show_column_numbers = true
128
127
  # warn_no_return = false
@@ -150,9 +149,10 @@ exclude = [
150
149
  ]
151
150
 
152
151
  [tool.hatch.envs.default]
152
+ installer = "uv"
153
153
  dependencies = [
154
- "pandas>=1.5",
155
- "pyarrow>=11.0.0",
154
+ "pandas>=2.2.2", # numpy 2 support
155
+ "pyarrow>=16.0.0", # numpy 2 support
156
156
  "pytest",
157
157
  "pytest-cov",
158
158
  "pytest-xdist",
@@ -166,26 +166,24 @@ no-cov = "cov --no-cov"
166
166
 
167
167
  [tool.hatch.envs.docs]
168
168
  dependencies = [
169
- "mkdocs-material~=9.5.31",
169
+ "properdocs>=1.6.7", # https://github.com/ProperDocs/properdocs/discussions/33
170
+ "mkdocs-material~=9.6.7",
170
171
  "mkdocstrings[python]>=0.25.1",
171
172
  "mkdocs-gen-files>=0.5.0",
172
173
  "mkdocs-literate-nav>=0.6.1",
173
174
  "mkdocs-section-index>=0.3.9",
174
175
  "mkdocs-jupyter==0.24.7", # https://github.com/danielfrg/mkdocs-jupyter/issues/212
175
- ]
176
- extra-dependencies = [
177
- "scikit-learn>=1.3.0", # for Gamma deviance in HistGradientBoostingRegressor
176
+ "click<=8.2.1", # https://github.com/mkdocs/mkdocs/issues/4032
178
177
  ]
179
178
 
180
179
  [tool.hatch.envs.docs.scripts]
181
- build = "mkdocs build --clean --strict {args}"
182
- serve = "mkdocs serve --dev-addr localhost:8000 {args}"
183
- ci-build = "mkdocs gh-deploy --force {args}"
180
+ build = "properdocs build --clean --strict {args}"
181
+ serve = "properdocs serve --dev-addr localhost:8000 {args}"
182
+ ci-build = "properdocs gh-deploy --force {args}"
184
183
 
185
184
  [tool.hatch.envs.jupyter]
186
185
  extra-dependencies = [
187
186
  "jupyterlab>=4.0.4",
188
- "scikit-learn>=1.3.0",
189
187
  "plotly>=5.11.0",
190
188
  ]
191
189
 
@@ -195,7 +193,7 @@ lab = "jupyter lab"
195
193
  [tool.hatch.envs.format]
196
194
  detached = true
197
195
  dependencies = [
198
- "numpy>=1.22",
196
+ "numpy>=2.3",
199
197
  "mypy>=1.14",
200
198
  "ruff==0.4.4",
201
199
  ]
@@ -241,36 +239,36 @@ dependencies = [
241
239
  ]
242
240
 
243
241
  [[tool.hatch.envs.test.matrix]]
244
- python = ["3.9", "3.10", "3.11", "3.12"]
242
+ python = ["3.11", "3.12", "3.13", "3.14"]
245
243
 
246
244
  [tool.hatch.envs.test.overrides]
247
- # Minimal versions (partially inherited from scikit-learn 1.2.0)
245
+ # Minimal versions
248
246
  # but including pandas and pyarrow
249
- name."py3.9".set-extra-dependencies = [
250
- "numpy==1.22",
251
- "polars==1.0.0",
252
- "scipy==1.10",
253
- "pandas==1.5.*",
254
- "pyarrow==11.0.*"
247
+ name."py3.11".set-extra-dependencies = [
248
+ "numpy==2.0.0",
249
+ "polars==1.1.0",
250
+ "scipy==1.13.1",
251
+ "pandas==2.2.2", # numpy 2 support
252
+ "pyarrow==16.0.*" # numpy 2 support
255
253
  ]
256
254
  # Minimal versions without pandas and pyarrow
257
- name."py3.10".set-extra-dependencies = [
258
- "numpy==1.22",
259
- "polars==1.0.0",
260
- "scipy==1.10",
255
+ name."py3.12".set-extra-dependencies = [
256
+ "numpy==2.0.0",
257
+ "polars==1.1.0",
258
+ "scipy==1.13.1",
261
259
  ]
262
260
  # Some intermediate versions, with pandads but without pyarrow
263
- name."py3.11".set-extra-dependencies = [
264
- "numpy==1.26.*",
265
- "polars==1.0.*",
266
- "scipy==1.12.*",
267
- "pandas==2.0.*",
261
+ name."py3.13".set-extra-dependencies = [
262
+ "numpy==2.1.*",
263
+ "polars==1.10.*",
264
+ "scipy==1.14.*",
265
+ "pandas==2.3.*",
268
266
  "plotly",
269
267
  ]
270
268
  # Latest versions, with plotly
271
- name."py3.12".set-extra-dependencies = [
272
- "numpy>=2.2.0",
273
- "polars>=1.21.0",
269
+ name."py3.14".set-extra-dependencies = [
270
+ "numpy>=2.3.0",
271
+ "polars>=1.31.0",
274
272
  "scipy",
275
273
  "pandas",
276
274
  "plotly",
@@ -300,4 +298,5 @@ doctest_optionflags = [
300
298
  filterwarnings = [
301
299
  # fail on any warnings that are not explicitly matched below
302
300
  "error",
301
+ "ignore:Support for the dataframe interchange protocol:DeprecationWarning",
303
302
  ]
@@ -14,4 +14,4 @@
14
14
  # Dev branch marker is: 'X.Y.dev' or 'X.Y.devN' where N is an integer.
15
15
  # 'X.Y.dev0' is the canonical version of 'X.Y.dev'
16
16
  #
17
- __version__ = "1.4.2"
17
+ __version__ = "1.5.0"
@@ -1,13 +1,10 @@
1
1
  import copy
2
2
  import sys
3
- import warnings
4
- from importlib.metadata import version
5
3
  from typing import Optional, Union
6
4
 
7
5
  import numpy as np
8
6
  import numpy.typing as npt
9
7
  import polars as pl
10
- from packaging.version import Version, parse
11
8
 
12
9
  AL_or_polars = Union[npt.ArrayLike, pl.Series]
13
10
 
@@ -261,46 +258,32 @@ def safe_assign_column(x, values, column_index):
261
258
  # Setting an item of incompatible dtype is deprecated and will raise in a
262
259
  # future error of pandas.
263
260
  # Also, assigning with a different index makes troubles.
261
+ # Also, we avoid to have pyarrow installed, which newer versions of polars
262
+ # need to series.to_pandas().
264
263
  pd = sys.modules["pandas"]
265
264
  dtype = x.dtypes.iloc[column_index]
266
- if isinstance(values, pl.Series) and isinstance(
267
- values.dtype, pl.Categorical
268
- ):
269
- # FIXME: pyarrow not installed
270
- pd_values = pd.Series(
271
- data=values.cast(pl.Utf8).to_numpy(),
272
- dtype=dtype,
273
- )
265
+ if isinstance(values, pl.Series):
266
+ if isinstance(values.dtype, (pl.Categorical, pl.String)):
267
+ pd_values = pd.Series(
268
+ data=values.cast(pl.String).to_numpy(),
269
+ dtype=dtype,
270
+ )
271
+ elif values.dtype.is_integer() or values.dtype.is_float():
272
+ pd_values = pd.Series(
273
+ data=values.to_numpy(),
274
+ dtype=dtype,
275
+ )
276
+ else:
277
+ pd_values = pd.Series(
278
+ data=values.to_pandas(),
279
+ dtype=dtype,
280
+ )
274
281
  else:
275
282
  pd_values = pd.Series(
276
- data=values.to_pandas()
277
- if isinstance(values, pl.Series)
278
- else values,
283
+ data=values,
279
284
  dtype=dtype,
280
285
  )
281
- if parse(version("pandas")) < Version("2.0.0"):
282
- # FIXME: pandas >= 2.0 (<2.0 means 1.5.*)
283
- with warnings.catch_warnings():
284
- msg = (
285
- r"In a future version, `df.iloc\[:, i\] = newvals` will "
286
- r"attempt to set the values inplace instead of always "
287
- r"setting a new array. To retain the old behavior, use either "
288
- r"`df\[df.columns\[i\]\] = newvals` or, if columns are "
289
- r"non-unique, `df.isetitem\(i, newvals\)`"
290
- )
291
- warnings.filterwarnings(
292
- "ignore", category=DeprecationWarning, message=msg
293
- )
294
- if not x.index.is_unique:
295
- # Pandas might error with:
296
- # cannot reindex on an axis with duplicate labels
297
- # Try reindexing ourselves.
298
- x = x.reset_index()
299
- if not pd_values.index.is_unique:
300
- pd_values = pd_values.reset_index()
301
- x.iloc[:, column_index] = pd_values
302
- else:
303
- x.iloc[:, column_index] = pd_values
286
+ x.iloc[:, column_index] = pd_values
304
287
  except Exception as e:
305
288
  # FIXME: pyarrow version XXX
306
289
  # Older pyarrow versions of AttributeError do not have a 'add_note' method.
@@ -352,3 +335,92 @@ def safe_index_rows(x, indices):
352
335
  else:
353
336
  # numpy, polars
354
337
  return x[indices]
338
+
339
+
340
+ def safe_copy(x) -> npt.ArrayLike:
341
+ """Create a safe copy of input data in various formats.
342
+
343
+ 'Safe' means that it is guaranteed that the original data will not be modified
344
+ by modifications of the 'safe' copy. But only copy if really required.
345
+
346
+ Parameters
347
+ ----------
348
+ x : array-like
349
+ The input data to be copied, which can be numpy array, pandas DataFrame,
350
+ polars DataFrame, PyArrow Table, or other object types.
351
+
352
+ Returns
353
+ -------
354
+ copied_x : array-like
355
+ A copy of the input data in the same format.
356
+ """
357
+ if is_pyarrow_table(x) or isinstance(x, pl.DataFrame):
358
+ # Copy on Write
359
+ pass
360
+ elif hasattr(x, "copy"):
361
+ # list, numpy, pandas, scipy sparse, ...
362
+ x = x.copy()
363
+ elif not isinstance(x, tuple):
364
+ x = copy.deepcopy(x)
365
+ return x
366
+
367
+
368
+ def get_column_names(x) -> list:
369
+ """Extract column names from different data containers.
370
+
371
+ This function handles different data container formats and returns
372
+ their column names or indices if names are not available.
373
+
374
+ Parameters
375
+ ----------
376
+ x : array-like
377
+ The input data which can be a numpy array, pandas DataFrame,
378
+ polars DataFrame, PyArrow Table, or other similar data container.
379
+
380
+ Returns
381
+ -------
382
+ list
383
+ A list of column names if available, or column indices (integers)
384
+ for array-like objects without named columns.
385
+ """
386
+ if is_pyarrow_table(x):
387
+ colnames = x.column_names
388
+ elif is_pandas_df(x):
389
+ colnames = x.columns.to_list()
390
+ elif hasattr(x, "columns") and isinstance(x.columns, list):
391
+ # polars
392
+ colnames = x.columns
393
+ else:
394
+ # e.g. numpy
395
+ colnames = [str(i) for i in range(x.shape[1])]
396
+ return colnames
397
+
398
+
399
+ def to_pl_series(x, name=None) -> pl.Series:
400
+ """Convert x to a polars Series."""
401
+ try:
402
+ feature_out = pl.Series(name=name, values=x)
403
+ except ImportError:
404
+ # FIXME: pyarrow not installed
405
+ # For non numpy-backed columns, pyarrow is needed. Here we handle the case
406
+ # where pyarrow is not installed and such a pandas extention array is
407
+ # passed, e.g. with CategoricalDtype.
408
+ if is_pandas_series(x):
409
+ pandas = sys.modules["pandas"]
410
+ is_pandas_categorical = isinstance(
411
+ x.dtype, # type: ignore
412
+ pandas.CategoricalDtype,
413
+ )
414
+ feature_out = pl.from_dataframe(
415
+ x.to_frame(name=name) # type: ignore
416
+ )[:, 0]
417
+ if name is None:
418
+ feature_out = feature_out.alias("")
419
+ if is_pandas_categorical and isinstance(feature_out.dtype, pl.Enum):
420
+ # Pandas categoricals usually get mapped to polars categoricals.
421
+ # But this code path gives pl.Enum.
422
+ feature_out = feature_out.cast(pl.Categorical)
423
+ else:
424
+ raise # re-raises the ImportError
425
+
426
+ return feature_out