validmind 2.5.8__py3-none-any.whl → 2.5.18__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. validmind/__version__.py +1 -1
  2. validmind/ai/test_descriptions.py +80 -119
  3. validmind/ai/test_result_description/config.yaml +29 -0
  4. validmind/ai/test_result_description/context.py +73 -0
  5. validmind/ai/test_result_description/image_processing.py +124 -0
  6. validmind/ai/test_result_description/system.jinja +39 -0
  7. validmind/ai/test_result_description/user.jinja +25 -0
  8. validmind/api_client.py +89 -43
  9. validmind/client.py +2 -2
  10. validmind/client_config.py +11 -14
  11. validmind/datasets/credit_risk/__init__.py +1 -0
  12. validmind/datasets/credit_risk/datasets/lending_club_biased.csv.gz +0 -0
  13. validmind/datasets/credit_risk/lending_club_bias.py +142 -0
  14. validmind/datasets/regression/fred_timeseries.py +67 -138
  15. validmind/template.py +1 -0
  16. validmind/test_suites/__init__.py +0 -2
  17. validmind/test_suites/statsmodels_timeseries.py +1 -1
  18. validmind/test_suites/summarization.py +0 -1
  19. validmind/test_suites/time_series.py +0 -43
  20. validmind/tests/__types__.py +14 -15
  21. validmind/tests/data_validation/ACFandPACFPlot.py +15 -13
  22. validmind/tests/data_validation/ADF.py +31 -24
  23. validmind/tests/data_validation/AutoAR.py +9 -9
  24. validmind/tests/data_validation/AutoMA.py +23 -16
  25. validmind/tests/data_validation/AutoSeasonality.py +18 -16
  26. validmind/tests/data_validation/AutoStationarity.py +21 -16
  27. validmind/tests/data_validation/BivariateScatterPlots.py +67 -96
  28. validmind/tests/{model_validation/statsmodels → data_validation}/BoxPierce.py +34 -34
  29. validmind/tests/data_validation/ChiSquaredFeaturesTable.py +85 -124
  30. validmind/tests/data_validation/ClassImbalance.py +15 -12
  31. validmind/tests/data_validation/DFGLSArch.py +19 -13
  32. validmind/tests/data_validation/DatasetDescription.py +17 -11
  33. validmind/tests/data_validation/DatasetSplit.py +7 -5
  34. validmind/tests/data_validation/DescriptiveStatistics.py +28 -21
  35. validmind/tests/data_validation/Duplicates.py +33 -25
  36. validmind/tests/data_validation/EngleGrangerCoint.py +35 -33
  37. validmind/tests/data_validation/FeatureTargetCorrelationPlot.py +59 -71
  38. validmind/tests/data_validation/HighCardinality.py +19 -12
  39. validmind/tests/data_validation/HighPearsonCorrelation.py +27 -22
  40. validmind/tests/data_validation/IQROutliersBarPlot.py +13 -10
  41. validmind/tests/data_validation/IQROutliersTable.py +40 -36
  42. validmind/tests/data_validation/IsolationForestOutliers.py +21 -14
  43. validmind/tests/data_validation/JarqueBera.py +70 -0
  44. validmind/tests/data_validation/KPSS.py +34 -29
  45. validmind/tests/data_validation/LJungBox.py +66 -0
  46. validmind/tests/data_validation/LaggedCorrelationHeatmap.py +22 -15
  47. validmind/tests/data_validation/MissingValues.py +32 -27
  48. validmind/tests/data_validation/MissingValuesBarPlot.py +25 -21
  49. validmind/tests/data_validation/PearsonCorrelationMatrix.py +71 -84
  50. validmind/tests/data_validation/PhillipsPerronArch.py +37 -30
  51. validmind/tests/data_validation/ProtectedClassesCombination.py +197 -0
  52. validmind/tests/data_validation/ProtectedClassesDescription.py +130 -0
  53. validmind/tests/data_validation/ProtectedClassesDisparity.py +133 -0
  54. validmind/tests/data_validation/ProtectedClassesThresholdOptimizer.py +172 -0
  55. validmind/tests/data_validation/RollingStatsPlot.py +31 -23
  56. validmind/tests/data_validation/RunsTest.py +72 -0
  57. validmind/tests/data_validation/ScatterPlot.py +63 -78
  58. validmind/tests/data_validation/SeasonalDecompose.py +38 -34
  59. validmind/tests/{model_validation/statsmodels → data_validation}/ShapiroWilk.py +35 -30
  60. validmind/tests/data_validation/Skewness.py +35 -37
  61. validmind/tests/data_validation/SpreadPlot.py +35 -35
  62. validmind/tests/data_validation/TabularCategoricalBarPlots.py +23 -17
  63. validmind/tests/data_validation/TabularDateTimeHistograms.py +21 -13
  64. validmind/tests/data_validation/TabularDescriptionTables.py +51 -16
  65. validmind/tests/data_validation/TabularNumericalHistograms.py +25 -22
  66. validmind/tests/data_validation/TargetRateBarPlots.py +21 -14
  67. validmind/tests/data_validation/TimeSeriesDescription.py +25 -18
  68. validmind/tests/data_validation/TimeSeriesDescriptiveStatistics.py +23 -17
  69. validmind/tests/data_validation/TimeSeriesFrequency.py +24 -17
  70. validmind/tests/data_validation/TimeSeriesHistogram.py +33 -32
  71. validmind/tests/data_validation/TimeSeriesLinePlot.py +17 -10
  72. validmind/tests/data_validation/TimeSeriesMissingValues.py +15 -10
  73. validmind/tests/data_validation/TimeSeriesOutliers.py +37 -33
  74. validmind/tests/data_validation/TooManyZeroValues.py +16 -11
  75. validmind/tests/data_validation/UniqueRows.py +11 -6
  76. validmind/tests/data_validation/WOEBinPlots.py +23 -16
  77. validmind/tests/data_validation/WOEBinTable.py +35 -30
  78. validmind/tests/data_validation/ZivotAndrewsArch.py +34 -28
  79. validmind/tests/data_validation/nlp/CommonWords.py +21 -14
  80. validmind/tests/data_validation/nlp/Hashtags.py +42 -40
  81. validmind/tests/data_validation/nlp/LanguageDetection.py +33 -14
  82. validmind/tests/data_validation/nlp/Mentions.py +21 -15
  83. validmind/tests/data_validation/nlp/PolarityAndSubjectivity.py +32 -9
  84. validmind/tests/data_validation/nlp/Punctuations.py +24 -20
  85. validmind/tests/data_validation/nlp/Sentiment.py +27 -8
  86. validmind/tests/data_validation/nlp/StopWords.py +26 -19
  87. validmind/tests/data_validation/nlp/TextDescription.py +39 -36
  88. validmind/tests/data_validation/nlp/Toxicity.py +32 -9
  89. validmind/tests/decorator.py +81 -42
  90. validmind/tests/model_validation/BertScore.py +36 -27
  91. validmind/tests/model_validation/BleuScore.py +25 -19
  92. validmind/tests/model_validation/ClusterSizeDistribution.py +38 -34
  93. validmind/tests/model_validation/ContextualRecall.py +38 -13
  94. validmind/tests/model_validation/FeaturesAUC.py +32 -13
  95. validmind/tests/model_validation/MeteorScore.py +46 -33
  96. validmind/tests/model_validation/ModelMetadata.py +32 -64
  97. validmind/tests/model_validation/ModelPredictionResiduals.py +75 -73
  98. validmind/tests/model_validation/RegardScore.py +30 -14
  99. validmind/tests/model_validation/RegressionResidualsPlot.py +10 -5
  100. validmind/tests/model_validation/RougeScore.py +36 -30
  101. validmind/tests/model_validation/TimeSeriesPredictionWithCI.py +30 -14
  102. validmind/tests/model_validation/TimeSeriesPredictionsPlot.py +27 -30
  103. validmind/tests/model_validation/TimeSeriesR2SquareBySegments.py +68 -63
  104. validmind/tests/model_validation/TokenDisparity.py +31 -23
  105. validmind/tests/model_validation/ToxicityScore.py +26 -17
  106. validmind/tests/model_validation/embeddings/ClusterDistribution.py +24 -20
  107. validmind/tests/model_validation/embeddings/CosineSimilarityComparison.py +30 -27
  108. validmind/tests/model_validation/embeddings/CosineSimilarityDistribution.py +7 -5
  109. validmind/tests/model_validation/embeddings/CosineSimilarityHeatmap.py +32 -23
  110. validmind/tests/model_validation/embeddings/DescriptiveAnalytics.py +7 -5
  111. validmind/tests/model_validation/embeddings/EmbeddingsVisualization2D.py +15 -11
  112. validmind/tests/model_validation/embeddings/EuclideanDistanceComparison.py +29 -29
  113. validmind/tests/model_validation/embeddings/EuclideanDistanceHeatmap.py +34 -25
  114. validmind/tests/model_validation/embeddings/PCAComponentsPairwisePlots.py +38 -26
  115. validmind/tests/model_validation/embeddings/StabilityAnalysis.py +40 -1
  116. validmind/tests/model_validation/embeddings/StabilityAnalysisKeyword.py +18 -17
  117. validmind/tests/model_validation/embeddings/StabilityAnalysisRandomNoise.py +40 -45
  118. validmind/tests/model_validation/embeddings/StabilityAnalysisSynonyms.py +17 -19
  119. validmind/tests/model_validation/embeddings/StabilityAnalysisTranslation.py +29 -25
  120. validmind/tests/model_validation/embeddings/TSNEComponentsPairwisePlots.py +38 -28
  121. validmind/tests/model_validation/ragas/AnswerCorrectness.py +5 -4
  122. validmind/tests/model_validation/ragas/AnswerRelevance.py +5 -4
  123. validmind/tests/model_validation/ragas/AnswerSimilarity.py +5 -4
  124. validmind/tests/model_validation/ragas/AspectCritique.py +12 -6
  125. validmind/tests/model_validation/ragas/ContextEntityRecall.py +9 -8
  126. validmind/tests/model_validation/ragas/ContextPrecision.py +5 -4
  127. validmind/tests/model_validation/ragas/ContextRecall.py +5 -4
  128. validmind/tests/model_validation/ragas/ContextUtilization.py +155 -0
  129. validmind/tests/model_validation/ragas/Faithfulness.py +5 -4
  130. validmind/tests/model_validation/ragas/NoiseSensitivity.py +152 -0
  131. validmind/tests/model_validation/ragas/utils.py +6 -0
  132. validmind/tests/model_validation/sklearn/AdjustedMutualInformation.py +19 -12
  133. validmind/tests/model_validation/sklearn/AdjustedRandIndex.py +22 -17
  134. validmind/tests/model_validation/sklearn/ClassifierPerformance.py +27 -25
  135. validmind/tests/model_validation/sklearn/ClusterCosineSimilarity.py +7 -5
  136. validmind/tests/model_validation/sklearn/ClusterPerformance.py +40 -78
  137. validmind/tests/model_validation/sklearn/ClusterPerformanceMetrics.py +15 -17
  138. validmind/tests/model_validation/sklearn/CompletenessScore.py +17 -11
  139. validmind/tests/model_validation/sklearn/ConfusionMatrix.py +22 -15
  140. validmind/tests/model_validation/sklearn/FeatureImportance.py +95 -0
  141. validmind/tests/model_validation/sklearn/FowlkesMallowsScore.py +7 -7
  142. validmind/tests/model_validation/sklearn/HomogeneityScore.py +19 -12
  143. validmind/tests/model_validation/sklearn/HyperParametersTuning.py +35 -30
  144. validmind/tests/model_validation/sklearn/KMeansClustersOptimization.py +10 -5
  145. validmind/tests/model_validation/sklearn/MinimumAccuracy.py +32 -32
  146. validmind/tests/model_validation/sklearn/MinimumF1Score.py +23 -23
  147. validmind/tests/model_validation/sklearn/MinimumROCAUCScore.py +15 -10
  148. validmind/tests/model_validation/sklearn/ModelsPerformanceComparison.py +26 -19
  149. validmind/tests/model_validation/sklearn/OverfitDiagnosis.py +38 -18
  150. validmind/tests/model_validation/sklearn/PermutationFeatureImportance.py +32 -26
  151. validmind/tests/model_validation/sklearn/PopulationStabilityIndex.py +8 -6
  152. validmind/tests/model_validation/sklearn/PrecisionRecallCurve.py +24 -17
  153. validmind/tests/model_validation/sklearn/ROCCurve.py +12 -7
  154. validmind/tests/model_validation/sklearn/RegressionErrors.py +74 -130
  155. validmind/tests/model_validation/sklearn/RegressionErrorsComparison.py +27 -12
  156. validmind/tests/model_validation/sklearn/{RegressionModelsPerformanceComparison.py → RegressionPerformance.py} +18 -20
  157. validmind/tests/model_validation/sklearn/RegressionR2Square.py +55 -94
  158. validmind/tests/model_validation/sklearn/RegressionR2SquareComparison.py +32 -13
  159. validmind/tests/model_validation/sklearn/RobustnessDiagnosis.py +36 -32
  160. validmind/tests/model_validation/sklearn/SHAPGlobalImportance.py +66 -5
  161. validmind/tests/model_validation/sklearn/SilhouettePlot.py +27 -19
  162. validmind/tests/model_validation/sklearn/TrainingTestDegradation.py +25 -18
  163. validmind/tests/model_validation/sklearn/VMeasure.py +14 -13
  164. validmind/tests/model_validation/sklearn/WeakspotsDiagnosis.py +7 -5
  165. validmind/tests/model_validation/statsmodels/AutoARIMA.py +24 -18
  166. validmind/tests/model_validation/statsmodels/CumulativePredictionProbabilities.py +73 -104
  167. validmind/tests/model_validation/statsmodels/DurbinWatsonTest.py +59 -32
  168. validmind/tests/model_validation/statsmodels/GINITable.py +44 -77
  169. validmind/tests/model_validation/statsmodels/KolmogorovSmirnov.py +33 -34
  170. validmind/tests/model_validation/statsmodels/Lilliefors.py +27 -24
  171. validmind/tests/model_validation/statsmodels/PredictionProbabilitiesHistogram.py +86 -119
  172. validmind/tests/model_validation/statsmodels/RegressionCoeffs.py +100 -0
  173. validmind/tests/model_validation/statsmodels/RegressionFeatureSignificance.py +14 -9
  174. validmind/tests/model_validation/statsmodels/RegressionModelForecastPlot.py +17 -13
  175. validmind/tests/model_validation/statsmodels/RegressionModelForecastPlotLevels.py +46 -43
  176. validmind/tests/model_validation/statsmodels/RegressionModelSensitivityPlot.py +38 -36
  177. validmind/tests/model_validation/statsmodels/RegressionModelSummary.py +30 -28
  178. validmind/tests/model_validation/statsmodels/RegressionPermutationFeatureImportance.py +18 -11
  179. validmind/tests/model_validation/statsmodels/ScorecardHistogram.py +75 -107
  180. validmind/tests/ongoing_monitoring/FeatureDrift.py +10 -6
  181. validmind/tests/ongoing_monitoring/PredictionAcrossEachFeature.py +31 -25
  182. validmind/tests/ongoing_monitoring/PredictionCorrelation.py +29 -21
  183. validmind/tests/ongoing_monitoring/TargetPredictionDistributionPlot.py +31 -23
  184. validmind/tests/prompt_validation/Bias.py +14 -11
  185. validmind/tests/prompt_validation/Clarity.py +16 -14
  186. validmind/tests/prompt_validation/Conciseness.py +7 -5
  187. validmind/tests/prompt_validation/Delimitation.py +23 -22
  188. validmind/tests/prompt_validation/NegativeInstruction.py +7 -5
  189. validmind/tests/prompt_validation/Robustness.py +12 -10
  190. validmind/tests/prompt_validation/Specificity.py +13 -11
  191. validmind/tests/prompt_validation/ai_powered_test.py +6 -0
  192. validmind/tests/run.py +68 -23
  193. validmind/unit_metrics/__init__.py +81 -144
  194. validmind/unit_metrics/classification/{sklearn/Accuracy.py → Accuracy.py} +1 -1
  195. validmind/unit_metrics/classification/{sklearn/F1.py → F1.py} +1 -1
  196. validmind/unit_metrics/classification/{sklearn/Precision.py → Precision.py} +1 -1
  197. validmind/unit_metrics/classification/{sklearn/ROC_AUC.py → ROC_AUC.py} +1 -2
  198. validmind/unit_metrics/classification/{sklearn/Recall.py → Recall.py} +1 -1
  199. validmind/unit_metrics/regression/{sklearn/AdjustedRSquaredScore.py → AdjustedRSquaredScore.py} +1 -1
  200. validmind/unit_metrics/regression/GiniCoefficient.py +1 -1
  201. validmind/unit_metrics/regression/HuberLoss.py +1 -1
  202. validmind/unit_metrics/regression/KolmogorovSmirnovStatistic.py +1 -1
  203. validmind/unit_metrics/regression/{sklearn/MeanAbsoluteError.py → MeanAbsoluteError.py} +1 -1
  204. validmind/unit_metrics/regression/MeanAbsolutePercentageError.py +1 -1
  205. validmind/unit_metrics/regression/MeanBiasDeviation.py +1 -1
  206. validmind/unit_metrics/regression/{sklearn/MeanSquaredError.py → MeanSquaredError.py} +1 -1
  207. validmind/unit_metrics/regression/QuantileLoss.py +1 -1
  208. validmind/unit_metrics/regression/{sklearn/RSquaredScore.py → RSquaredScore.py} +1 -1
  209. validmind/unit_metrics/regression/{sklearn/RootMeanSquaredError.py → RootMeanSquaredError.py} +1 -1
  210. validmind/utils.py +4 -0
  211. validmind/vm_models/dataset/dataset.py +2 -0
  212. validmind/vm_models/figure.py +5 -0
  213. validmind/vm_models/test/metric.py +1 -0
  214. validmind/vm_models/test/result_wrapper.py +143 -158
  215. validmind/vm_models/test/threshold_test.py +1 -0
  216. {validmind-2.5.8.dist-info → validmind-2.5.18.dist-info}/METADATA +4 -3
  217. validmind-2.5.18.dist-info/RECORD +324 -0
  218. validmind/tests/data_validation/ANOVAOneWayTable.py +0 -138
  219. validmind/tests/data_validation/BivariateFeaturesBarPlots.py +0 -142
  220. validmind/tests/data_validation/BivariateHistograms.py +0 -117
  221. validmind/tests/data_validation/HeatmapFeatureCorrelations.py +0 -124
  222. validmind/tests/data_validation/MissingValuesRisk.py +0 -88
  223. validmind/tests/model_validation/ModelMetadataComparison.py +0 -59
  224. validmind/tests/model_validation/sklearn/FeatureImportanceComparison.py +0 -83
  225. validmind/tests/model_validation/statsmodels/JarqueBera.py +0 -73
  226. validmind/tests/model_validation/statsmodels/LJungBox.py +0 -66
  227. validmind/tests/model_validation/statsmodels/RegressionCoeffsPlot.py +0 -135
  228. validmind/tests/model_validation/statsmodels/RegressionModelsCoeffs.py +0 -103
  229. validmind/tests/model_validation/statsmodels/RunsTest.py +0 -71
  230. validmind-2.5.8.dist-info/RECORD +0 -318
  231. {validmind-2.5.8.dist-info → validmind-2.5.18.dist-info}/LICENSE +0 -0
  232. {validmind-2.5.8.dist-info → validmind-2.5.18.dist-info}/WHEEL +0 -0
  233. {validmind-2.5.8.dist-info → validmind-2.5.18.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,172 @@
1
+ # Copyright © 2023-2024 ValidMind Inc. All rights reserved.
2
+ # See the LICENSE file in the root of this repository for details.
3
+ # SPDX-License-Identifier: AGPL-3.0 AND ValidMind Commercial
4
+
5
+ import json
6
+ import sys
7
+
8
+ import matplotlib.pyplot as plt
9
+ import pandas as pd
10
+ from fairlearn.metrics import (
11
+ MetricFrame,
12
+ count,
13
+ demographic_parity_ratio,
14
+ equalized_odds_ratio,
15
+ false_negative_rate,
16
+ false_positive_rate,
17
+ true_positive_rate,
18
+ )
19
+ from fairlearn.postprocessing import ThresholdOptimizer, plot_threshold_optimizer
20
+
21
+ from validmind import tags, tasks
22
+ from validmind.logging import get_logger
23
+
24
+ logger = get_logger(__name__)
25
+
26
+
27
+ @tags("bias_and_fairness")
28
+ @tasks("classification", "regression")
29
+ def ProtectedClassesThresholdOptimizer(
30
+ dataset, pipeline=None, protected_classes=None, X_train=None, y_train=None
31
+ ):
32
+ """
33
+ Obtains a classifier by applying group-specific thresholds to the provided estimator.
34
+
35
+ ### Purpose
36
+
37
+ This test aims to optimize the fairness of a machine learning model by applying different
38
+ classification thresholds for different protected groups. It helps in mitigating bias and
39
+ achieving more equitable outcomes across different demographic groups.
40
+
41
+ ### Test Mechanism
42
+
43
+ The test uses Fairlearn's ThresholdOptimizer to:
44
+ 1. Fit an optimizer on the training data, considering protected classes.
45
+ 2. Apply optimized thresholds to make predictions on the test data.
46
+ 3. Calculate and report various fairness metrics.
47
+ 4. Visualize the optimized thresholds.
48
+
49
+ ### Signs of High Risk
50
+
51
+ - Large disparities in fairness metrics (e.g., Demographic Parity Ratio, Equalized Odds Ratio)
52
+ across different protected groups.
53
+ - Significant differences in False Positive Rates (FPR) or True Positive Rates (TPR) between groups.
54
+ - Thresholds that vary widely across different protected groups.
55
+
56
+ ### Strengths
57
+
58
+ - Provides a post-processing method to improve model fairness without modifying the original model.
59
+ - Allows for balancing multiple fairness criteria simultaneously.
60
+ - Offers visual insights into the threshold optimization process.
61
+
62
+ ### Limitations
63
+
64
+ - May lead to a decrease in overall model performance while improving fairness.
65
+ - Requires access to protected attribute information at prediction time.
66
+ - The effectiveness can vary depending on the chosen fairness constraint and objective.
67
+ """
68
+
69
+ if sys.version_info < (3, 9):
70
+ raise RuntimeError("This test requires Python 3.9 or higher.")
71
+
72
+ if (
73
+ pipeline is None
74
+ or protected_classes is None
75
+ or X_train is None
76
+ or y_train is None
77
+ ):
78
+ logger.warning(
79
+ "Missing required parameters. Please provide pipeline, protected_classes, X_train, and y_train."
80
+ )
81
+ return pd.DataFrame()
82
+
83
+ test_df = dataset.df
84
+
85
+ threshold_optimizer = initialize_and_fit_optimizer(
86
+ pipeline, X_train, y_train, X_train[protected_classes]
87
+ )
88
+
89
+ fig = plot_thresholds(threshold_optimizer)
90
+
91
+ target = dataset.target_column
92
+ y_pred_opt = make_predictions(threshold_optimizer, test_df, protected_classes)
93
+
94
+ fairness_metrics = calculate_fairness_metrics(
95
+ test_df, target, y_pred_opt, protected_classes
96
+ )
97
+
98
+ return (
99
+ {"DPR and EOR Table": fairness_metrics.reset_index()},
100
+ fig,
101
+ )
102
+
103
+
104
+ def initialize_and_fit_optimizer(pipeline, X_train, y_train, protected_classes_df):
105
+ threshold_optimizer = ThresholdOptimizer(
106
+ estimator=pipeline,
107
+ objective="balanced_accuracy_score",
108
+ constraints="demographic_parity",
109
+ predict_method="predict_proba",
110
+ prefit=False,
111
+ )
112
+ threshold_optimizer.fit(X_train, y_train, sensitive_features=protected_classes_df)
113
+ return threshold_optimizer
114
+
115
+
116
+ def plot_thresholds(threshold_optimizer):
117
+ fig = plt.figure()
118
+ plot_threshold_optimizer(threshold_optimizer, show_plot=False)
119
+ return fig
120
+
121
+
122
+ def make_predictions(threshold_optimizer, test_df, protected_classes):
123
+ y_pred_opt = threshold_optimizer.predict(
124
+ test_df, sensitive_features=test_df[protected_classes]
125
+ )
126
+ return y_pred_opt
127
+
128
+
129
+ def calculate_fairness_metrics(test_df, target, y_pred_opt, protected_classes):
130
+ fairness_metrics = pd.DataFrame(
131
+ columns=protected_classes,
132
+ index=["demographic parity ratio", "equal odds ratio"],
133
+ )
134
+
135
+ for feature in protected_classes:
136
+ dpr = demographic_parity_ratio(
137
+ y_true=test_df[target],
138
+ y_pred=y_pred_opt,
139
+ sensitive_features=test_df[[feature]],
140
+ )
141
+ eor = equalized_odds_ratio(
142
+ y_true=test_df[target],
143
+ y_pred=y_pred_opt,
144
+ sensitive_features=test_df[[feature]],
145
+ )
146
+ fairness_metrics[feature] = [round(dpr, 2), round(eor, 2)]
147
+
148
+ return fairness_metrics
149
+
150
+
151
+ def calculate_group_metrics(test_df, target, y_pred_opt, protected_classes):
152
+ metrics = {
153
+ "fpr": false_positive_rate,
154
+ "tpr": true_positive_rate,
155
+ "fnr": false_negative_rate,
156
+ "count": count,
157
+ }
158
+ mf = MetricFrame(
159
+ metrics=metrics,
160
+ y_true=test_df[target],
161
+ y_pred=y_pred_opt,
162
+ sensitive_features=test_df[protected_classes],
163
+ )
164
+ group_metrics = mf.by_group
165
+ return group_metrics
166
+
167
+
168
+ def get_thresholds_by_group(threshold_optimizer):
169
+ threshold_rules = threshold_optimizer.interpolated_thresholder_.interpolation_dict
170
+ thresholds = json.dumps(threshold_rules, default=str, indent=4)
171
+ thresholds_df = pd.DataFrame.from_records(json.loads(thresholds))
172
+ return thresholds_df
@@ -10,41 +10,49 @@ from validmind.vm_models import Figure, Metric
10
10
 
11
11
  class RollingStatsPlot(Metric):
12
12
  """
13
- This test evaluates the stationarity of time series data by plotting its rolling mean and standard deviation.
14
-
15
- **Purpose**: The `RollingStatsPlot` metric is employed to gauge the stationarity of time series data in a given
16
- dataset. This metric specifically evaluates the rolling mean and rolling standard deviation of the dataset over a
17
- pre-specified window size. The rolling mean provides an understanding of the average trend in the data, while the
18
- rolling standard deviation gauges the volatility of the data within the window. It is critical in preparing time
19
- series data for modeling as it reveals key insights into data behavior across time.
20
-
21
- **Test Mechanism**: This mechanism is comprised of two steps. Initially, the rolling mean and standard deviation
22
- for each of the dataset's columns are calculated over a window size, which can be user-specified or by default set
23
- to 12 data points. Then, the calculated rolling mean and standard deviation are visualized via separate plots,
24
- illustrating the trends and volatility in the dataset. A straightforward check is conducted to ensure the existence
25
- of columns in the dataset, and to verify that the given dataset has been indexed by its date and time—a necessary
26
- prerequisites for time series analysis.
27
-
28
- **Signs of High Risk**:
13
+ Evaluates the stationarity of time series data by plotting its rolling mean and standard deviation over a specified
14
+ window.
15
+
16
+ ### Purpose
17
+
18
+ The `RollingStatsPlot` metric is employed to gauge the stationarity of time series data in a given dataset. This
19
+ metric specifically evaluates the rolling mean and rolling standard deviation of the dataset over a pre-specified
20
+ window size. The rolling mean provides an understanding of the average trend in the data, while the rolling
21
+ standard deviation gauges the volatility of the data within the window. It is critical in preparing time series
22
+ data for modeling as it reveals key insights into data behavior across time.
23
+
24
+ ### Test Mechanism
25
+
26
+ This mechanism is comprised of two steps. Initially, the rolling mean and standard deviation for each of the
27
+ dataset's columns are calculated over a window size, which can be user-specified or by default set to 12 data
28
+ points. Then, the calculated rolling mean and standard deviation are visualized via separate plots, illustrating
29
+ the trends and volatility in the dataset. A straightforward check is conducted to ensure the existence of columns
30
+ in the dataset, and to verify that the given dataset has been indexed by its date and time—a necessary prerequisite
31
+ for time series analysis.
32
+
33
+ ### Signs of High Risk
34
+
29
35
  - The presence of non-stationary patterns in either the rolling mean or the rolling standard deviation plots, which
30
36
  could indicate trends or seasonality in the data that may affect the performance of time series models.
31
37
  - Missing columns in the dataset, which would prevent the execution of this metric correctly.
32
38
  - The detection of NaN values in the dataset, which may need to be addressed before the metric can proceed
33
39
  successfully.
34
40
 
35
- **Strengths**:
36
- - Offers visualizations of trending behaviour and volatility within the data, facilitating a broader understanding
41
+ ### Strengths
42
+
43
+ - Offers visualizations of trending behavior and volatility within the data, facilitating a broader understanding
37
44
  of the dataset's inherent characteristics.
38
- - Checks of the dataset's integrity, such as existence of all required columns and the availability of a datetime
39
- index.
45
+ - Checks of the dataset's integrity, such as the existence of all required columns and the availability of a
46
+ datetime index.
40
47
  - Adjusts to accommodate various window sizes, thus allowing accurate analysis of data with differing temporal
41
48
  granularities.
42
49
  - Considers each column of the data individually, thereby accommodating multi-feature datasets.
43
50
 
44
- **Limitations**:
45
- - For all columns, a fixed-size window is utilised. This may not accurately capture patterns in datasets where
51
+ ### Limitations
52
+
53
+ - For all columns, a fixed-size window is utilized. This may not accurately capture patterns in datasets where
46
54
  different features may require different optimal window sizes.
47
- - Requires the dataset to be indexed by date and time, hence it may not be useable for datasets without a timestamp
55
+ - Requires the dataset to be indexed by date and time, hence it may not be usable for datasets without a timestamp
48
56
  index.
49
57
  - Primarily serves for data visualization as it does not facilitate any quantitative measures for stationarity,
50
58
  such as through statistical tests. Therefore, the interpretation is subjective and depends heavily on modeler
@@ -0,0 +1,72 @@
1
+ # Copyright © 2023-2024 ValidMind Inc. All rights reserved.
2
+ # See the LICENSE file in the root of this repository for details.
3
+ # SPDX-License-Identifier: AGPL-3.0 AND ValidMind Commercial
4
+
5
+ import pandas as pd
6
+ from statsmodels.sandbox.stats.runs import runstest_1samp
7
+
8
+ from validmind import tags, tasks
9
+
10
+
11
+ @tasks("classification", "regression")
12
+ @tags("tabular_data", "statistical_test", "statsmodels")
13
+ def RunsTest(dataset):
14
+ """
15
+ Executes Runs Test on ML model to detect non-random patterns in output data sequence.
16
+
17
+ ### Purpose
18
+
19
+ The Runs Test is a statistical procedure used to determine whether the sequence of data extracted from the ML model
20
+ behaves randomly or not. Specifically, it analyzes runs, sequences of consecutive positives or negatives, in the
21
+ data to check if there are more or fewer runs than expected under the assumption of randomness. This can be an
22
+ indication of some pattern, trend, or cycle in the model's output which may need attention.
23
+
24
+ ### Test Mechanism
25
+
26
+ The testing mechanism applies the Runs Test from the statsmodels module on each column of the training dataset. For
27
+ every feature in the dataset, a Runs Test is executed, whose output includes a Runs Statistic and P-value. A low
28
+ P-value suggests that data arrangement in the feature is not likely to be random. The results are stored in a
29
+ dictionary where the keys are the feature names, and the values are another dictionary storing the test statistic
30
+ and the P-value for each feature.
31
+
32
+ ### Signs of High Risk
33
+
34
+ - High risk is indicated when the P-value is close to zero.
35
+ - If the P-value is less than a predefined significance level (like 0.05), it suggests that the runs (series of
36
+ positive or negative values) in the model's output are not random and are longer or shorter than what is expected
37
+ under a random scenario.
38
+ - This would mean there's a high risk of non-random distribution of errors or model outcomes, suggesting potential
39
+ issues with the model.
40
+
41
+ ### Strengths
42
+
43
+ - Straightforward and fast for detecting non-random patterns in data sequence.
44
+ - Validates assumptions of randomness, which is valuable for checking error distributions in regression models,
45
+ trendless time series data, and ensuring a classifier doesn't favor one class over another.
46
+ - Can be applied to both classification and regression tasks, making it versatile.
47
+
48
+ ### Limitations
49
+
50
+ - Assumes that the data is independently and identically distributed (i.i.d.), which might not be the case for many
51
+ real-world datasets.
52
+ - The conclusion drawn from the low P-value indicating non-randomness does not provide information about the type
53
+ or the source of the detected pattern.
54
+ - Sensitive to extreme values (outliers), and overly large or small run sequences can influence the results.
55
+ - Does not provide model performance evaluation; it is used to detect patterns in the sequence of outputs only.
56
+ """
57
+
58
+ df = dataset.df[dataset.feature_columns_numeric]
59
+
60
+ runs_test_values = {}
61
+ for col in df.columns:
62
+ runs_stat, runs_p_value = runstest_1samp(df[col].values)
63
+ runs_test_values[col] = {
64
+ "stat": runs_stat,
65
+ "pvalue": runs_p_value,
66
+ }
67
+
68
+ runs_test_df = pd.DataFrame.from_dict(runs_test_values, orient="index")
69
+ runs_test_df.reset_index(inplace=True)
70
+ runs_test_df.columns = ["feature", "stat", "pvalue"]
71
+
72
+ return runs_test_df
@@ -5,86 +5,71 @@
5
5
  import matplotlib.pyplot as plt
6
6
  import seaborn as sns
7
7
 
8
- from validmind.vm_models import Figure, Metric
8
+ from validmind import tags, tasks
9
9
 
10
10
 
11
- class ScatterPlot(Metric):
11
+ @tags("tabular_data", "visualization")
12
+ @tasks("classification", "regression")
13
+ def ScatterPlot(dataset):
12
14
  """
13
- Creates a scatter plot matrix to visually analyze feature relationships, patterns, and outliers in a dataset.
14
-
15
- **Purpose**: The ScatterPlot metric is designed to offer a visual analysis of a given dataset by constructing a
16
- scatter plot matrix encapsulating all the dataset's features (or columns). Its primary function lies in unearthing
17
- relationships, patterns, or outliers across different features, thus providing both quantitative and qualitative
18
- insights into the multidimensional relationships within the dataset. This visual assessment aids in understanding
19
- the efficacy of the chosen features for model training and their overall suitability.
20
-
21
- **Test Mechanism**: Using the seaborn library, the ScatterPlot class creates the scatter plot matrix. The process
22
- includes retrieving all columns from the dataset, verifying their existence, and subsequently generating a pairplot
23
- for these columns. A kernel density estimate (kde) is utilized to present a smoother, univariate distribution along
24
- the grid's diagonal. The final plot is housed in an array of Figure objects, each wrapping a matplotlib figure
25
- instance for storage and future usage.
26
-
27
- **Signs of High Risk**:
28
- - The emergence of non-linear or random patterns across different feature pairs. This may suggest intricate
29
- relationships unfit for linear presumptions.
30
- - A lack of clear patterns or clusters which might point to weak or non-existent correlations among features, thus
31
- creating a problem for certain model types.
32
- - The occurrence of outliers as visual outliers in your data can adversely influence the model's performance.
33
-
34
- **Strengths**:
35
- - It offers insight into the multidimensional relationships among multiple features.
36
- - It assists in identifying trends, correlations, and outliers which could potentially affect the model's
37
- performance.
38
- - As a diagnostic tool, it can validate whether certain assumptions made during the model-creation process, such as
39
- linearity, hold true.
40
- - The tool's versatility extends to its application for both regression and classification tasks.
41
-
42
- **Limitations**:
43
- - Scatter plot matrices may become cluttered and hard to decipher as the number of features escalates, resulting in
44
- complexity and confusion.
45
- - While extremely proficient in revealing pairwise relationships, these matrices may fail to illuminate complex
46
- interactions that involve three or more features.
47
- - These matrices are primarily visual tools, so the precision of quantitative analysis may be compromised.
48
- - If not clearly visible, outliers can be missed, which could negatively affect model performance.
49
- - It assumes that the dataset can fit into the computer's memory, which might not always be valid particularly for
50
- extremely large datasets.
15
+ Assesses visual relationships, patterns, and outliers among features in a dataset through scatter plot matrices.
16
+
17
+ ### Purpose
18
+
19
+ The ScatterPlot test aims to visually analyze a given dataset by constructing a scatter plot matrix of its
20
+ numerical features. The primary goal is to uncover relationships, patterns, and outliers across different features
21
+ to provide both quantitative and qualitative insights into multidimensional relationships within the dataset. This
22
+ visual assessment aids in understanding the efficacy of the chosen features for model training and their
23
+ suitability.
24
+
25
+ ### Test Mechanism
26
+
27
+ Using the Seaborn library, the ScatterPlot function creates the scatter plot matrix. The process involves
28
+ retrieving all numerical columns from the dataset and generating a scatter matrix for these columns. The resulting
29
+ scatter plot provides visual representations of feature relationships. The function also adjusts axis labels for
30
+ readability and returns the final plot as a Matplotlib Figure object for further analysis and visualization.
31
+
32
+ ### Signs of High Risk
33
+
34
+ - The emergence of non-linear or random patterns across different feature pairs, suggesting complex relationships
35
+ unsuitable for linear assumptions.
36
+ - Lack of clear patterns or clusters, indicating weak or non-existent correlations among features, which could
37
+ challenge certain model types.
38
+ - Presence of outliers, as visual outliers can adversely influence the model's performance.
39
+
40
+ ### Strengths
41
+
42
+ - Provides insight into the multidimensional relationships among multiple features.
43
+ - Assists in identifying trends, correlations, and outliers that could affect model performance.
44
+ - Validates assumptions made during model creation, such as linearity.
45
+ - Versatile for application in both regression and classification tasks.
46
+ - Using Seaborn facilitates an intuitive and detailed visual exploration of data.
47
+
48
+ ### Limitations
49
+
50
+ - Scatter plot matrices may become cluttered and hard to decipher as the number of features increases.
51
+ - Primarily reveals pairwise relationships and may fail to illuminate complex interactions involving three or more
52
+ features.
53
+ - Being a visual tool, precision in quantitative analysis might be compromised.
54
+ - Outliers not clearly visible in plots can be missed, affecting model performance.
55
+ - Assumes that the dataset can fit into the computer's memory, which might not be valid for extremely large
56
+ datasets.
51
57
  """
52
58
 
53
- name = "scatter_plot"
54
- required_inputs = ["dataset"]
55
- tasks = ["classification", "regression"]
56
- tags = ["tabular_data", "visualization"]
57
-
58
- def run(self):
59
- columns = list(self.inputs.dataset.df.columns)
60
-
61
- df = self.inputs.dataset.df[columns]
62
-
63
- if not set(columns).issubset(set(df.columns)):
64
- raise ValueError("Provided 'columns' must exist in the dataset")
65
-
66
- g = sns.pairplot(data=df, diag_kind="kde")
67
- for ax in g.axes.flatten():
68
- # rotate x axis labels
69
- ax.set_xlabel(ax.get_xlabel(), rotation=45)
70
- # rotate y axis labels
71
- ax.set_ylabel(ax.get_ylabel(), rotation=45)
72
- # set y labels alignment
73
- ax.yaxis.get_label().set_horizontalalignment("right")
74
- # Get the current figure
75
- fig = plt.gcf()
76
-
77
- figures = []
78
- figures.append(
79
- Figure(
80
- for_object=self,
81
- key=self.key,
82
- figure=fig,
83
- )
84
- )
85
-
86
- plt.close("all")
87
-
88
- return self.cache_results(
89
- figures=figures,
90
- )
59
+ g = sns.pairplot(data=dataset.df, diag_kind="kde")
60
+ for ax in g.axes.flatten():
61
+ # rotate x axis labels
62
+ ax.set_xlabel(ax.get_xlabel(), rotation=45)
63
+ # rotate y axis labels
64
+ ax.set_ylabel(ax.get_ylabel(), rotation=45)
65
+ # set y labels alignment
66
+ ax.yaxis.get_label().set_horizontalalignment("right")
67
+ # Get the current figure
68
+ fig = plt.gcf()
69
+
70
+ figures = []
71
+ figures.append(fig)
72
+
73
+ plt.close("all")
74
+
75
+ return tuple(figures)
@@ -19,41 +19,45 @@ logger = get_logger(__name__)
19
19
 
20
20
  class SeasonalDecompose(Metric):
21
21
  """
22
- Decomposes dataset features into observed, trend, seasonal, and residual components to identify patterns and
23
- validate dataset.
24
-
25
- **Purpose**: This test utilizes the Seasonal Decomposition of Time Series by Loess (STL) method to decompose a
26
- dataset into its fundamental components: observed, trend, seasonal, and residuals. The purpose is to identify
27
- implicit patterns, majorly any seasonality, in the dataset's features which aid in developing a more comprehensive
28
- understanding and effectively validating the dataset.
29
-
30
- **Test Mechanism**: The testing process exploits the `seasonal_decompose` function from the
31
- `statsmodels.tsa.seasonal` library to evaluate each feature in the dataset. It isolates each feature into four
32
- components: observed, trend, seasonal, and residuals, and generates essentially six subplot graphs per feature for
33
- visual interpretation of the results. Prior to the seasonal decomposition, non-finite values are scrutinized and
34
- removed thus, ensuring reliability in the analysis.
35
-
36
- **Signs of High Risk**:
37
- - **Non-Finiteness**: If a dataset carries too many non-finite values it might flag high risk as these values are
22
+ Assesses patterns and seasonality in a time series dataset by decomposing its features into foundational components.
23
+
24
+ ### Purpose
25
+
26
+ The Seasonal Decompose test aims to decompose the features of a time series dataset into their fundamental
27
+ components: observed, trend, seasonal, and residuals. By utilizing the Seasonal Decomposition of Time Series by
28
+ Loess (STL) method, the test identifies underlying patterns, predominantly seasonality, in the dataset's features.
29
+ This aids in developing a more comprehensive understanding of the dataset, which in turn facilitates more effective
30
+ model validation.
31
+
32
+ ### Test Mechanism
33
+
34
+ The testing process leverages the `seasonal_decompose` function from the `statsmodels.tsa.seasonal` library to
35
+ evaluate each feature in the dataset. It isolates each feature into four components—observed, trend, seasonal, and
36
+ residuals—and generates six subplot graphs per feature for visual interpretation. Prior to decomposition, the test
37
+ scrutinizes and removes any non-finite values, ensuring the reliability of the analysis.
38
+
39
+ ### Signs of High Risk
40
+
41
+ - **Non-Finiteness**: Datasets with a high number of non-finite values may flag as high risk since these values are
38
42
  omitted before conducting the seasonal decomposition.
39
- - **Frequent Warnings**: The test could be at risk if it chronically fails to infer frequency for a scrutinized
40
- feature.
41
- - **High Seasonality**: A high seasonal component could potentially render forecasts unreliable due to overwhelming
42
- seasonal variation.
43
-
44
- **Strengths**:
45
- - **Seasonality Detection**: The code aptly discerns hidden seasonality patterns in the features of datasets.
46
- - **Visualization**: The test facilitates interpretation and comprehension via graphical representations.
47
- - **Unrestricted Usage**: The code is not confined to any specific regression model, thereby promoting wide-ranging
48
- applicability.
49
-
50
- **Limitations**:
51
- - **Dependence on Assumptions**: The test presumes that features in the dataset are periodically distributed. If no
52
- frequency could be inferred for a variable, that feature is excluded from the test.
53
- - **Handling Non-finite Values**: The test disregards non-finite values during the analysis which could potentially
54
- result in incomplete understanding of the dataset.
55
- - **Unreliability with Noisy Datasets**: The test tends to produce unreliable results when used with heavy noise
56
- present in the dataset.
43
+ - **Frequent Warnings**: Chronic failure to infer the frequency for a scrutinized feature indicates high risk.
44
+ - **High Seasonality**: A significant seasonal component could potentially render forecasts unreliable due to
45
+ overwhelming seasonal variation.
46
+
47
+ ### Strengths
48
+
49
+ - **Seasonality Detection**: Accurately discerns hidden seasonality patterns in dataset features.
50
+ - **Visualization**: Facilitates interpretation and comprehension through graphical representations.
51
+ - **Unrestricted Usage**: Not confined to any specific regression model, promoting wide-ranging applicability.
52
+
53
+ ### Limitations
54
+
55
+ - **Dependence on Assumptions**: Assumes that dataset features are periodically distributed. Features with no
56
+ inferable frequency are excluded from the test.
57
+ - **Handling Non-Finite Values**: Disregards non-finite values during analysis, potentially resulting in an
58
+ incomplete understanding of the dataset.
59
+ - **Unreliability with Noisy Datasets**: Produces unreliable results when used with datasets that contain heavy
60
+ noise.
57
61
  """
58
62
 
59
63
  name = "seasonal_decompose"