classifier-toolkit 0.3.5__tar.gz → 0.3.6__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 (242) hide show
  1. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/.github/workflows/checks.yaml +16 -2
  2. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/PKG-INFO +1 -1
  3. classifier_toolkit-0.3.6/classifier_toolkit/calibration/__init__.py +34 -0
  4. classifier_toolkit-0.3.6/classifier_toolkit/calibration/base.py +5 -0
  5. classifier_toolkit-0.3.6/classifier_toolkit/calibration/ovr_calibration.py +254 -0
  6. classifier_toolkit-0.3.6/classifier_toolkit/calibration/reliability.py +109 -0
  7. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/eda/eda_toolkit.py +6 -0
  8. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/eda/visualizations.py +314 -91
  9. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/explainability/__init__.py +1 -0
  10. classifier_toolkit-0.3.6/classifier_toolkit/explainability/base.py +138 -0
  11. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/explainability/interactions.py +34 -6
  12. classifier_toolkit-0.3.6/classifier_toolkit/explainability/misclassification.py +244 -0
  13. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/explainability/plots.py +55 -2
  14. classifier_toolkit-0.3.6/classifier_toolkit/explainability/toolkit.py +234 -0
  15. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/explainability/tree_explainer.py +49 -1
  16. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_reduction/counter_intuitive.py +64 -6
  17. classifier_toolkit-0.3.6/classifier_toolkit/feature_selection/utils/scoring.py +373 -0
  18. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_selection/wrapper_methods/combination_search.py +78 -15
  19. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_selection/wrapper_methods/rfe.py +62 -28
  20. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/model_training/hyper_parameter_tuning/tuner.py +162 -39
  21. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/model_training/models/ensemble_methods.py +93 -30
  22. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/model_training/utils/params.py +45 -4
  23. classifier_toolkit-0.3.6/docs/calibration/overview.md +53 -0
  24. classifier_toolkit-0.3.6/docs/changelog.md +65 -0
  25. classifier_toolkit-0.3.6/docs/reference/calibration/ovr_calibration.md +3 -0
  26. classifier_toolkit-0.3.6/docs/reference/calibration/reliability.md +3 -0
  27. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/mkdocs.yml +5 -0
  28. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/pyproject.toml +1 -1
  29. classifier_toolkit-0.3.6/tests/calibration/test_ovr_calibration.py +271 -0
  30. classifier_toolkit-0.3.6/tests/calibration/test_reliability.py +67 -0
  31. classifier_toolkit-0.3.6/tests/eda/test_visualizations.py +400 -0
  32. classifier_toolkit-0.3.6/tests/explainability/__init__.py +0 -0
  33. classifier_toolkit-0.3.6/tests/explainability/test_multiclass_e2e.py +473 -0
  34. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/feature_reduction/test_counter_intuitive.py +104 -0
  35. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/feature_selection/test_combination_search.py +113 -0
  36. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/feature_selection/test_rfe.py +39 -6
  37. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/feature_selection/test_scoring.py +118 -6
  38. classifier_toolkit-0.3.6/tests/model_training/__init__.py +0 -0
  39. classifier_toolkit-0.3.6/tests/model_training/hyper_parameter_tuning/__init__.py +0 -0
  40. classifier_toolkit-0.3.6/tests/model_training/hyper_parameter_tuning/test_params.py +103 -0
  41. classifier_toolkit-0.3.6/tests/model_training/hyper_parameter_tuning/test_tuner.py +418 -0
  42. classifier_toolkit-0.3.6/tests/model_training/models/__init__.py +0 -0
  43. classifier_toolkit-0.3.6/tests/model_training/models/test_ensemble_methods.py +160 -0
  44. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/uv.lock +1 -1
  45. classifier_toolkit-0.3.5/classifier_toolkit/explainability/base.py +0 -60
  46. classifier_toolkit-0.3.5/classifier_toolkit/explainability/misclassification.py +0 -107
  47. classifier_toolkit-0.3.5/classifier_toolkit/explainability/toolkit.py +0 -137
  48. classifier_toolkit-0.3.5/classifier_toolkit/feature_selection/utils/scoring.py +0 -226
  49. classifier_toolkit-0.3.5/docs/changelog.md +0 -36
  50. classifier_toolkit-0.3.5/tests/eda/test_visualizations.py +0 -116
  51. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/.github/pull_request_template/default.md +0 -0
  52. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/.github/workflows/docs.yml +0 -0
  53. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/.github/workflows/master.yaml +0 -0
  54. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/.github/workflows/release.yaml +0 -0
  55. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/.github/workflows/working-branch.yaml +0 -0
  56. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/.gitignore +0 -0
  57. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/.python-version +0 -0
  58. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/.sqlfluff +0 -0
  59. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/LICENSE +0 -0
  60. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/Makefile +0 -0
  61. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/README.md +0 -0
  62. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/data_partition/__init__.py +0 -0
  63. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/data_partition/data_preprocess.py +0 -0
  64. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/data_partition/optimize_data.py +0 -0
  65. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/data_partition/split_train_test.py +0 -0
  66. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/eda/__init__.py +0 -0
  67. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/eda/bivariate_analysis.py +0 -0
  68. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/eda/feature_engineering.py +0 -0
  69. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/eda/first_glance.py +0 -0
  70. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/eda/univariate_analysis.py +0 -0
  71. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/eda/warnings/__init__.py +0 -0
  72. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/eda/warnings/automated_warnings.py +0 -0
  73. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/eda/warnings/default_warnings.py +0 -0
  74. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_reduction/__init__.py +0 -0
  75. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_reduction/base.py +0 -0
  76. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_reduction/correlation.py +0 -0
  77. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_reduction/drift.py +0 -0
  78. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_reduction/expert_rules.py +0 -0
  79. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_reduction/low_variance.py +0 -0
  80. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_reduction/predictive_power.py +0 -0
  81. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_reduction/reducer.py +0 -0
  82. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_selection/__init__.py +0 -0
  83. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_selection/base.py +0 -0
  84. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_selection/embedded_methods/__init__.py +0 -0
  85. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_selection/embedded_methods/elastic_net.py +0 -0
  86. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_selection/feature_stability.py +0 -0
  87. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_selection/meta_selector.py +0 -0
  88. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_selection/utils/__init__.py +0 -0
  89. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_selection/utils/data_handling.py +0 -0
  90. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_selection/utils/feature_type_constraints.py +0 -0
  91. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_selection/utils/plottings.py +0 -0
  92. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_selection/wrapper_methods/__init__.py +0 -0
  93. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_selection/wrapper_methods/bayesian_search.py +0 -0
  94. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_selection/wrapper_methods/boruta.py +0 -0
  95. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_selection/wrapper_methods/recursive_feature_eliminator.py +0 -0
  96. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_selection/wrapper_methods/rfe_catboost.py +0 -0
  97. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/feature_selection/wrapper_methods/sequential_selection.py +0 -0
  98. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/model_training/__init__.py +0 -0
  99. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/model_training/hyper_parameter_tuning/__init__.py +0 -0
  100. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/model_training/models/__init__.py +0 -0
  101. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/model_training/models/base.py +0 -0
  102. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/classifier_toolkit/model_training/utils/__init__.py +0 -0
  103. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/CNAME +0 -0
  104. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/data_partition/data_preprocess.md +0 -0
  105. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/data_partition/optimize_data.md +0 -0
  106. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/data_partition/overview.md +0 -0
  107. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/data_partition/split_train_test.md +0 -0
  108. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/eda/bivariate_analysis.md +0 -0
  109. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/eda/eda_toolkit.md +0 -0
  110. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/eda/feature_engineering.md +0 -0
  111. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/eda/first_glance.md +0 -0
  112. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/eda/overview.md +0 -0
  113. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/eda/univariate_analysis.md +0 -0
  114. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/eda/visualizations.md +0 -0
  115. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/eda/warnings/default_warnings.md +0 -0
  116. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/eda/warnings/warning_system.md +0 -0
  117. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/examples/eda_example.md +0 -0
  118. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/examples/feature_selection_advanced.md +0 -0
  119. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/examples/feature_selection_example.md +0 -0
  120. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/explainability/interactions.md +0 -0
  121. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/explainability/misclassification.md +0 -0
  122. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/explainability/overview.md +0 -0
  123. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/explainability/plots.md +0 -0
  124. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/explainability/toolkit.md +0 -0
  125. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/explainability/tree_explainer.md +0 -0
  126. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/feature_reduction/correlation.md +0 -0
  127. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/feature_reduction/counter_intuitive.md +0 -0
  128. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/feature_reduction/drift.md +0 -0
  129. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/feature_reduction/expert_rules.md +0 -0
  130. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/feature_reduction/low_variance.md +0 -0
  131. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/feature_reduction/overview.md +0 -0
  132. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/feature_reduction/predictive_power.md +0 -0
  133. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/feature_reduction/reducer.md +0 -0
  134. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/feature_selection/embedded_methods/elastic_net.md +0 -0
  135. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/feature_selection/feature_stability.md +0 -0
  136. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/feature_selection/meta_selector.md +0 -0
  137. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/feature_selection/overview.md +0 -0
  138. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/feature_selection/utils/data_handling.md +0 -0
  139. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/feature_selection/utils/scoring.md +0 -0
  140. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/feature_selection/wrapper_methods/bayesian_search.md +0 -0
  141. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/feature_selection/wrapper_methods/boruta.md +0 -0
  142. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/feature_selection/wrapper_methods/combination_search.md +0 -0
  143. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/feature_selection/wrapper_methods/recursive_feature_eliminator.md +0 -0
  144. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/feature_selection/wrapper_methods/rfe.md +0 -0
  145. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/feature_selection/wrapper_methods/sequential_selection.md +0 -0
  146. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/index.md +0 -0
  147. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/model_training/overview.md +0 -0
  148. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/model_training/tuner.md +0 -0
  149. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/data_partition/data_preprocess.md +0 -0
  150. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/data_partition/optimize_data.md +0 -0
  151. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/data_partition/overview.md +0 -0
  152. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/data_partition/split_train_test.md +0 -0
  153. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/eda/bivariate_analysis.md +0 -0
  154. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/eda/eda_toolkit.md +0 -0
  155. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/eda/feature_engineering.md +0 -0
  156. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/eda/first_glance.md +0 -0
  157. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/eda/overview.md +0 -0
  158. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/eda/univariate_analysis.md +0 -0
  159. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/eda/visualizations.md +0 -0
  160. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/eda/warnings/default_warnings.md +0 -0
  161. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/eda/warnings/warning_system.md +0 -0
  162. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/explainability/interactions.md +0 -0
  163. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/explainability/misclassification.md +0 -0
  164. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/explainability/overview.md +0 -0
  165. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/explainability/plots.md +0 -0
  166. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/explainability/toolkit.md +0 -0
  167. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/explainability/tree_explainer.md +0 -0
  168. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_reduction/base.md +0 -0
  169. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_reduction/correlation.md +0 -0
  170. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_reduction/counter_intuitive.md +0 -0
  171. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_reduction/drift.md +0 -0
  172. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_reduction/expert_rules.md +0 -0
  173. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_reduction/low_variance.md +0 -0
  174. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_reduction/overview.md +0 -0
  175. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_reduction/predictive_power.md +0 -0
  176. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_reduction/reducer.md +0 -0
  177. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_selection/base.md +0 -0
  178. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_selection/embedded_methods/elastic_net.md +0 -0
  179. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_selection/feature_stability.md +0 -0
  180. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_selection/meta_selector.md +0 -0
  181. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_selection/overview.md +0 -0
  182. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_selection/utils/data_handling.md +0 -0
  183. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_selection/utils/plottings.md +0 -0
  184. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_selection/utils/scoring.md +0 -0
  185. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_selection/wrapper_methods/bayesian_search.md +0 -0
  186. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_selection/wrapper_methods/boruta.md +0 -0
  187. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_selection/wrapper_methods/combination_search.md +0 -0
  188. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_selection/wrapper_methods/recursive_feature_eliminator.md +0 -0
  189. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_selection/wrapper_methods/rfe.md +0 -0
  190. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/feature_selection/wrapper_methods/sequential_selection.md +0 -0
  191. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/model_training/params.md +0 -0
  192. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/reference/tuner/tuner.md +0 -0
  193. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/docs/stylesheets/extra.css +0 -0
  194. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/examples/__init__.py +0 -0
  195. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/examples/example_bayesian_search.ipynb +0 -0
  196. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/examples/example_combination_feature_search.ipynb +0 -0
  197. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/examples/example_explainability_catboost.ipynb +0 -0
  198. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/examples/example_explainability_lgbm.ipynb +0 -0
  199. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/examples/example_feature_reduction.ipynb +0 -0
  200. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/examples/example_grid_search.ipynb +0 -0
  201. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/examples/example_model_training_catboost.ipynb +0 -0
  202. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/examples/example_model_training_lgbm.ipynb +0 -0
  203. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/examples/example_recursive_feature_eliminator.ipynb +0 -0
  204. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/examples/example_train_test_partition.ipynb +0 -0
  205. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/main.py +0 -0
  206. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/notebooks/paylater_removed.json +0 -0
  207. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/ruff.toml +0 -0
  208. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/__init__.py +0 -0
  209. {classifier_toolkit-0.3.5/tests/data_partition → classifier_toolkit-0.3.6/tests/calibration}/__init__.py +0 -0
  210. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/conftest.py +0 -0
  211. {classifier_toolkit-0.3.5/tests/eda → classifier_toolkit-0.3.6/tests/data_partition}/__init__.py +0 -0
  212. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/data_partition/test_data_preprocess.py +0 -0
  213. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/data_partition/test_optimize_data.py +0 -0
  214. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/data_partition/test_split_train_test.py +0 -0
  215. {classifier_toolkit-0.3.5/tests/explainability → classifier_toolkit-0.3.6/tests/eda}/__init__.py +0 -0
  216. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/eda/test_bivariate_analysis.py +0 -0
  217. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/eda/test_feature_engineering.py +0 -0
  218. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/eda/test_first_glance.py +0 -0
  219. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/eda/test_univariate_analysis.py +0 -0
  220. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/eda/test_warnings.py +0 -0
  221. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/explainability/test_catboost_e2e.py +0 -0
  222. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/explainability/test_misclassification.py +0 -0
  223. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/explainability/test_plots.py +0 -0
  224. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/explainability/test_smoke.py +0 -0
  225. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/explainability/test_toolkit.py +0 -0
  226. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/explainability/test_tree_explainer.py +0 -0
  227. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/feature_reduction/__init__.py +0 -0
  228. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/feature_reduction/test_correlation.py +0 -0
  229. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/feature_reduction/test_drift.py +0 -0
  230. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/feature_reduction/test_expert_rules.py +0 -0
  231. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/feature_reduction/test_low_variance.py +0 -0
  232. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/feature_reduction/test_predictive_power.py +0 -0
  233. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/feature_reduction/test_reducer.py +0 -0
  234. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/feature_reduction/test_smoke.py +0 -0
  235. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/feature_selection/__init__.py +0 -0
  236. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/feature_selection/test_bayesian_search.py +0 -0
  237. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/feature_selection/test_boruta.py +0 -0
  238. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/feature_selection/test_elastic_net.py +0 -0
  239. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/feature_selection/test_feature_stability.py +0 -0
  240. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/feature_selection/test_recursive_feature_eliminator.py +0 -0
  241. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/feature_selection/test_rfe_catboost.py +0 -0
  242. {classifier_toolkit-0.3.5 → classifier_toolkit-0.3.6}/tests/feature_selection/test_sequential_selection.py +0 -0
