validmind 2.13.7__tar.gz → 2.13.8__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 (378) hide show
  1. {validmind-2.13.7 → validmind-2.13.8}/PKG-INFO +1 -1
  2. {validmind-2.13.7 → validmind-2.13.8}/pyproject.toml +1 -1
  3. validmind-2.13.8/validmind/__version__.py +1 -0
  4. {validmind-2.13.7 → validmind-2.13.8}/validmind/api_client.py +2 -2
  5. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/PopulationStabilityIndex.py +31 -46
  6. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/PrecisionRecallCurve.py +18 -40
  7. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/ROCCurve.py +18 -41
  8. validmind-2.13.8/validmind/tests/model_validation/sklearn/_multiclass_proba.py +150 -0
  9. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/statsmodels/GINITable.py +19 -41
  10. validmind-2.13.7/validmind/__version__.py +0 -1
  11. {validmind-2.13.7 → validmind-2.13.8}/.gitignore +0 -0
  12. {validmind-2.13.7 → validmind-2.13.8}/LICENSE +0 -0
  13. {validmind-2.13.7 → validmind-2.13.8}/README.pypi.md +0 -0
  14. {validmind-2.13.7 → validmind-2.13.8}/validmind/__init__.py +0 -0
  15. {validmind-2.13.7 → validmind-2.13.8}/validmind/ai/test_descriptions.py +0 -0
  16. {validmind-2.13.7 → validmind-2.13.8}/validmind/ai/utils.py +0 -0
  17. {validmind-2.13.7 → validmind-2.13.8}/validmind/client.py +0 -0
  18. {validmind-2.13.7 → validmind-2.13.8}/validmind/client_config.py +0 -0
  19. {validmind-2.13.7 → validmind-2.13.8}/validmind/credentials_store.py +0 -0
  20. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/__init__.py +0 -0
  21. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/classification/__init__.py +0 -0
  22. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/classification/config.json +0 -0
  23. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/classification/customer_churn.py +0 -0
  24. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/classification/datasets/bank_customer_churn.csv +0 -0
  25. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/classification/datasets/taiwan_credit.csv +0 -0
  26. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/classification/taiwan_credit.py +0 -0
  27. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/cluster/digits.py +0 -0
  28. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/credit_risk/__init__.py +0 -0
  29. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/credit_risk/datasets/lending_club_biased.csv.gz +0 -0
  30. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/credit_risk/datasets/lending_club_loan_data_2007_2014_clean.csv.gz +0 -0
  31. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/credit_risk/lending_club.py +0 -0
  32. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/credit_risk/lending_club_bias.py +0 -0
  33. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/llm/__init__.py +0 -0
  34. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/llm/agent_dataset.py +0 -0
  35. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/llm/rag/__init__.py +0 -0
  36. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/llm/rag/datasets/rfp_existing_questions_client_1.csv +0 -0
  37. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/llm/rag/datasets/rfp_existing_questions_client_2.csv +0 -0
  38. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/llm/rag/datasets/rfp_existing_questions_client_3.csv +0 -0
  39. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/llm/rag/datasets/rfp_existing_questions_client_4.csv +0 -0
  40. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/llm/rag/datasets/rfp_existing_questions_client_5.csv +0 -0
  41. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/llm/rag/rfp.py +0 -0
  42. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/nlp/__init__.py +0 -0
  43. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/nlp/cnn_dailymail.py +0 -0
  44. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/nlp/datasets/Covid_19.csv +0 -0
  45. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/nlp/datasets/cnn_dailymail_100_with_predictions.csv +0 -0
  46. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/nlp/datasets/cnn_dailymail_500_with_predictions.csv +0 -0
  47. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/nlp/datasets/sentiments_with_predictions.csv +0 -0
  48. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/nlp/twitter_covid_19.py +0 -0
  49. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/__init__.py +0 -0
  50. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/california_housing.py +0 -0
  51. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/datasets/california_housing.csv +0 -0
  52. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/datasets/fred/CPIAUCSL.csv +0 -0
  53. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/datasets/fred/CSUSHPISA.csv +0 -0
  54. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/datasets/fred/DRSFRMACBS.csv +0 -0
  55. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/datasets/fred/FEDFUNDS.csv +0 -0
  56. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/datasets/fred/GDP.csv +0 -0
  57. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/datasets/fred/GDPC1.csv +0 -0
  58. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/datasets/fred/GS10.csv +0 -0
  59. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/datasets/fred/GS3.csv +0 -0
  60. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/datasets/fred/GS5.csv +0 -0
  61. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/datasets/fred/MORTGAGE30US.csv +0 -0
  62. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/datasets/fred/UNRATE.csv +0 -0
  63. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/datasets/fred_loan_rates.csv +0 -0
  64. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/datasets/fred_loan_rates_test_1.csv +0 -0
  65. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/datasets/fred_loan_rates_test_2.csv +0 -0
  66. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/datasets/fred_loan_rates_test_3.csv +0 -0
  67. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/datasets/fred_loan_rates_test_4.csv +0 -0
  68. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/datasets/fred_loan_rates_test_5.csv +0 -0
  69. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/datasets/leanding_club_loan_rates.csv +0 -0
  70. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/fred.py +0 -0
  71. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/fred_timeseries.py +0 -0
  72. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/generate_california_housing_csv.py +0 -0
  73. {validmind-2.13.7 → validmind-2.13.8}/validmind/datasets/regression/lending_club.py +0 -0
  74. {validmind-2.13.7 → validmind-2.13.8}/validmind/errors.py +0 -0
  75. {validmind-2.13.7 → validmind-2.13.8}/validmind/experimental/__init__.py +0 -0
  76. {validmind-2.13.7 → validmind-2.13.8}/validmind/experimental/agents.py +0 -0
  77. {validmind-2.13.7 → validmind-2.13.8}/validmind/html_templates/__init__.py +0 -0
  78. {validmind-2.13.7 → validmind-2.13.8}/validmind/html_templates/content_blocks.py +0 -0
  79. {validmind-2.13.7 → validmind-2.13.8}/validmind/input_registry.py +0 -0
  80. {validmind-2.13.7 → validmind-2.13.8}/validmind/logging.py +0 -0
  81. {validmind-2.13.7 → validmind-2.13.8}/validmind/models/__init__.py +0 -0
  82. {validmind-2.13.7 → validmind-2.13.8}/validmind/models/foundation.py +0 -0
  83. {validmind-2.13.7 → validmind-2.13.8}/validmind/models/function.py +0 -0
  84. {validmind-2.13.7 → validmind-2.13.8}/validmind/models/huggingface.py +0 -0
  85. {validmind-2.13.7 → validmind-2.13.8}/validmind/models/metadata.py +0 -0
  86. {validmind-2.13.7 → validmind-2.13.8}/validmind/models/pipeline.py +0 -0
  87. {validmind-2.13.7 → validmind-2.13.8}/validmind/models/pytorch.py +0 -0
  88. {validmind-2.13.7 → validmind-2.13.8}/validmind/models/r_model.py +0 -0
  89. {validmind-2.13.7 → validmind-2.13.8}/validmind/models/sklearn.py +0 -0
  90. {validmind-2.13.7 → validmind-2.13.8}/validmind/oidc_device.py +0 -0
  91. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/__init__.py +0 -0
  92. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/classification/AbsoluteError.py +0 -0
  93. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/classification/BrierScore.py +0 -0
  94. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/classification/CalibrationError.py +0 -0
  95. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/classification/ClassBalance.py +0 -0
  96. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/classification/Confidence.py +0 -0
  97. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/classification/Correctness.py +0 -0
  98. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/classification/LogLoss.py +0 -0
  99. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/classification/OutlierScore.py +0 -0
  100. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/classification/ProbabilityError.py +0 -0
  101. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/classification/Uncertainty.py +0 -0
  102. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/classification/__init__.py +0 -0
  103. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/llm/deepeval/AnswerRelevancy.py +0 -0
  104. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/llm/deepeval/ArgumentCorrectness.py +0 -0
  105. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/llm/deepeval/Bias.py +0 -0
  106. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/llm/deepeval/ContextualPrecision.py +0 -0
  107. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/llm/deepeval/ContextualRecall.py +0 -0
  108. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/llm/deepeval/ContextualRelevancy.py +0 -0
  109. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/llm/deepeval/Faithfulness.py +0 -0
  110. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/llm/deepeval/GEval.py +0 -0
  111. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/llm/deepeval/Hallucination.py +0 -0
  112. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/llm/deepeval/PlanAdherence.py +0 -0
  113. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/llm/deepeval/PlanQuality.py +0 -0
  114. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/llm/deepeval/Summarization.py +0 -0
  115. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/llm/deepeval/TaskCompletion.py +0 -0
  116. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/llm/deepeval/ToolCorrectness.py +0 -0
  117. {validmind-2.13.7 → validmind-2.13.8}/validmind/scorers/llm/deepeval/__init__.py +0 -0
  118. {validmind-2.13.7 → validmind-2.13.8}/validmind/template.py +0 -0
  119. {validmind-2.13.7 → validmind-2.13.8}/validmind/test_suites/__init__.py +0 -0
  120. {validmind-2.13.7 → validmind-2.13.8}/validmind/test_suites/classifier.py +0 -0
  121. {validmind-2.13.7 → validmind-2.13.8}/validmind/test_suites/cluster.py +0 -0
  122. {validmind-2.13.7 → validmind-2.13.8}/validmind/test_suites/embeddings.py +0 -0
  123. {validmind-2.13.7 → validmind-2.13.8}/validmind/test_suites/llm.py +0 -0
  124. {validmind-2.13.7 → validmind-2.13.8}/validmind/test_suites/nlp.py +0 -0
  125. {validmind-2.13.7 → validmind-2.13.8}/validmind/test_suites/parameters_optimization.py +0 -0
  126. {validmind-2.13.7 → validmind-2.13.8}/validmind/test_suites/regression.py +0 -0
  127. {validmind-2.13.7 → validmind-2.13.8}/validmind/test_suites/statsmodels_timeseries.py +0 -0
  128. {validmind-2.13.7 → validmind-2.13.8}/validmind/test_suites/summarization.py +0 -0
  129. {validmind-2.13.7 → validmind-2.13.8}/validmind/test_suites/tabular_datasets.py +0 -0
  130. {validmind-2.13.7 → validmind-2.13.8}/validmind/test_suites/text_data.py +0 -0
  131. {validmind-2.13.7 → validmind-2.13.8}/validmind/test_suites/time_series.py +0 -0
  132. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/__init__.py +0 -0
  133. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/__types__.py +0 -0
  134. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/_store.py +0 -0
  135. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/comparison.py +0 -0
  136. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/ACFandPACFPlot.py +0 -0
  137. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/ADF.py +0 -0
  138. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/AutoAR.py +0 -0
  139. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/AutoMA.py +0 -0
  140. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/AutoStationarity.py +0 -0
  141. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/BivariateScatterPlots.py +0 -0
  142. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/BoxPierce.py +0 -0
  143. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/ChiSquaredFeaturesTable.py +0 -0
  144. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/ClassImbalance.py +0 -0
  145. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/DatasetDescription.py +0 -0
  146. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/DatasetSplit.py +0 -0
  147. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/DescriptiveStatistics.py +0 -0
  148. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/DickeyFullerGLS.py +0 -0
  149. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/Duplicates.py +0 -0
  150. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/EngleGrangerCoint.py +0 -0
  151. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/FeatureTargetCorrelationPlot.py +0 -0
  152. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/HighCardinality.py +0 -0
  153. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/HighPearsonCorrelation.py +0 -0
  154. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/IQROutliersBarPlot.py +0 -0
  155. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/IQROutliersTable.py +0 -0
  156. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/IsolationForestOutliers.py +0 -0
  157. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/JarqueBera.py +0 -0
  158. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/KPSS.py +0 -0
  159. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/LJungBox.py +0 -0
  160. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/LaggedCorrelationHeatmap.py +0 -0
  161. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/MissingValues.py +0 -0
  162. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/MissingValuesBarPlot.py +0 -0
  163. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/MutualInformation.py +0 -0
  164. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/PearsonCorrelationMatrix.py +0 -0
  165. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/PhillipsPerronArch.py +0 -0
  166. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/ProtectedClassesCombination.py +0 -0
  167. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/ProtectedClassesDescription.py +0 -0
  168. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/ProtectedClassesDisparity.py +0 -0
  169. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/ProtectedClassesThresholdOptimizer.py +0 -0
  170. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/RollingStatsPlot.py +0 -0
  171. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/RunsTest.py +0 -0
  172. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/ScatterPlot.py +0 -0
  173. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/ScoreBandDefaultRates.py +0 -0
  174. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/SeasonalDecompose.py +0 -0
  175. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/ShapiroWilk.py +0 -0
  176. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/Skewness.py +0 -0
  177. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/SpreadPlot.py +0 -0
  178. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/TabularCategoricalBarPlots.py +0 -0
  179. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/TabularDateTimeHistograms.py +0 -0
  180. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/TabularDescriptionTables.py +0 -0
  181. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/TabularNumericalHistograms.py +0 -0
  182. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/TargetRateBarPlots.py +0 -0
  183. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/TimeSeriesDescription.py +0 -0
  184. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/TimeSeriesDescriptiveStatistics.py +0 -0
  185. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/TimeSeriesFrequency.py +0 -0
  186. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/TimeSeriesHistogram.py +0 -0
  187. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/TimeSeriesLinePlot.py +0 -0
  188. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/TimeSeriesMissingValues.py +0 -0
  189. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/TimeSeriesOutliers.py +0 -0
  190. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/TooManyZeroValues.py +0 -0
  191. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/UniqueRows.py +0 -0
  192. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/WOEBinPlots.py +0 -0
  193. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/WOEBinTable.py +0 -0
  194. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/ZivotAndrewsArch.py +0 -0
  195. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/__init__.py +0 -0
  196. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/nlp/CommonWords.py +0 -0
  197. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/nlp/Hashtags.py +0 -0
  198. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/nlp/LanguageDetection.py +0 -0
  199. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/nlp/Mentions.py +0 -0
  200. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/nlp/PolarityAndSubjectivity.py +0 -0
  201. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/nlp/Punctuations.py +0 -0
  202. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/nlp/Sentiment.py +0 -0
  203. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/nlp/StopWords.py +0 -0
  204. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/nlp/TextDescription.py +0 -0
  205. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/nlp/Toxicity.py +0 -0
  206. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/data_validation/nlp/__init__.py +0 -0
  207. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/decorator.py +0 -0
  208. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/load.py +0 -0
  209. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/BertScore.py +0 -0
  210. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/BleuScore.py +0 -0
  211. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/ClusterSizeDistribution.py +0 -0
  212. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/ContextualRecall.py +0 -0
  213. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/FeaturesAUC.py +0 -0
  214. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/MeteorScore.py +0 -0
  215. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/ModelMetadata.py +0 -0
  216. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/ModelPredictionResiduals.py +0 -0
  217. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/RegardScore.py +0 -0
  218. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/RegressionResidualsPlot.py +0 -0
  219. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/RougeScore.py +0 -0
  220. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/TimeSeriesPredictionWithCI.py +0 -0
  221. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/TimeSeriesPredictionsPlot.py +0 -0
  222. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/TimeSeriesR2SquareBySegments.py +0 -0
  223. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/TokenDisparity.py +0 -0
  224. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/ToxicityScore.py +0 -0
  225. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/__init__.py +0 -0
  226. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/embeddings/ClusterDistribution.py +0 -0
  227. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/embeddings/CosineSimilarityComparison.py +0 -0
  228. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/embeddings/CosineSimilarityDistribution.py +0 -0
  229. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/embeddings/CosineSimilarityHeatmap.py +0 -0
  230. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/embeddings/DescriptiveAnalytics.py +0 -0
  231. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/embeddings/EmbeddingsVisualization2D.py +0 -0
  232. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/embeddings/EuclideanDistanceComparison.py +0 -0
  233. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/embeddings/EuclideanDistanceHeatmap.py +0 -0
  234. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/embeddings/PCAComponentsPairwisePlots.py +0 -0
  235. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/embeddings/StabilityAnalysisKeyword.py +0 -0
  236. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/embeddings/StabilityAnalysisRandomNoise.py +0 -0
  237. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/embeddings/StabilityAnalysisSynonyms.py +0 -0
  238. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/embeddings/StabilityAnalysisTranslation.py +0 -0
  239. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/embeddings/TSNEComponentsPairwisePlots.py +0 -0
  240. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/embeddings/utils.py +0 -0
  241. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/ragas/AnswerCorrectness.py +0 -0
  242. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/ragas/AspectCritic.py +0 -0
  243. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/ragas/ContextEntityRecall.py +0 -0
  244. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/ragas/ContextPrecision.py +0 -0
  245. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/ragas/ContextPrecisionWithoutReference.py +0 -0
  246. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/ragas/ContextRecall.py +0 -0
  247. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/ragas/Faithfulness.py +0 -0
  248. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/ragas/NoiseSensitivity.py +0 -0
  249. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/ragas/ResponseRelevancy.py +0 -0
  250. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/ragas/SemanticSimilarity.py +0 -0
  251. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/ragas/utils.py +0 -0
  252. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/AdjustedMutualInformation.py +0 -0
  253. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/AdjustedRandIndex.py +0 -0
  254. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/CalibrationCurve.py +0 -0
  255. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/ClassifierPerformance.py +0 -0
  256. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/ClassifierThresholdOptimization.py +0 -0
  257. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/ClusterCosineSimilarity.py +0 -0
  258. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/ClusterPerformanceMetrics.py +0 -0
  259. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/CompletenessScore.py +0 -0
  260. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/ConfusionMatrix.py +0 -0
  261. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/FeatureImportance.py +0 -0
  262. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/FowlkesMallowsScore.py +0 -0
  263. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/HomogeneityScore.py +0 -0
  264. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/HyperParametersTuning.py +0 -0
  265. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/KMeansClustersOptimization.py +0 -0
  266. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/MinimumAccuracy.py +0 -0
  267. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/MinimumF1Score.py +0 -0
  268. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/MinimumROCAUCScore.py +0 -0
  269. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/ModelParameters.py +0 -0
  270. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/ModelsPerformanceComparison.py +0 -0
  271. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/OverfitDiagnosis.py +0 -0
  272. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/PermutationFeatureImportance.py +0 -0
  273. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/RegressionErrors.py +0 -0
  274. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/RegressionErrorsComparison.py +0 -0
  275. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/RegressionPerformance.py +0 -0
  276. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/RegressionR2Square.py +0 -0
  277. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/RegressionR2SquareComparison.py +0 -0
  278. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/RobustnessDiagnosis.py +0 -0
  279. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/SHAPGlobalImportance.py +0 -0
  280. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/ScoreProbabilityAlignment.py +0 -0
  281. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/SilhouettePlot.py +0 -0
  282. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/TrainingTestDegradation.py +0 -0
  283. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/VMeasure.py +0 -0
  284. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/WeakspotsDiagnosis.py +0 -0
  285. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/__init__.py +0 -0
  286. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/sklearn/_diagnosis_metrics.py +0 -0
  287. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/statsmodels/AutoARIMA.py +0 -0
  288. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/statsmodels/CumulativePredictionProbabilities.py +0 -0
  289. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/statsmodels/DurbinWatsonTest.py +0 -0
  290. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/statsmodels/KolmogorovSmirnov.py +0 -0
  291. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/statsmodels/Lilliefors.py +0 -0
  292. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/statsmodels/PredictionProbabilitiesHistogram.py +0 -0
  293. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/statsmodels/RegressionCoeffs.py +0 -0
  294. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/statsmodels/RegressionFeatureSignificance.py +0 -0
  295. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/statsmodels/RegressionModelForecastPlot.py +0 -0
  296. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/statsmodels/RegressionModelForecastPlotLevels.py +0 -0
  297. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/statsmodels/RegressionModelSensitivityPlot.py +0 -0
  298. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/statsmodels/RegressionModelSummary.py +0 -0
  299. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/statsmodels/RegressionPermutationFeatureImportance.py +0 -0
  300. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/statsmodels/ScorecardHistogram.py +0 -0
  301. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/statsmodels/__init__.py +0 -0
  302. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/model_validation/statsmodels/statsutils.py +0 -0
  303. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/ongoing_monitoring/CalibrationCurveDrift.py +0 -0
  304. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/ongoing_monitoring/ClassDiscriminationDrift.py +0 -0
  305. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/ongoing_monitoring/ClassImbalanceDrift.py +0 -0
  306. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/ongoing_monitoring/ClassificationAccuracyDrift.py +0 -0
  307. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/ongoing_monitoring/ConfusionMatrixDrift.py +0 -0
  308. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/ongoing_monitoring/CumulativePredictionProbabilitiesDrift.py +0 -0
  309. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/ongoing_monitoring/FeatureDrift.py +0 -0
  310. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/ongoing_monitoring/PredictionAcrossEachFeature.py +0 -0
  311. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/ongoing_monitoring/PredictionCorrelation.py +0 -0
  312. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/ongoing_monitoring/PredictionProbabilitiesHistogramDrift.py +0 -0
  313. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/ongoing_monitoring/PredictionQuantilesAcrossFeatures.py +0 -0
  314. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/ongoing_monitoring/ROCCurveDrift.py +0 -0
  315. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/ongoing_monitoring/ScoreBandsDrift.py +0 -0
  316. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/ongoing_monitoring/ScorecardHistogramDrift.py +0 -0
  317. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/ongoing_monitoring/TargetPredictionDistributionPlot.py +0 -0
  318. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/output.py +0 -0
  319. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/plots/BoxPlot.py +0 -0
  320. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/plots/CorrelationHeatmap.py +0 -0
  321. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/plots/HistogramPlot.py +0 -0
  322. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/plots/ViolinPlot.py +0 -0
  323. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/plots/__init__.py +0 -0
  324. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/prompt_validation/Bias.py +0 -0
  325. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/prompt_validation/Clarity.py +0 -0
  326. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/prompt_validation/Conciseness.py +0 -0
  327. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/prompt_validation/Delimitation.py +0 -0
  328. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/prompt_validation/NegativeInstruction.py +0 -0
  329. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/prompt_validation/Robustness.py +0 -0
  330. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/prompt_validation/Specificity.py +0 -0
  331. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/prompt_validation/__init__.py +0 -0
  332. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/prompt_validation/ai_powered_test.py +0 -0
  333. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/run.py +0 -0
  334. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/stats/CorrelationAnalysis.py +0 -0
  335. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/stats/DescriptiveStats.py +0 -0
  336. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/stats/NormalityTests.py +0 -0
  337. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/stats/OutlierDetection.py +0 -0
  338. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/stats/__init__.py +0 -0
  339. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/test_providers.py +0 -0
  340. {validmind-2.13.7 → validmind-2.13.8}/validmind/tests/utils.py +0 -0
  341. {validmind-2.13.7 → validmind-2.13.8}/validmind/unit_metrics/__init__.py +0 -0
  342. {validmind-2.13.7 → validmind-2.13.8}/validmind/unit_metrics/classification/Accuracy.py +0 -0
  343. {validmind-2.13.7 → validmind-2.13.8}/validmind/unit_metrics/classification/F1.py +0 -0
  344. {validmind-2.13.7 → validmind-2.13.8}/validmind/unit_metrics/classification/Precision.py +0 -0
  345. {validmind-2.13.7 → validmind-2.13.8}/validmind/unit_metrics/classification/ROC_AUC.py +0 -0
  346. {validmind-2.13.7 → validmind-2.13.8}/validmind/unit_metrics/classification/Recall.py +0 -0
  347. {validmind-2.13.7 → validmind-2.13.8}/validmind/unit_metrics/regression/AdjustedRSquaredScore.py +0 -0
  348. {validmind-2.13.7 → validmind-2.13.8}/validmind/unit_metrics/regression/GiniCoefficient.py +0 -0
  349. {validmind-2.13.7 → validmind-2.13.8}/validmind/unit_metrics/regression/HuberLoss.py +0 -0
  350. {validmind-2.13.7 → validmind-2.13.8}/validmind/unit_metrics/regression/KolmogorovSmirnovStatistic.py +0 -0
  351. {validmind-2.13.7 → validmind-2.13.8}/validmind/unit_metrics/regression/MeanAbsoluteError.py +0 -0
  352. {validmind-2.13.7 → validmind-2.13.8}/validmind/unit_metrics/regression/MeanAbsolutePercentageError.py +0 -0
  353. {validmind-2.13.7 → validmind-2.13.8}/validmind/unit_metrics/regression/MeanBiasDeviation.py +0 -0
  354. {validmind-2.13.7 → validmind-2.13.8}/validmind/unit_metrics/regression/MeanSquaredError.py +0 -0
  355. {validmind-2.13.7 → validmind-2.13.8}/validmind/unit_metrics/regression/QuantileLoss.py +0 -0
  356. {validmind-2.13.7 → validmind-2.13.8}/validmind/unit_metrics/regression/RSquaredScore.py +0 -0
  357. {validmind-2.13.7 → validmind-2.13.8}/validmind/unit_metrics/regression/RootMeanSquaredError.py +0 -0
  358. {validmind-2.13.7 → validmind-2.13.8}/validmind/utils.py +0 -0
  359. {validmind-2.13.7 → validmind-2.13.8}/validmind/vm_models/__init__.py +0 -0
  360. {validmind-2.13.7 → validmind-2.13.8}/validmind/vm_models/dataset/__init__.py +0 -0
  361. {validmind-2.13.7 → validmind-2.13.8}/validmind/vm_models/dataset/dataset.py +0 -0
  362. {validmind-2.13.7 → validmind-2.13.8}/validmind/vm_models/dataset/utils.py +0 -0
  363. {validmind-2.13.7 → validmind-2.13.8}/validmind/vm_models/figure.py +0 -0
  364. {validmind-2.13.7 → validmind-2.13.8}/validmind/vm_models/html_progress.py +0 -0
  365. {validmind-2.13.7 → validmind-2.13.8}/validmind/vm_models/html_renderer.py +0 -0
  366. {validmind-2.13.7 → validmind-2.13.8}/validmind/vm_models/input.py +0 -0
  367. {validmind-2.13.7 → validmind-2.13.8}/validmind/vm_models/model.py +0 -0
  368. {validmind-2.13.7 → validmind-2.13.8}/validmind/vm_models/result/__init__.py +0 -0
  369. {validmind-2.13.7 → validmind-2.13.8}/validmind/vm_models/result/pii_filter.py +0 -0
  370. {validmind-2.13.7 → validmind-2.13.8}/validmind/vm_models/result/result.jinja +0 -0
  371. {validmind-2.13.7 → validmind-2.13.8}/validmind/vm_models/result/result.py +0 -0
  372. {validmind-2.13.7 → validmind-2.13.8}/validmind/vm_models/result/utils.py +0 -0
  373. {validmind-2.13.7 → validmind-2.13.8}/validmind/vm_models/test_suite/__init__.py +0 -0
  374. {validmind-2.13.7 → validmind-2.13.8}/validmind/vm_models/test_suite/runner.py +0 -0
  375. {validmind-2.13.7 → validmind-2.13.8}/validmind/vm_models/test_suite/summary.py +0 -0
  376. {validmind-2.13.7 → validmind-2.13.8}/validmind/vm_models/test_suite/test.py +0 -0
  377. {validmind-2.13.7 → validmind-2.13.8}/validmind/vm_models/test_suite/test_suite.py +0 -0
  378. {validmind-2.13.7 → validmind-2.13.8}/validmind/vm_models/text_generation_summary.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: validmind