@@ -91,13 +91,27 @@ jobs:
91
91
  - name: Run linting
92
92
  run: uv run make lint
93
93
 
94
+ discover-test-groups:
95
+ runs-on: default
96
+ outputs:
97
+ test-groups: ${{ steps.list.outputs.test-groups }}
98
+ steps:
99
+ - uses: actions/checkout@v6
100
+
101
+ - name: List test groups
102
+ id: list
103
+ run: |
104
+ groups=$(find tests -mindepth 1 -maxdepth 1 -type d ! -name '__*' ! -name '.*' -exec basename {} \; | sort | sed 's/.*/"&"/' | paste -sd, -)
105
+ echo "test-groups=[${groups}]" >> "$GITHUB_OUTPUT"
106
+ echo "Test groups: [${groups}]"
107
+
94
108
  test:
95
- needs: dependencies
109
+ needs: [dependencies, discover-test-groups]
96
110
  runs-on: default
97
111
  strategy:
98
112
  fail-fast: false
99
113
  matrix:
100
- test-group: [eda, feature_selection, feature_reduction, data_partition]
114
+ test-group: ${{ fromJSON(needs.discover-test-groups.outputs.test-groups) }}
101
115
  steps:
102
116
  - uses: actions/checkout@v6
103
117
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: classifier-toolkit
3
- Version: 0.3.5
3
+ Version: 0.3.6
4
4
  Project-URL: Documentation, https://supreme-adventure-jg5qkyr.pages.github.io/