3
- Version: 2.13.7
3
+ Version: 2.13.8
4
4
  Summary: ValidMind Library
5
5
  Author-email: Andres Rodriguez <andres@validmind.ai>, Juan Martinez <juan@validmind.ai>, Anil Sorathiya <anil@validmind.ai>, Luis Pallares <luis@validmind.ai>, John Walz <john@validmind.ai>
6
6
  License: DUAL LICENSE NOTICE
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "validmind"
3
- version = "2.13.7"
3
+ version = "2.13.8"
4
4
  description = "ValidMind Library"
5
5
  readme = "README.pypi.md"
6
6
  requires-python = ">=3.9,<3.15"
@@ -0,0 +1 @@
1
+ __version__ = "2.13.8"
@@ -317,7 +317,7 @@ def init(
317
317
  Can be set via env ``VM_OIDC_ISSUER``.
318
318
  client_id (str, optional): OAuth public client id for device flow. Can be
319
319
  set via env ``VM_OIDC_CLIENT_ID``.
320
- scope (str, optional): OAuth scopes (default ``openid profile email``).
320
+ scope (str, optional): OAuth scopes (default ``openid profile email offline_access``).
321
321
  Can be set via env ``VM_OIDC_SCOPE``.
322
322
  audience (str, optional): Resource / API identifier for the access token
323
323
  (e.g. Auth0 API Identifier). Use the same value the ValidMind backend
@@ -392,7 +392,7 @@ def init(
392
392
  _api_key = None
393
393
  _api_secret = None
394
394
  _api_host = resolved_host
395
- scope_val = oidc_scope or "openid profile email"
395
+ scope_val = oidc_scope or "openid profile email offline_access"
396
396
  from .credentials_store import normalize_audience
397
397
 
398
398
  oidc_audience_val = normalize_audience(
@@ -14,6 +14,8 @@ from validmind.errors import SkipTestError
14
14
  from validmind.logging import get_logger
15
15
  from validmind.vm_models import VMDataset, VMModel
16
16
 
17
+ from ._multiclass_proba import multiclass_proba, proba_matrix
18
+
17
19
  logger = get_logger(__name__)
18
20
 
19
21
  _PSI_PALETTE = ["#DE257E", "#1F77B4", "#2CA02C", "#FF7F0E", "#9467BD", "#8C564B"]
@@ -104,54 +106,37 @@ def _psi_table_rows(psi_results):
104
106
  return rows_with_total, table_rows
105
107
 
106
108
 
107
- def _multiclass_psi(datasets, model, classes, num_bins, mode):
109
+ def _multiclass_psi(datasets, model, num_bins, mode):
108
110
  """One-vs-rest PSI for a multiclass model.
109
111
 
110
112
  PSI needs a 1-D score distribution to compare across the two datasets. The
111
- stored single probability column cannot represent every class, so we ask the
112
- underlying estimator for the full per-class probability matrix (mirroring the
113
- ROC/PR curve tests). Models without a usable ``predict_proba`` (metadata-only
114
- / precomputed single-column predictions) are skipped rather than crashed.
113
+ stored single probability column cannot represent every class, so the shared
114
+ helper reaches the underlying estimator for the full per-class probability
115
+ matrix (mirroring the ROC/PR curve tests), aligning columns to the training
116
+ class order. The initial dataset drives the class alignment and the set of
117
+ classes actually present; the new dataset's matrix is validated against the
118
+ same class list. Models that cannot supply a matching matrix are skipped.
115
119
  """
116
- raw_model = getattr(model, "model", None)
117
- proba_fn = getattr(raw_model, "predict_proba", None)
118
- if not callable(proba_fn):
119
- raise SkipTestError(
120
- "Multiclass Population Stability Index requires per-class "
121
- "probabilities from the underlying model's predict_proba, which is "
122
- "not available for this model (e.g. metadata-only / precomputed "
123
- "predictions). Skipping."
124
- )
125
- try:
126
- prob_initial = np.asarray(proba_fn(datasets[0].x_df()))
127
- prob_new = np.asarray(proba_fn(datasets[1].x_df()))
128
- except Exception as e:
129
- raise SkipTestError(
130
- "Multiclass Population Stability Index could not compute per-class "
131
- f"probabilities ({type(e).__name__}). Skipping."
132
- ) from e
133
-
134
- n_classes = len(classes)
135
- for prob in (prob_initial, prob_new):
136
- if prob.ndim != 2 or prob.shape[1] != n_classes:
137
- raise SkipTestError(
138
- "Multiclass Population Stability Index requires a per-class "
139
- f"probability matrix with one column per class (got shape "
140
- f"{getattr(prob, 'shape', None)} for {n_classes} classes). Skipping."
141
- )
142
-
143
- # predict_proba columns are ordered by sorted class label == np.unique.
120
+ aligned = multiclass_proba(model, datasets[0], "Population Stability Index")
121
+ prob_initial = aligned.y_prob
122
+ prob_new = proba_matrix(
123
+ model, datasets[1], aligned.class_list, "Population Stability Index"
124
+ )
125
+
126
+ classes_present = aligned.classes_present
127
+ n_present = len(classes_present)
128
+
144
129
  fig = make_subplots(
145
- rows=n_classes,
130
+ rows=n_present,
146
131
  cols=1,
147
- specs=[[{"secondary_y": True}] for _ in range(n_classes)],
148
- subplot_titles=[f"Class {cls}" for cls in classes],
132
+ specs=[[{"secondary_y": True}] for _ in range(n_present)],
133
+ subplot_titles=[f"Class {cls}" for cls in classes_present],
149
134
  vertical_spacing=0.08,
150
135
  )
151
136
 
152
137
  tables = {}
153
138
  raw_per_class = {}
154
- for i, cls in enumerate(classes):
139
+ for plot_i, (i, cls) in enumerate(zip(aligned.present_indices, classes_present)):
155
140
  psi_results = calculate_psi(
156
141
  prob_initial[:, i].copy(),
157
142
  prob_new[:, i].copy(),
@@ -159,17 +144,17 @@ def _multiclass_psi(datasets, model, classes, num_bins, mode):
159
144
  mode=mode,
160
145
  )
161
146
  x = list(range(len(psi_results)))
162
- color = _PSI_PALETTE[i % len(_PSI_PALETTE)]
147
+ color = _PSI_PALETTE[plot_i % len(_PSI_PALETTE)]
163
148
  fig.add_trace(
164
149
  go.Bar(
165
150
  x=x,
166
151
  y=[d["percent_initial"] for d in psi_results],
167
152
  name="Initial",
168
153
  marker=dict(color="#DE257E"),
169
- showlegend=i == 0,
154
+ showlegend=plot_i == 0,
170
155
  legendgroup="initial",
171
156
  ),
172
- row=i + 1,
157
+ row=plot_i + 1,
173
158
  col=1,
174
159
  secondary_y=False,
175
160
  )
@@ -179,10 +164,10 @@ def _multiclass_psi(datasets, model, classes, num_bins, mode):
179
164
  y=[d["percent_new"] for d in psi_results],
180
165
  name="New",
181
166
  marker=dict(color="#E8B1F8"),
182
- showlegend=i == 0,
167
+ showlegend=plot_i == 0,
183
168
  legendgroup="new",
184
169
  ),
185
- row=i + 1,
170
+ row=plot_i + 1,
186
171
  col=1,
187
172
  secondary_y=False,
188
173
  )
@@ -192,10 +177,10 @@ def _multiclass_psi(datasets, model, classes, num_bins, mode):
192
177
  y=[d["psi"] for d in psi_results],
193
178
  name="PSI",
194
179
  line=dict(color=color),
195
- showlegend=i == 0,
180
+ showlegend=plot_i == 0,
196
181
  legendgroup="psi",
197
182
  ),