5
5
  Author-email: "senih.yilmaz" <senih.yilmaz@qonto.com>, "jeremy.fraoua" <jeremy.fraoua@qonto.com>, "gauthier.marquand" <gauthier.marquand@qonto.com>, "arnaud.alepee" <arnaud.alepee@qonto.com>
6
6
  License-File: LICENSE
@@ -0,0 +1,34 @@
1
+ """Probability calibration for multiclass (and binary) model output.
2
+
3
+ Public API for the OVR histogram-binning calibrator and its reliability
4
+ curve diagnostics — see :mod:`classifier_toolkit.calibration.ovr_calibration`
5
+ for details.
6
+ """
7
+
8
+ import logging
9
+ from importlib import import_module
10
+ from typing import Any
11
+
12
+ logging.getLogger("classifier_toolkit.calibration").addHandler(logging.NullHandler())
13
+
14
+ _EXPORTS: dict[str, str] = {
15
+ "CalibrationError": "classifier_toolkit.calibration.base",
16
+ "OVRHistogramCalibrator": "classifier_toolkit.calibration.ovr_calibration",
17
+ "plot_reliability_curves": "classifier_toolkit.calibration.reliability",
18
+ }
19
+
20
+ __all__ = list(_EXPORTS.keys())
21
+
22
+
23
+ def __getattr__(name: str) -> Any: # pragma: no cover
24
+ module_path = _EXPORTS.get(name)
25
+ if module_path is None:
26
+ raise AttributeError(
27
+ f"module 'classifier_toolkit.calibration' has no attribute '{name}'"
28
+ )
29
+ module = import_module(module_path)
30
+ return getattr(module, name)
31
+
32
+
33
+ def __dir__(): # pragma: no cover
34
+ return sorted(list(globals().keys()) + __all__)
@@ -0,0 +1,5 @@
1
+ """Shared exception for the calibration package."""
2
+
3
+
4
+ class CalibrationError(Exception):
5
+ """Base exception for calibration errors."""
@@ -0,0 +1,254 @@
1
+ """One-vs-Rest histogram-binning calibration for multiclass probabilities.
2
+
3
+ Raw CatBoost/LightGBM scores are not guaranteed to be calibrated, which
4
+ matters whenever predicted probabilities are used as probabilities (pricing,
5
+ provisioning, or combining several models' outputs). This module calibrates
6
+ each class independently via histogram binning, then renormalizes the
7
+ calibrated row back to sum to 1.
8
+
9
+ It calibrates the output of a *single* model across the classes it predicts.
10
+ """
11
+
12
+ import warnings
13
+ from typing import Dict, Optional, Sequence, Union
14
+
15
+ import numpy as np
16
+
17
+ from classifier_toolkit.calibration.base import CalibrationError
18
+
19
+ ClassLabel = Union[str, int]
20
+
21
+
22
+ class OVRHistogramCalibrator:
23
+ """Calibrate multiclass probabilities via One-vs-Rest histogram binning.
24
+
25
+ For each class independently: bin the raw predicted probability into
26
+ ``n_bins`` quantile-width bins, and replace it with the empirical class
27
+ frequency observed in that bin at fit time (histogram/binning
28
+ calibration — a non-parametric alternative to isotonic regression or
29
+ Platt scaling). Because each class is calibrated independently, the
30
+ calibrated row no longer sums to 1 — :meth:`transform` renormalizes it.
31
+
32
+ Sparse cells (e.g. very few observed events of a rare class in a given
33
+ probability bin) are shrunk toward that class's overall prevalence in
34
+ proportion to how little data the bin has, rather than reported as a
35
+ noisy raw frequency — see ``min_samples_per_bin``.
36
+
37
+ Parameters
38
+ ----------
39
+ n_bins : int, optional
40
+ Target number of quantile bins per class, by default 10. When many
41
+ scores are tied (common for a rare class, e.g. most D scores at the
42
+ same low value), plain quantile edges collapse; each heavily tied
43
+ value then gets its own bin and the remaining bins are spread over
44
+ the untied scores. If fewer than 3 bins can still be formed (the
45
+ scores take very few distinct values), a warning is raised, since
46
+ the calibrated output for that class is then nearly constant.
47
+ min_samples_per_bin : int, optional
48
+ Minimum training samples a bin must contain before its empirical
49
+ frequency is trusted as-is; bins with fewer samples are shrunk
50
+ toward the class's overall prevalence in proportion to
51
+ ``n_in_bin / min_samples_per_bin``. By default 20.
52
+
53
+ Attributes
54
+ ----------
55
+ classes_ : Optional[np.ndarray]
56
+ Class labels, in the order matching probability columns. Set by fit.
57
+ bin_edges_ : Dict[ClassLabel, np.ndarray]
58
+ Per-class quantile bin edges from fit (outer edges are +/-inf so
59
+ every future probability falls inside some bin).
60
+ bin_values_ : Dict[ClassLabel, np.ndarray]
61
+ Per-class calibrated (possibly shrunk) frequency for each bin.
62
+ class_prior_ : Dict[ClassLabel, float]
63
+ Per-class overall prevalence at fit time, used for shrinkage.
64
+ """
65
+
66
+ def __init__(self, n_bins: int = 10, min_samples_per_bin: int = 20) -> None:
67
+ self.n_bins = n_bins
68
+ self.min_samples_per_bin = min_samples_per_bin
69
+ self.classes_: Optional[np.ndarray] = None
70
+ self.bin_edges_: Dict[ClassLabel, np.ndarray] = {}
71
+ self.bin_values_: Dict[ClassLabel, np.ndarray] = {}
72
+ self.class_prior_: Dict[ClassLabel, float] = {}
73
+
74
+ def _quantile_edges(self, p: np.ndarray) -> np.ndarray:
75
+ quantiles = np.linspace(0.0, 1.0, self.n_bins + 1)
76
+ edges = np.unique(np.quantile(p, quantiles))
77
+ if len(edges) - 1 < self.n_bins:
78
+ edges = self._tie_aware_edges(p)
79
+ if len(edges) < 2:
80
+ edges = np.array([0.0, 1.0])
81
+ edges = edges.astype(float)
82
+ edges[0] = -np.inf
83
+ edges[-1] = np.inf
84
+ return edges
85
+
86
+ def _tie_aware_edges(self, p: np.ndarray) -> np.ndarray:
87
+ """Quantile edges that give each heavily tied score its own bin.
88
+
89
+ A value is "heavily tied" when it holds more than ``1 / n_bins`` of
90
+ the samples, i.e. more than one quantile bin's worth. Such a value
91
+ collapses neighbouring quantile edges onto itself, so it is isolated
92
+ in its own bin (``[v, next float after v)``) and the rest of the bin
93
+ budget is spent on quantiles of the other scores.
94
+ """
95
+ values, counts = np.unique(p, return_counts=True)
96
+ spikes = values[counts > len(p) / self.n_bins]
97
+ rest = p[~np.isin(p, spikes)]
98
+ n_rest_bins = max(self.n_bins - len(spikes), 1)
99
+ edges = list(spikes) + [np.nextafter(v, np.inf) for v in spikes]
100
+ if rest.size:
101
+ edges += list(np.quantile(rest, np.linspace(0.0, 1.0, n_rest_bins + 1)))
102
+ return np.unique(np.asarray(edges, dtype=float))
103
+
104
+ @staticmethod
105
+ def _bin_index(p: np.ndarray, edges: np.ndarray) -> np.ndarray:
106
+ return np.clip(np.digitize(p, edges[1:-1], right=False), 0, len(edges) - 2)
107
+
108
+ def fit(
109
+ self,
110
+ y_true: Union[Sequence, np.ndarray],
111
+ y_proba: np.ndarray,
112
+ classes: Optional[Sequence[ClassLabel]] = None,
113
+ ) -> "OVRHistogramCalibrator":
114
+ """Fit per-class histogram bins from raw predictions.
115
+
116
+ Parameters
117
+ ----------
118
+ y_true : array-like of shape (n_samples,)
119
+ True class labels.
120
+ y_proba : np.ndarray of shape (n_samples, n_classes)
121
+ Raw (uncalibrated) predicted probabilities, e.g. from
122
+ ``model.predict_proba(X)``.
123
+ classes : Sequence[ClassLabel], optional
124
+ Class labels in the order matching ``y_proba``'s columns
125
+ (typically ``model.classes_``). If None, inferred as the sorted
126
+ unique values of ``y_true`` — only safe if every class appears
127
+ in ``y_true`` and ``y_proba``'s columns are already in that
128
+ sorted order.
129
+
130
+ Returns
131
+ -------
132
+ OVRHistogramCalibrator
133
+ The fitted calibrator.
134
+ """
135
+ y_true = np.asarray(y_true)
136
+ y_proba = self._check_proba(y_proba)
137
+ if classes is None:
138
+ classes = np.unique(y_true)
139
+ classes = np.asarray(classes)
140
+ if y_proba.shape[1] != len(classes):
141
+ raise CalibrationError(
142
+ f"y_proba has {y_proba.shape[1]} columns but {len(classes)} "
143
+ "classes were given."
144
+ )
145
+ if y_proba.shape[0] != len(y_true):
146
+ raise CalibrationError(
147
+ f"y_proba has {y_proba.shape[0]} rows but y_true has {len(y_true)}."
148
+ )
149
+
150
+ self.classes_ = classes
151
+ self.bin_edges_ = {}
152
+ self.bin_values_ = {}
153
+ self.class_prior_ = {}
154
+
155
+ for i, c in enumerate(classes):
156
+ y_bin = (y_true == c).astype(int)
157
+ p = y_proba[:, i]
158
+ prior = float(y_bin.mean()) if len(y_bin) > 0 else 0.0
159
+ self.class_prior_[c] = prior
160
+
161
+ edges = self._quantile_edges(p)
162
+ bin_idx = self._bin_index(p, edges)
163
+ n_populated = len(np.unique(bin_idx))
164
+ if n_populated < min(self.n_bins, 3):
165
+ warnings.warn(
166
+ f"Class {c!r}: only {n_populated} calibration bin(s) could "
167
+ f"be formed (n_bins={self.n_bins}) because its scores take "
168
+ "very few distinct values; its calibrated probability will "
169
+ "be nearly constant.",
170
+ stacklevel=2,
171
+ )
172
+
173
+ values = np.empty(len(edges) - 1, dtype=float)
174
+ for b in range(len(edges) - 1):
175
+ mask = bin_idx == b
176
+ n_in_bin = int(mask.sum())
177
+ if n_in_bin == 0:
178
+ values[b] = prior
179
+ continue
180
+ observed = float(y_bin[mask].mean())
181
+ if n_in_bin < self.min_samples_per_bin:
182
+ weight = n_in_bin / self.min_samples_per_bin
183
+ values[b] = weight * observed + (1 - weight) * prior
184
+ else:
185
+ values[b] = observed
186
+ self.bin_edges_[c] = edges
187
+ self.bin_values_[c] = values
188
+
189
+ return self
190
+
191
+ def transform(self, y_proba: np.ndarray) -> np.ndarray:
192
+ """Calibrate raw probabilities and renormalize to sum to 1.
193
+
194
+ Parameters
195
+ ----------
196
+ y_proba : np.ndarray of shape (n_samples, n_classes)
197
+ Raw predicted probabilities, columns matching ``classes_``.
198
+
199
+ Returns
200
+ -------
201
+ np.ndarray of shape (n_samples, n_classes)
202
+ Calibrated probabilities; each row sums to 1. A row whose
203
+ calibrated values are all exactly 0 (every relevant bin observed
204
+ no events) carries no information, so it falls back to the
205
+ class priors from fit.
206
+ """
207
+ if self.classes_ is None:
208
+ raise CalibrationError("Calibrator is not fitted. Call fit() first.")
209
+ y_proba = self._check_proba(y_proba)
210
+ if y_proba.shape[1] != len(self.classes_):
211
+ raise CalibrationError(
212
+ f"y_proba has {y_proba.shape[1]} columns but the calibrator "
213
+ f"was fit on {len(self.classes_)} classes."
214
+ )
215
+
216
+ calibrated = np.empty_like(y_proba)
217
+ for i, c in enumerate(self.classes_):
218
+ edges = self.bin_edges_[c]
219
+ values = self.bin_values_[c]
220
+ bin_idx = self._bin_index(y_proba[:, i], edges)
221
+ calibrated[:, i] = values[bin_idx]
222
+
223
+ row_sums = calibrated.sum(axis=1, keepdims=True)
224
+ empty_rows = row_sums[:, 0] == 0
225
+ if empty_rows.any():
226
+ priors = np.array([self.class_prior_[c] for c in self.classes_])
227
+ if priors.sum() == 0:
228
+ priors = np.ones(len(self.classes_))
229
+ calibrated[empty_rows] = priors
230
+ row_sums = calibrated.sum(axis=1, keepdims=True)
231
+ return calibrated / row_sums
232
+
233
+ @staticmethod
234
+ def _check_proba(y_proba: np.ndarray) -> np.ndarray:
235
+ y_proba = np.asarray(y_proba, dtype=float)
236
+ if y_proba.ndim != 2:
237
+ raise CalibrationError(
238
+ f"y_proba must be 2D (n_samples, n_classes); got shape {y_proba.shape}."
239
+ )
240
+ if np.isnan(y_proba).any():
241
+ raise CalibrationError(
242
+ f"y_proba contains {int(np.isnan(y_proba).sum())} NaN value(s); "
243
+ "calibration needs a probability for every sample and class."
244
+ )
245
+ return y_proba
246
+
247
+ def fit_transform(
248
+ self,
249
+ y_true: Union[Sequence, np.ndarray],
250
+ y_proba: np.ndarray,
251
+ classes: Optional[Sequence[ClassLabel]] = None,
252
+ ) -> np.ndarray:
253
+ """Fit the calibrator and calibrate the same data in one step."""
254
+ return self.fit(y_true, y_proba, classes=classes).transform(y_proba)
@@ -0,0 +1,109 @@
1
+ """Reliability curve diagnostics for OVR calibration.
2
+
3
+ One reliability (calibration) curve per class, each an
4
+ independent binary "class *c* vs rest" diagnostic — matching the OVR
5
+ calibration approach itself. Plots raw and (optionally) calibrated curves
6
+ together so the effect of calibration is visible directly.
7
+ """
8
+
9
+ import math
10
+ from typing import Optional, Sequence, Union
11
+
12
+ import matplotlib.pyplot as plt
13
+ import numpy as np
14
+ from sklearn.calibration import calibration_curve
15
+
16
+ ClassLabel = Union[str, int]
17
+
18
+
19
+ def plot_reliability_curves(
20
+ y_true: Union[Sequence, np.ndarray],
21
+ y_proba_raw: np.ndarray,
22
+ y_proba_calibrated: Optional[np.ndarray] = None,
23
+ classes: Optional[Sequence[ClassLabel]] = None,
24
+ n_bins: int = 10,
25
+ pos_label: Optional[ClassLabel] = None,
26
+ n_cols: int = 3,
27
+ show: bool = True,
28
+ ) -> plt.Figure:
29
+ """Plot a reliability curve per class, one subplot each.
30
+
31
+ Parameters
32
+ ----------
33
+ y_true : array-like of shape (n_samples,)
34
+ True class labels.
35
+ y_proba_raw : np.ndarray of shape (n_samples, n_classes)
36
+ Raw (uncalibrated) predicted probabilities.
37
+ y_proba_calibrated : np.ndarray of shape (n_samples, n_classes), optional
38
+ Calibrated predicted probabilities (e.g. from
39
+ :meth:`OVRHistogramCalibrator.transform`), plotted alongside the raw
40
+ curve for comparison. If None, only the raw curve is shown.
41
+ classes : Sequence[ClassLabel], optional
42
+ Class labels in the order matching the probability columns. If
43
+ None, inferred as the sorted unique values of ``y_true``.
44
+ n_bins : int, optional
45
+ Number of quantile bins per curve, by default 10.
46
+ pos_label : ClassLabel, optional
47
+ A class of interest (e.g. the default class). If given and present
48
+ in ``classes``, that subplot's title is bolded in red to keep it
49
+ visually prominent, consistent with the rest of the multiclass
50
+ toolkit. By default None.
51
+ n_cols : int, optional
52
+ Subplot grid columns, by default 3.
53
+ show : bool, optional
54
+ Whether to call ``plt.show()``, by default True.
55
+
56
+ Returns
57
+ -------
58
+ matplotlib.figure.Figure
59
+ """
60
+ y_true = np.asarray(y_true)
61
+ y_proba_raw = np.asarray(y_proba_raw)
62
+ if classes is None:
63
+ classes = np.unique(y_true)
64
+ classes = list(classes)
65
+ n_classes = len(classes)
66
+
67
+ n_cols = min(n_cols, n_classes)
68
+ n_rows = math.ceil(n_classes / n_cols)
69
+ fig, axes = plt.subplots(
70
+ n_rows, n_cols, figsize=(5 * n_cols, 4 * n_rows), squeeze=False
71
+ )
72
+ axes_flat = axes.flatten()
73
+
74
+ for i, c in enumerate(classes):
75
+ ax = axes_flat[i]
76
+ y_bin = (y_true == c).astype(int)
77
+
78
+ frac_pos, mean_pred = calibration_curve(
79
+ y_bin, y_proba_raw[:, i], n_bins=n_bins, strategy="quantile"
80
+ )
81
+ ax.plot(mean_pred, frac_pos, marker="o", label="Raw")
82
+
83
+ if y_proba_calibrated is not None:
84
+ frac_pos_cal, mean_pred_cal = calibration_curve(
85
+ y_bin,
86
+ np.asarray(y_proba_calibrated)[:, i],
87
+ n_bins=n_bins,
88
+ strategy="quantile",
89
+ )
90
+ ax.plot(mean_pred_cal, frac_pos_cal, marker="s", label="Calibrated")
91
+
92
+ ax.plot([0, 1], [0, 1], linestyle="--", color="gray", label="Perfect")
93
+ ax.set_xlabel("Mean predicted probability")
94
+ ax.set_ylabel("Observed frequency")
95
+ title = f"Class {c}"
96
+ if pos_label is not None and c == pos_label:
97
+ ax.set_title(title, fontweight="bold", color="red")
98
+ else:
99
+ ax.set_title(title)
100
+ ax.legend(fontsize=8)
101
+
102
+ for i in range(n_classes, n_rows * n_cols):
103
+ axes_flat[i].set_visible(False)
104
+
105
+ fig.suptitle("Reliability Curves (One-vs-Rest per class)", fontsize=14, y=1.02)
106
+ plt.tight_layout()
107
+ if show:
108
+ plt.show()
109
+ return fig
@@ -49,6 +49,7 @@ class EDAToolkit:
49
49
  id_column: Optional[str] = None,
50
50
  to_be_enc: Optional[List[str]] = None,
51
51
  warning_system: Optional[WarningSystem] = None,
52
+ pos_label: Optional[Union[str, int]] = None,
52
53
  ) -> None:
53
54
  """
54
55
  Initialize the EDAToolkit class with data and configuration settings.
@@ -73,6 +74,10 @@ class EDAToolkit:
73
74
  List of columns to be encoded, by default None.
74
75
  warning_system : Optional[WarningSystem], optional
75
76
  The warning system to use, by default None.
77
+ pos_label : Union[str, int], optional
78
+ The target class of interest (e.g. the default class). Forwarded
79
+ to :class:`Visualizations` to highlight/select that class in the
80
+ per-class EDA views. By default None.
76
81
  """
77
82
  self.dataframe = dataframe
78
83
  self.target_column = target_column or ""
@@ -114,6 +119,7 @@ class EDAToolkit:
114
119
  self.target_column,
115
120
  self.numerical_columns,
116
121
  self.categorical_columns,
122
+ pos_label=pos_label,
117
123
  )
118
124
  self.univariate_analysis = UnivariateAnalysis(
119
125
  self.dataframe, self.target_column, self.numerical_columns