198
- row=i + 1,
183
+ row=plot_i + 1,
199
184
  col=1,
200
185
  secondary_y=True,
201
186
  )
@@ -211,7 +196,7 @@ def _multiclass_psi(datasets, model, classes, num_bins, mode):
211
196
  fig.update_layout(
212
197
  title="Population Stability Index (PSI) — one-vs-rest per class",
213
198
  barmode="group",
214
- height=300 * n_classes,
199
+ height=300 * n_present,
215
200
  )
216
201
 
217
202
  return (
@@ -291,7 +276,7 @@ def PopulationStabilityIndex(
291
276
 
292
277
  classes = np.unique(datasets[0].y)
293
278
  if len(classes) > 2:
294
- return _multiclass_psi(datasets, model, classes, num_bins, mode)
279
+ return _multiclass_psi(datasets, model, num_bins, mode)
295
280
 
296
281
  psi_results = calculate_psi(
297
282
  datasets[0].y_prob(model).copy(),
@@ -7,13 +7,14 @@ from typing import Tuple
7
7
  import numpy as np
8
8
  import plotly.graph_objects as go
9
9
  from sklearn.metrics import average_precision_score, precision_recall_curve
10
- from sklearn.preprocessing import label_binarize
11
10
 
12
11
  from validmind import RawData, tags, tasks
13
12
  from validmind.errors import SkipTestError
14
13
  from validmind.models import FoundationModel
15
14
  from validmind.vm_models import VMDataset, VMModel
16
15
 
16
+ from ._multiclass_proba import multiclass_proba
17
+
17
18
 
18
19
  @tags(
19
20
  "sklearn",
@@ -75,7 +76,7 @@ def PrecisionRecallCurve(
75
76
  classes = np.unique(y_true)
76
77
 
77
78
  if len(classes) > 2:
78
- return _multiclass_pr_curve(model, dataset, classes)
79
+ return _multiclass_pr_curve(model, dataset)
79
80
 
80
81
  precision, recall, _ = precision_recall_curve(y_true, dataset.y_prob(model))
81
82
 
@@ -105,53 +106,27 @@ def PrecisionRecallCurve(
105
106
 
106
107
 
107
108
  def _multiclass_pr_curve(
108
- model: VMModel, dataset: VMDataset, classes: np.ndarray
109
+ model: VMModel, dataset: VMDataset
109
110
  ) -> Tuple[go.Figure, RawData]:
110
111
  """One-vs-rest precision-recall curves for a multiclass model.
111
112
 
112
113
  Needs the full per-class probability matrix, which the stored single
113
- probability column cannot provide, so we ask the model for it directly.
114
- Models without a usable ``predict_proba`` (Foundation/metadata-only,
115
- precomputed single-column probabilities) are skipped rather than crashed.
114
+ probability column cannot provide; the shared helper reaches the underlying
115
+ estimator, aligns the probability columns to the training class order and
116
+ skips models that cannot supply a matching matrix.
116
117
  """
117
- # The VMModel wrapper's predict_proba is binary-only (it returns just the
118
- # positive-class column), so reach the underlying estimator for the full
119
- # per-class probability matrix.
120
- raw_model = getattr(model, "model", None)
121
- proba_fn = getattr(raw_model, "predict_proba", None)
122
- if not callable(proba_fn):
123
- raise SkipTestError(
124
- "Multiclass Precision-Recall Curve requires per-class probabilities "
125
- "from the underlying model's predict_proba, which is not available "
126
- "for this model (e.g. Foundation / metadata-only / precomputed "
127
- "predictions). Skipping."
128
- )
129
- try:
130
- y_prob = np.asarray(proba_fn(dataset.x_df()))
131
- except Exception as e:
132
- raise SkipTestError(
133
- "Multiclass Precision-Recall Curve could not compute per-class "
134
- f"probabilities ({type(e).__name__}). Skipping."
135
- ) from e
136
-
137
- n_classes = len(classes)
138
- if y_prob.ndim != 2 or y_prob.shape[1] != n_classes:
139
- raise SkipTestError(
140
- "Multiclass Precision-Recall Curve requires a per-class probability "
141
- f"matrix with one column per class (got shape "
142
- f"{getattr(y_prob, 'shape', None)} for {n_classes} classes). Skipping."
143
- )
144
-
145
- # One-hot the true labels in the same class order predict_proba columns use
146
- # (sklearn orders predict_proba columns by sorted class label == np.unique).
147
- y_bin = label_binarize(dataset.y.flatten(), classes=classes)
118
+ aligned = multiclass_proba(model, dataset, "Precision-Recall Curve")
119
+ y_bin = aligned.y_bin
120
+ y_prob = aligned.y_prob
148
121
 
149
122
  traces = []
150
123
  raw_precision = {}
151
124
  raw_recall = {}
152
125
  raw_ap = {}
153
126
  palette = ["#DE257E", "#1F77B4", "#2CA02C", "#FF7F0E", "#9467BD", "#8C564B"]
154
- for i, cls in enumerate(classes):
127
+ for plot_i, (i, cls) in enumerate(
128
+ zip(aligned.present_indices, aligned.classes_present)
129
+ ):
155
130
  precision, recall, _ = precision_recall_curve(y_bin[:, i], y_prob[:, i])
156
131
  ap = average_precision_score(y_bin[:, i], y_prob[:, i])
157
132
  key = str(cls)
@@ -164,11 +139,14 @@ def _multiclass_pr_curve(
164
139
  y=precision,
165
140
  mode="lines",
166
141
  name=f"Class {key} (AP = {ap:.2f})",
167
- line=dict(color=palette[i % len(palette)]),
142
+ line=dict(color=palette[plot_i % len(palette)]),
168
143
  )
169
144
  )
170
145
 
171
- # Micro-average across all one-vs-rest decisions.
146
+ # Micro-average across the one-vs-rest decisions of the present classes.
147
+ present = aligned.present_indices
148
+ y_bin = y_bin[:, present]
149
+ y_prob = y_prob[:, present]
172
150
  micro_precision, micro_recall, _ = precision_recall_curve(
173
151
  y_bin.ravel(), y_prob.ravel()
174
152
  )
@@ -7,12 +7,12 @@ from typing import Tuple
7
7
  import numpy as np
8
8
  import plotly.graph_objects as go
9
9
  from sklearn.metrics import roc_auc_score, roc_curve
10
- from sklearn.preprocessing import label_binarize
11
10
 
12
11
  from validmind import RawData, tags, tasks
13
- from validmind.errors import SkipTestError
14
12
  from validmind.vm_models import VMDataset, VMModel
15
13
 
14
+ from ._multiclass_proba import multiclass_proba
15
+
16
16
 
17
17
  @tags(
18
18
  "sklearn",
@@ -76,7 +76,7 @@ def ROCCurve(model: VMModel, dataset: VMDataset) -> Tuple[go.Figure, RawData]:
76
76
  classes = np.unique(dataset.y)
77
77
 
78
78
  if len(classes) > 2:
79
- return _multiclass_roc_curve(model, dataset, classes)
79
+ return _multiclass_roc_curve(model, dataset)
80
80
 
81
81
  y_prob = dataset.y_prob(model)
82
82
  y_true = dataset.y.astype(y_prob.dtype).flatten()
@@ -117,53 +117,27 @@ def ROCCurve(model: VMModel, dataset: VMDataset) -> Tuple[go.Figure, RawData]:
117
117
 
118
118
 
119
119
  def _multiclass_roc_curve(
120
- model: VMModel, dataset: VMDataset, classes: np.ndarray
120
+ model: VMModel, dataset: VMDataset
121
121
  ) -> Tuple[go.Figure, RawData]:
122
122
  """One-vs-rest ROC curves for a multiclass model.
123
123
 
124
124
  Needs the full per-class probability matrix, which the stored single
125
- probability column cannot provide, so we ask the model for it directly.
126
- Models without a usable ``predict_proba`` (metadata-only, precomputed
127
- single-column probabilities) are skipped rather than crashed.
125
+ probability column cannot provide; the shared helper reaches the underlying
126
+ estimator, aligns the probability columns to the training class order and
127
+ skips models that cannot supply a matching matrix.
128
128
  """
129
- # The VMModel wrapper's predict_proba is binary-only (it returns just the
130
- # positive-class column), so reach the underlying estimator for the full
131
- # per-class probability matrix.
132
- raw_model = getattr(model, "model", None)
133
- proba_fn = getattr(raw_model, "predict_proba", None)
134
- if not callable(proba_fn):
135
- raise SkipTestError(
136
- "Multiclass ROC Curve requires per-class probabilities from the "
137
- "underlying model's predict_proba, which is not available for this "
138
- "model (e.g. metadata-only / precomputed predictions). Skipping."
139
- )
140
- try:
141
- y_prob = np.asarray(proba_fn(dataset.x_df()))
142
- except Exception as e:
143
- raise SkipTestError(
144
- "Multiclass ROC Curve could not compute per-class probabilities "
145
- f"({type(e).__name__}). Skipping."
146
- ) from e
147
-
148
- n_classes = len(classes)
149
- if y_prob.ndim != 2 or y_prob.shape[1] != n_classes:
150
- raise SkipTestError(
151
- "Multiclass ROC Curve requires a per-class probability matrix with "
152
- f"one column per class (got shape {getattr(y_prob, 'shape', None)} "
153
- f"for {n_classes} classes). Skipping."
154
- )
155
-
156
- # One-hot the true labels in the same class order predict_proba columns use
157
- # (sklearn orders predict_proba columns by sorted class label == np.unique).
158
- y_true = dataset.y.flatten()
159
- y_bin = label_binarize(y_true, classes=classes)
129
+ aligned = multiclass_proba(model, dataset, "ROC Curve")
130
+ y_bin = aligned.y_bin
131
+ y_prob = aligned.y_prob
160
132
 
161
133
  traces = []
162
134
  raw_fpr = {}
163
135
  raw_tpr = {}
164
136
  raw_auc = {}
165
137
  palette = ["#DE257E", "#1F77B4", "#2CA02C", "#FF7F0E", "#9467BD", "#8C564B"]
166
- for i, cls in enumerate(classes):
138
+ for plot_i, (i, cls) in enumerate(
139
+ zip(aligned.present_indices, aligned.classes_present)
140
+ ):
167
141
  fpr, tpr, _ = roc_curve(y_bin[:, i], y_prob[:, i], drop_intermediate=False)
168
142
  auc = roc_auc_score(y_bin[:, i], y_prob[:, i])
169
143
  key = str(cls)
@@ -176,11 +150,14 @@ def _multiclass_roc_curve(
176
150
  y=tpr,
177
151
  mode="lines",
178
152
  name=f"Class {key} (AUC = {auc:.2f})",
179
- line=dict(color=palette[i % len(palette)]),
153
+ line=dict(color=palette[plot_i % len(palette)]),
180
154
  )
181
155
  )
182
156
 
183
- # Micro-average across all one-vs-rest decisions.
157
+ # Micro-average across the one-vs-rest decisions of the present classes.
158
+ present = aligned.present_indices
159
+ y_bin = y_bin[:, present]
160
+ y_prob = y_prob[:, present]
184
161
  micro_fpr, micro_tpr, _ = roc_curve(y_bin.ravel(), y_prob.ravel())
185
162
  micro_auc = roc_auc_score(y_bin, y_prob, average="micro", multi_class="ovr")
186
163
  raw_fpr["micro"] = micro_fpr
@@ -0,0 +1,150 @@
1
+ # Copyright © 2023-2026 ValidMind Inc. All rights reserved.
2
+ # Refer to the LICENSE file in the root of this repository for details.
3
+ # SPDX-License-Identifier: AGPL-3.0 AND ValidMind Commercial
4
+
5
+ """Shared preamble for the one-vs-rest multiclass classification tests.
6
+
7
+ ROCCurve, PrecisionRecallCurve, PopulationStabilityIndex and GINITable all need
8
+ the full per-class probability matrix for a multiclass model. The VMModel wrapper
9
+ only stores/exposes the positive-class column, so every one of those tests reaches
10
+ the underlying estimator's ``predict_proba``, guards the cases where it is missing,
11
+ shaped wrong, trained on fewer than 3 classes, or evaluated against labels the
12
+ model never saw (raising ``SkipTestError`` with a test-specific message), and
13
+ one-hot encodes the true labels. This module holds that preamble in one place.
14
+
15
+ Column alignment matters: scikit-learn orders ``predict_proba`` columns by
16
+ ``estimator.classes_`` (the classes seen in training), which is not necessarily
17
+ ``np.unique(dataset.y)`` — a dataset slice can be missing a training class. We
18
+ align on ``classes_`` when available (falling back to ``np.unique``) so the
19
+ probability columns line up, binarize against that full training class list to
20
+ keep the columns aligned, and expose the subset of classes actually present in the
21
+ evaluated dataset's ``y`` (a class with no positives has no defined ROC) so callers
22
+ emit per-class output only for those. Consequently, callers that compute a
23
+ micro-average pool only the present classes' aligned columns, so when a training
24
+ class is absent from the evaluated slice the micro number deliberately excludes
25
+ that class's column rather than pooling the full training-class matrix.
26
+ """
27
+
28
+ from typing import Any, List, NamedTuple
29
+
30
+ import numpy as np
31
+ from sklearn.preprocessing import label_binarize
32
+
33
+ from validmind.errors import SkipTestError
34
+ from validmind.vm_models import VMDataset, VMModel
35
+
36
+
37
+ class MulticlassProba(NamedTuple):
38
+ """Aligned per-class probabilities for a multiclass one-vs-rest test.
39
+
40
+ ``class_list`` is the full training class order used for column alignment and
41
+ binarization; ``classes_present``/``present_indices`` select the classes that
42
+ actually appear in the evaluated dataset's ``y`` (paired: ``present_indices[k]``
43
+ is the ``class_list``/``y_prob`` column for ``classes_present[k]``). ``y_bin`` is
44
+ the true labels one-hot encoded against ``class_list``; ``y_prob`` is the
45
+ estimator's per-class probability matrix in ``class_list`` column order.
46
+ """
47
+
48
+ class_list: np.ndarray
49
+ classes_present: List[Any]
50
+ present_indices: List[int]
51
+ y_bin: np.ndarray
52
+ y_prob: np.ndarray
53
+
54
+
55
+ def resolve_class_list(model: VMModel, dataset: VMDataset) -> np.ndarray:
56
+ """Return the ``predict_proba`` column order for a multiclass model.
57
+
58
+ scikit-learn orders columns by ``estimator.classes_`` (training classes), so
59
+ prefer that; fall back to ``np.unique(dataset.y)`` for models that do not
60
+ expose it.
61
+ """
62
+ raw_model = getattr(model, "model", None)
63
+ classes = getattr(raw_model, "classes_", None)
64
+ if classes is None:
65
+ classes = np.unique(dataset.y)
66
+ return np.asarray(classes)
67
+
68
+
69
+ def proba_matrix(
70
+ model: VMModel, dataset: VMDataset, class_list: np.ndarray, test_name: str
71
+ ) -> np.ndarray:
72
+ """Return the estimator's per-class probability matrix, or ``SkipTestError``.
73
+
74
+ The VMModel wrapper's ``predict_proba`` is binary-only (positive-class column
75
+ only), so reach the underlying estimator for the full per-class matrix. Skips
76
+ (rather than crashes) for models without a usable ``predict_proba``
77
+ (metadata-only / precomputed single-column predictions) or a matrix whose width
78
+ does not match ``class_list``.
79
+ """
80
+ raw_model = getattr(model, "model", None)
81
+ proba_fn = getattr(raw_model, "predict_proba", None)
82
+ if not callable(proba_fn):
83
+ raise SkipTestError(
84
+ f"Multiclass {test_name} requires per-class probabilities from the "
85
+ "underlying model's predict_proba, which is not available for this "
86
+ "model (e.g. metadata-only / precomputed predictions). Skipping."
87
+ )
88
+ try:
89
+ y_prob = np.asarray(proba_fn(dataset.x_df()))
90
+ except Exception as e:
91
+ raise SkipTestError(
92
+ f"Multiclass {test_name} could not compute per-class probabilities "
93
+ f"({type(e).__name__}). Skipping."
94
+ ) from e
95
+
96
+ n_classes = len(class_list)
97
+ if y_prob.ndim != 2 or y_prob.shape[1] != n_classes:
98
+ raise SkipTestError(
99
+ f"Multiclass {test_name} requires a per-class probability matrix with "
100
+ f"one column per class (got shape {getattr(y_prob, 'shape', None)} for "
101
+ f"{n_classes} classes). Skipping."
102
+ )
103
+ return y_prob
104
+
105
+
106
+ def multiclass_proba(
107
+ model: VMModel, dataset: VMDataset, test_name: str
108
+ ) -> MulticlassProba:
109
+ """Resolve aligned per-class probabilities for a multiclass one-vs-rest test.
110
+
111
+ Aligns on the estimator's training classes, binarizes the true labels against
112
+ that full class list (so columns stay aligned even when the dataset is missing a
113
+ class), and reports which classes are actually present in the evaluated ``y``.
114
+ Raises ``SkipTestError`` for models that cannot supply a matching per-class
115
+ probability matrix, that were trained on fewer than 3 classes (one-vs-rest
116
+ multiclass metrics don't apply to a binary model), or when the evaluated
117
+ dataset's ``y`` contains a label the model was never trained on.
118
+ """
119
+ class_list = resolve_class_list(model, dataset)
120
+ if len(class_list) < 3:
121
+ raise SkipTestError(
122
+ f"Multiclass {test_name} requires a model trained on at least 3 "
123
+ "classes for one-vs-rest multiclass metrics to apply, but this model "
124
+ f"appears to be binary (trained on {len(class_list)} classes). "
125
+ "Skipping."
126
+ )
127
+
128
+ y_prob = proba_matrix(model, dataset, class_list, test_name)
129
+
130
+ y_true = np.asarray(dataset.y).flatten()
131
+ y_bin = label_binarize(y_true, classes=class_list)
132
+
133
+ unknown_labels = sorted(set(np.unique(y_true)) - set(class_list))
134
+ if unknown_labels:
135
+ raise SkipTestError(
136
+ f"Multiclass {test_name} found label(s) {unknown_labels} in the "
137
+ "evaluated dataset that the model was not trained on (not present in "
138
+ "the estimator's classes_). Skipping."
139
+ )
140
+
141
+ present_indices = [i for i, cls in enumerate(class_list) if np.any(y_true == cls)]
142
+ classes_present = [class_list[i] for i in present_indices]
143
+
144
+ return MulticlassProba(
145
+ class_list=class_list,
146
+ classes_present=classes_present,
147
+ present_indices=present_indices,
148
+ y_bin=y_bin,
149
+ y_prob=y_prob,
150
+ )
@@ -7,10 +7,9 @@ from typing import Tuple
7
7
  import numpy as np
8
8
  import pandas as pd
9
9
  from sklearn.metrics import roc_auc_score, roc_curve
10
- from sklearn.preprocessing import label_binarize
11
10
 
12
11
  from validmind import RawData, tags, tasks
13
- from validmind.errors import SkipTestError
12
+ from validmind.tests.model_validation.sklearn._multiclass_proba import multiclass_proba
14
13
  from validmind.vm_models import VMDataset, VMModel
15
14
 
16
15
 
@@ -71,7 +70,7 @@ def GINITable(dataset: VMDataset, model: VMModel) -> Tuple[pd.DataFrame, RawData
71
70
  classes = np.unique(dataset.y)
72
71
 
73
72
  if len(classes) > 2:
74
- return _multiclass_gini_table(model, dataset, classes)
73
+ return _multiclass_gini_table(model, dataset)
75
74
 
76
75
  y_true = np.ravel(dataset.y) # Flatten y_true to make it one-dimensional
77
76
  y_prob = dataset.y_prob(model)
@@ -99,50 +98,24 @@ def GINITable(dataset: VMDataset, model: VMModel) -> Tuple[pd.DataFrame, RawData
99
98
 
100
99
 
101
100
  def _multiclass_gini_table(
102
- model: VMModel, dataset: VMDataset, classes: np.ndarray
101
+ model: VMModel, dataset: VMDataset
103
102
  ) -> Tuple[pd.DataFrame, RawData]:
104
103
  """One-vs-rest AUC/GINI/KS for a multiclass model.
105
104
 
106
105
  Needs the full per-class probability matrix, which the stored single
107
- probability column cannot provide, so we ask the underlying estimator for
108
- it directly. Models without a usable ``predict_proba`` (metadata-only,
109
- precomputed single-column probabilities) are skipped rather than crashed.
106
+ probability column cannot provide; the shared helper reaches the underlying
107
+ estimator, aligns the probability columns to the training class order and
108
+ skips models that cannot supply a matching matrix.
110
109
  """
111
- # The VMModel wrapper's y_prob is binary-only (positive-class column only),
112
- # so reach the underlying estimator for the full per-class probability matrix.
113
- raw_model = getattr(model, "model", None)
114
- proba_fn = getattr(raw_model, "predict_proba", None)
115
- if not callable(proba_fn):
116
- raise SkipTestError(
117
- "Multiclass GINITable requires per-class probabilities from the "
118
- "underlying model's predict_proba, which is not available for this "
119
- "model (e.g. metadata-only / precomputed predictions). Skipping."
120
- )
121
- try:
122
- y_prob = np.asarray(proba_fn(dataset.x_df()))
123
- except Exception as e:
124
- raise SkipTestError(
125
- "Multiclass GINITable could not compute per-class probabilities "
126
- f"({type(e).__name__}). Skipping."
127
- ) from e
128
-
129
- n_classes = len(classes)
130
- if y_prob.ndim != 2 or y_prob.shape[1] != n_classes:
131
- raise SkipTestError(
132
- "Multiclass GINITable requires a per-class probability matrix with "
133
- f"one column per class (got shape {getattr(y_prob, 'shape', None)} "
134
- f"for {n_classes} classes). Skipping."
135
- )
136
-
137
- # One-hot the true labels in the same class order predict_proba columns use
138
- # (sklearn orders predict_proba columns by sorted class label == np.unique).
139
- y_true = dataset.y.flatten()
140
- y_bin = label_binarize(y_true, classes=classes)
110
+ aligned = multiclass_proba(model, dataset, "GINITable")
111
+ y_true = np.asarray(dataset.y).flatten()
112
+ y_bin = aligned.y_bin
113
+ y_prob = aligned.y_prob
141
114
 
142
115
  rows = []
143
116
  raw_fpr = {}
144
117
  raw_tpr = {}
145
- for i, cls in enumerate(classes):
118
+ for i, cls in zip(aligned.present_indices, aligned.classes_present):
146
119
  fpr, tpr, _ = roc_curve(y_bin[:, i], y_prob[:, i])
147
120
  auc = roc_auc_score(y_bin[:, i], y_prob[:, i])
148
121
  key = str(cls)
@@ -152,9 +125,14 @@ def _multiclass_gini_table(
152
125
  {"Class": key, "AUC": auc, "GINI": 2 * auc - 1, "KS": max(tpr - fpr)}
153
126
  )
154
127
 
155
- # Micro-average across all one-vs-rest decisions.
156
- micro_fpr, micro_tpr, _ = roc_curve(y_bin.ravel(), y_prob.ravel())
157
- micro_auc = roc_auc_score(y_bin, y_prob, average="micro", multi_class="ovr")
128
+ # Micro-average across the one-vs-rest decisions of the present classes.
129
+ present = aligned.present_indices
130
+ micro_fpr, micro_tpr, _ = roc_curve(
131
+ y_bin[:, present].ravel(), y_prob[:, present].ravel()
132
+ )
133
+ micro_auc = roc_auc_score(
134
+ y_bin[:, present], y_prob[:, present], average="micro", multi_class="ovr"
135
+ )
158
136
  raw_fpr["micro"] = micro_fpr
159
137
  raw_tpr["micro"] = micro_tpr
160
138
  rows.append(
@@ -1 +0,0 @@
1
- __version__ = "2.13.7"
File without changes
File without changes
File without changes