validmind 2.8.10__py3-none-any.whl → 2.8.20__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 (189) hide show
  1. validmind/__init__.py +6 -5
  2. validmind/__version__.py +1 -1
  3. validmind/ai/test_descriptions.py +17 -11
  4. validmind/ai/utils.py +2 -2
  5. validmind/api_client.py +75 -32
  6. validmind/client.py +108 -100
  7. validmind/client_config.py +3 -3
  8. validmind/datasets/classification/__init__.py +7 -3
  9. validmind/datasets/credit_risk/lending_club.py +28 -16
  10. validmind/datasets/nlp/cnn_dailymail.py +10 -4
  11. validmind/datasets/regression/__init__.py +22 -5
  12. validmind/errors.py +17 -7
  13. validmind/input_registry.py +1 -1
  14. validmind/logging.py +44 -35
  15. validmind/models/foundation.py +2 -2
  16. validmind/models/function.py +10 -3
  17. validmind/template.py +30 -22
  18. validmind/test_suites/__init__.py +2 -2
  19. validmind/tests/_store.py +13 -4
  20. validmind/tests/comparison.py +65 -33
  21. validmind/tests/data_validation/ACFandPACFPlot.py +4 -1
  22. validmind/tests/data_validation/AutoMA.py +1 -1
  23. validmind/tests/data_validation/BivariateScatterPlots.py +5 -1
  24. validmind/tests/data_validation/BoxPierce.py +3 -1
  25. validmind/tests/data_validation/ClassImbalance.py +4 -2
  26. validmind/tests/data_validation/DatasetDescription.py +3 -24
  27. validmind/tests/data_validation/DescriptiveStatistics.py +1 -1
  28. validmind/tests/data_validation/DickeyFullerGLS.py +1 -1
  29. validmind/tests/data_validation/FeatureTargetCorrelationPlot.py +1 -1
  30. validmind/tests/data_validation/HighCardinality.py +5 -1
  31. validmind/tests/data_validation/HighPearsonCorrelation.py +1 -1
  32. validmind/tests/data_validation/IQROutliersBarPlot.py +5 -3
  33. validmind/tests/data_validation/IQROutliersTable.py +5 -2
  34. validmind/tests/data_validation/IsolationForestOutliers.py +5 -4
  35. validmind/tests/data_validation/JarqueBera.py +2 -2
  36. validmind/tests/data_validation/LJungBox.py +2 -2
  37. validmind/tests/data_validation/LaggedCorrelationHeatmap.py +1 -1
  38. validmind/tests/data_validation/MissingValues.py +14 -10
  39. validmind/tests/data_validation/MissingValuesBarPlot.py +3 -1
  40. validmind/tests/data_validation/MutualInformation.py +2 -1
  41. validmind/tests/data_validation/PearsonCorrelationMatrix.py +1 -1
  42. validmind/tests/data_validation/ProtectedClassesCombination.py +2 -0
  43. validmind/tests/data_validation/ProtectedClassesDescription.py +2 -2
  44. validmind/tests/data_validation/ProtectedClassesDisparity.py +9 -5
  45. validmind/tests/data_validation/ProtectedClassesThresholdOptimizer.py +10 -2
  46. validmind/tests/data_validation/RollingStatsPlot.py +2 -1
  47. validmind/tests/data_validation/ScoreBandDefaultRates.py +4 -2
  48. validmind/tests/data_validation/SeasonalDecompose.py +1 -1
  49. validmind/tests/data_validation/ShapiroWilk.py +2 -2
  50. validmind/tests/data_validation/Skewness.py +7 -6
  51. validmind/tests/data_validation/SpreadPlot.py +1 -1
  52. validmind/tests/data_validation/TabularCategoricalBarPlots.py +1 -1
  53. validmind/tests/data_validation/TabularDateTimeHistograms.py +1 -1
  54. validmind/tests/data_validation/TargetRateBarPlots.py +4 -1
  55. validmind/tests/data_validation/TimeSeriesFrequency.py +1 -1
  56. validmind/tests/data_validation/TimeSeriesOutliers.py +7 -2
  57. validmind/tests/data_validation/WOEBinPlots.py +1 -1
  58. validmind/tests/data_validation/WOEBinTable.py +1 -1
  59. validmind/tests/data_validation/ZivotAndrewsArch.py +5 -2
  60. validmind/tests/data_validation/nlp/CommonWords.py +1 -1
  61. validmind/tests/data_validation/nlp/Hashtags.py +1 -1
  62. validmind/tests/data_validation/nlp/LanguageDetection.py +1 -1
  63. validmind/tests/data_validation/nlp/Mentions.py +1 -1
  64. validmind/tests/data_validation/nlp/PolarityAndSubjectivity.py +5 -1
  65. validmind/tests/data_validation/nlp/Punctuations.py +1 -1
  66. validmind/tests/data_validation/nlp/Sentiment.py +3 -1
  67. validmind/tests/data_validation/nlp/TextDescription.py +1 -1
  68. validmind/tests/data_validation/nlp/Toxicity.py +1 -1
  69. validmind/tests/decorator.py +14 -11
  70. validmind/tests/load.py +38 -24
  71. validmind/tests/model_validation/BertScore.py +7 -1
  72. validmind/tests/model_validation/BleuScore.py +7 -1
  73. validmind/tests/model_validation/ClusterSizeDistribution.py +3 -1
  74. validmind/tests/model_validation/ContextualRecall.py +9 -1
  75. validmind/tests/model_validation/FeaturesAUC.py +1 -1
  76. validmind/tests/model_validation/MeteorScore.py +7 -1
  77. validmind/tests/model_validation/ModelPredictionResiduals.py +5 -1
  78. validmind/tests/model_validation/RegardScore.py +6 -1
  79. validmind/tests/model_validation/RegressionResidualsPlot.py +10 -1
  80. validmind/tests/model_validation/RougeScore.py +3 -1
  81. validmind/tests/model_validation/TimeSeriesPredictionWithCI.py +2 -0
  82. validmind/tests/model_validation/TimeSeriesPredictionsPlot.py +10 -2
  83. validmind/tests/model_validation/TimeSeriesR2SquareBySegments.py +6 -2
  84. validmind/tests/model_validation/TokenDisparity.py +5 -1
  85. validmind/tests/model_validation/ToxicityScore.py +2 -0
  86. validmind/tests/model_validation/embeddings/ClusterDistribution.py +1 -1
  87. validmind/tests/model_validation/embeddings/CosineSimilarityComparison.py +5 -1
  88. validmind/tests/model_validation/embeddings/CosineSimilarityDistribution.py +5 -1
  89. validmind/tests/model_validation/embeddings/CosineSimilarityHeatmap.py +5 -1
  90. validmind/tests/model_validation/embeddings/DescriptiveAnalytics.py +2 -0
  91. validmind/tests/model_validation/embeddings/EmbeddingsVisualization2D.py +5 -1
  92. validmind/tests/model_validation/embeddings/EuclideanDistanceComparison.py +6 -2
  93. validmind/tests/model_validation/embeddings/EuclideanDistanceHeatmap.py +3 -1
  94. validmind/tests/model_validation/embeddings/PCAComponentsPairwisePlots.py +4 -1
  95. validmind/tests/model_validation/embeddings/StabilityAnalysisKeyword.py +5 -1
  96. validmind/tests/model_validation/embeddings/StabilityAnalysisRandomNoise.py +5 -1
  97. validmind/tests/model_validation/embeddings/StabilityAnalysisSynonyms.py +5 -1
  98. validmind/tests/model_validation/embeddings/StabilityAnalysisTranslation.py +5 -1
  99. validmind/tests/model_validation/embeddings/TSNEComponentsPairwisePlots.py +6 -1
  100. validmind/tests/model_validation/ragas/AnswerCorrectness.py +5 -3
  101. validmind/tests/model_validation/ragas/AspectCritic.py +4 -1
  102. validmind/tests/model_validation/ragas/ContextEntityRecall.py +5 -3
  103. validmind/tests/model_validation/ragas/ContextPrecision.py +5 -3
  104. validmind/tests/model_validation/ragas/ContextPrecisionWithoutReference.py +5 -3
  105. validmind/tests/model_validation/ragas/ContextRecall.py +5 -3
  106. validmind/tests/model_validation/ragas/Faithfulness.py +5 -3
  107. validmind/tests/model_validation/ragas/NoiseSensitivity.py +1 -1
  108. validmind/tests/model_validation/ragas/ResponseRelevancy.py +5 -3
  109. validmind/tests/model_validation/ragas/SemanticSimilarity.py +5 -3
  110. validmind/tests/model_validation/sklearn/AdjustedMutualInformation.py +9 -9
  111. validmind/tests/model_validation/sklearn/AdjustedRandIndex.py +9 -9
  112. validmind/tests/model_validation/sklearn/CalibrationCurve.py +5 -2
  113. validmind/tests/model_validation/sklearn/ClassifierThresholdOptimization.py +28 -5
  114. validmind/tests/model_validation/sklearn/ClusterCosineSimilarity.py +5 -1
  115. validmind/tests/model_validation/sklearn/ClusterPerformanceMetrics.py +24 -14
  116. validmind/tests/model_validation/sklearn/CompletenessScore.py +8 -9
  117. validmind/tests/model_validation/sklearn/ConfusionMatrix.py +22 -3
  118. validmind/tests/model_validation/sklearn/FeatureImportance.py +6 -2
  119. validmind/tests/model_validation/sklearn/FowlkesMallowsScore.py +12 -9
  120. validmind/tests/model_validation/sklearn/HomogeneityScore.py +14 -9
  121. validmind/tests/model_validation/sklearn/HyperParametersTuning.py +4 -2
  122. validmind/tests/model_validation/sklearn/KMeansClustersOptimization.py +6 -1
  123. validmind/tests/model_validation/sklearn/MinimumAccuracy.py +12 -7
  124. validmind/tests/model_validation/sklearn/MinimumF1Score.py +12 -7
  125. validmind/tests/model_validation/sklearn/MinimumROCAUCScore.py +21 -6
  126. validmind/tests/model_validation/sklearn/OverfitDiagnosis.py +11 -3
  127. validmind/tests/model_validation/sklearn/PermutationFeatureImportance.py +5 -1
  128. validmind/tests/model_validation/sklearn/PopulationStabilityIndex.py +5 -1
  129. validmind/tests/model_validation/sklearn/PrecisionRecallCurve.py +6 -1
  130. validmind/tests/model_validation/sklearn/ROCCurve.py +3 -1
  131. validmind/tests/model_validation/sklearn/RegressionErrors.py +6 -2
  132. validmind/tests/model_validation/sklearn/RegressionPerformance.py +13 -8
  133. validmind/tests/model_validation/sklearn/RegressionR2Square.py +8 -5
  134. validmind/tests/model_validation/sklearn/RobustnessDiagnosis.py +5 -1
  135. validmind/tests/model_validation/sklearn/SHAPGlobalImportance.py +34 -26
  136. validmind/tests/model_validation/sklearn/ScoreProbabilityAlignment.py +10 -2
  137. validmind/tests/model_validation/sklearn/SilhouettePlot.py +5 -1
  138. validmind/tests/model_validation/sklearn/VMeasure.py +12 -9
  139. validmind/tests/model_validation/sklearn/WeakspotsDiagnosis.py +15 -10
  140. validmind/tests/model_validation/statsmodels/CumulativePredictionProbabilities.py +5 -1
  141. validmind/tests/model_validation/statsmodels/DurbinWatsonTest.py +6 -1
  142. validmind/tests/model_validation/statsmodels/GINITable.py +8 -1
  143. validmind/tests/model_validation/statsmodels/KolmogorovSmirnov.py +2 -2
  144. validmind/tests/model_validation/statsmodels/PredictionProbabilitiesHistogram.py +6 -2
  145. validmind/tests/model_validation/statsmodels/RegressionCoeffs.py +8 -2
  146. validmind/tests/model_validation/statsmodels/RegressionFeatureSignificance.py +3 -1
  147. validmind/tests/model_validation/statsmodels/RegressionModelForecastPlot.py +7 -2
  148. validmind/tests/model_validation/statsmodels/RegressionModelForecastPlotLevels.py +2 -0
  149. validmind/tests/model_validation/statsmodels/RegressionModelSensitivityPlot.py +2 -0
  150. validmind/tests/model_validation/statsmodels/RegressionModelSummary.py +4 -2
  151. validmind/tests/model_validation/statsmodels/RegressionPermutationFeatureImportance.py +3 -1
  152. validmind/tests/ongoing_monitoring/CalibrationCurveDrift.py +11 -1
  153. validmind/tests/ongoing_monitoring/ClassificationAccuracyDrift.py +10 -2
  154. validmind/tests/ongoing_monitoring/ConfusionMatrixDrift.py +8 -1
  155. validmind/tests/ongoing_monitoring/CumulativePredictionProbabilitiesDrift.py +18 -2
  156. validmind/tests/ongoing_monitoring/FeatureDrift.py +9 -2
  157. validmind/tests/ongoing_monitoring/PredictionAcrossEachFeature.py +8 -2
  158. validmind/tests/ongoing_monitoring/PredictionCorrelation.py +13 -2
  159. validmind/tests/ongoing_monitoring/PredictionProbabilitiesHistogramDrift.py +13 -2
  160. validmind/tests/ongoing_monitoring/ROCCurveDrift.py +16 -2
  161. validmind/tests/ongoing_monitoring/ScoreBandsDrift.py +11 -2
  162. validmind/tests/ongoing_monitoring/TargetPredictionDistributionPlot.py +13 -2
  163. validmind/tests/output.py +66 -11
  164. validmind/tests/prompt_validation/Clarity.py +1 -1
  165. validmind/tests/prompt_validation/NegativeInstruction.py +1 -1
  166. validmind/tests/prompt_validation/Robustness.py +6 -1
  167. validmind/tests/prompt_validation/Specificity.py +1 -1
  168. validmind/tests/run.py +28 -14
  169. validmind/tests/test_providers.py +28 -35
  170. validmind/tests/utils.py +17 -4
  171. validmind/unit_metrics/__init__.py +1 -1
  172. validmind/utils.py +295 -31
  173. validmind/vm_models/dataset/dataset.py +19 -16
  174. validmind/vm_models/dataset/utils.py +5 -3
  175. validmind/vm_models/figure.py +6 -6
  176. validmind/vm_models/input.py +6 -5
  177. validmind/vm_models/model.py +5 -5
  178. validmind/vm_models/result/result.py +122 -43
  179. validmind/vm_models/result/utils.py +9 -28
  180. validmind/vm_models/test_suite/__init__.py +5 -0
  181. validmind/vm_models/test_suite/runner.py +5 -5
  182. validmind/vm_models/test_suite/summary.py +20 -2
  183. validmind/vm_models/test_suite/test.py +6 -6
  184. validmind/vm_models/test_suite/test_suite.py +10 -10
  185. {validmind-2.8.10.dist-info → validmind-2.8.20.dist-info}/METADATA +4 -5
  186. {validmind-2.8.10.dist-info → validmind-2.8.20.dist-info}/RECORD +189 -188
  187. {validmind-2.8.10.dist-info → validmind-2.8.20.dist-info}/WHEEL +1 -1
  188. {validmind-2.8.10.dist-info → validmind-2.8.20.dist-info}/LICENSE +0 -0
  189. {validmind-2.8.10.dist-info → validmind-2.8.20.dist-info}/entry_points.txt +0 -0
validmind/client.py CHANGED
@@ -6,8 +6,12 @@
6
6
  Client interface for all data and model validation functions
7
7
  """
8
8
 
9
+ from typing import Any, Callable, Dict, List, Optional, Union
10
+
11
+ import numpy as np
9
12
  import pandas as pd
10
13
  import polars as pl
14
+ import torch
11
15
 
12
16
  from .api_client import log_input as log_input
13
17
  from .client_config import client_config
@@ -42,20 +46,22 @@ logger = get_logger(__name__)
42
46
 
43
47
 
44
48
  def init_dataset(
45
- dataset,
46
- model=None,
47
- index=None,
48
- index_name: str = None,
49
+ dataset: Union[
50
+ pd.DataFrame, pl.DataFrame, "np.ndarray", "torch.utils.data.TensorDataset"
51
+ ],
52
+ model: Optional[VMModel] = None,
53
+ index: Optional[Any] = None,
54
+ index_name: Optional[str] = None,
49
55
  date_time_index: bool = False,
50
- columns: list = None,
51
- text_column: str = None,
52
- target_column: str = None,
53
- feature_columns: list = None,
54
- extra_columns: dict = None,
55
- class_labels: dict = None,
56
- type: str = None,
57
- input_id: str = None,
58
- __log=True,
56
+ columns: Optional[List[str]] = None,
57
+ text_column: Optional[str] = None,
58
+ target_column: Optional[str] = None,
59
+ feature_columns: Optional[List[str]] = None,
60
+ extra_columns: Optional[Dict[str, Any]] = None,
61
+ class_labels: Optional[Dict[str, Any]] = None,
62
+ type: Optional[str] = None,
63
+ input_id: Optional[str] = None,
64
+ __log: bool = True,
59
65
  ) -> VMDataset:
60
66
  """
61
67
  Initializes a VM Dataset, which can then be passed to other functions
@@ -69,25 +75,30 @@ def init_dataset(
69
75
  - Torch TensorDataset
70
76
 
71
77
  Args:
72
- dataset : dataset from various python libraries
73
- model (VMModel): ValidMind model object
74
- targets (vm.vm.DatasetTargets): A list of target variables
75
- target_column (str): The name of the target column in the dataset
76
- feature_columns (list): A list of names of feature columns in the dataset
77
- extra_columns (dictionary): A dictionary containing the names of the
78
- prediction_column and group_by_columns in the dataset
79
- class_labels (dict): A list of class labels for classification problems
80
- type (str): The type of dataset (one of DATASET_TYPES)
81
- input_id (str): The input ID for the dataset (e.g. "my_dataset"). By default,
78
+ dataset: Dataset from various Python libraries.
79
+ model (VMModel): ValidMind model object.
80
+ index (Any, optional): Index for the dataset.
81
+ index_name (str, optional): Name of the index column.
82
+ date_time_index (bool): Whether the index is a datetime index.
83
+ columns (List[str], optional): List of column names.
84
+ text_column (str, optional): Name of the text column.
85
+ target_column (str, optional): The name of the target column in the dataset.
86
+ feature_columns (List[str], optional): A list of names of feature columns in the dataset.
87
+ extra_columns (Dict[str, Any], optional): A dictionary containing the names of the
88
+ prediction_column and group_by_columns in the dataset.
89
+ class_labels (Dict[str, Any], optional): A list of class labels for classification problems.
90
+ type (str, optional): The type of dataset (one of DATASET_TYPES) - DEPRECATED.
91
+ input_id (str, optional): The input ID for the dataset (e.g. "my_dataset"). By default,
82
92
  this will be set to `dataset` but if you are passing this dataset as a
83
93
  test input using some other key than `dataset`, then you should set
84
94
  this to the same key.
95
+ __log (bool): Whether to log the input. Defaults to True.
85
96
 
86
97
  Raises:
87
- ValueError: If the dataset type is not supported
98
+ ValueError: If the dataset type is not supported.
88
99
 
89
100
  Returns:
90
- vm.vm.Dataset: A VM Dataset instance
101
+ vm.vm.Dataset: A VM Dataset instance.
91
102
  """
92
103
  # Show deprecation notice if type is passed
93
104
  if type is not None:
@@ -171,12 +182,12 @@ def init_dataset(
171
182
 
172
183
 
173
184
  def init_model(
174
- model: object = None,
185
+ model: Optional[object] = None,
175
186
  input_id: str = "model",
176
- attributes: dict = None,
177
- predict_fn: callable = None,
178
- __log=True,
179
- **kwargs,
187
+ attributes: Optional[Dict[str, Any]] = None,
188
+ predict_fn: Optional[Callable] = None,
189
+ __log: bool = True,
190
+ **kwargs: Any,
180
191
  ) -> VMModel:
181
192
  """
182
193
  Initializes a VM Model, which can then be passed to other functions
@@ -184,35 +195,21 @@ def init_model(
184
195
  also ensures we are creating a model supported libraries.
185
196
 
186
197
  Args:
187
- model: A trained model or VMModel instance
198
+ model: A trained model or VMModel instance.
188
199
  input_id (str): The input ID for the model (e.g. "my_model"). By default,
189
200
  this will be set to `model` but if you are passing this model as a
190
201
  test input using some other key than `model`, then you should set
191
202
  this to the same key.
192
- attributes (dict): A dictionary of model attributes
193
- predict_fn (callable): A function that takes an input and returns a prediction
194
- **kwargs: Additional arguments to pass to the model
203
+ attributes (dict): A dictionary of model attributes.
204
+ predict_fn (callable): A function that takes an input and returns a prediction.
205
+ **kwargs: Additional arguments to pass to the model.
195
206
 
196
207
  Raises:
197
- ValueError: If the model type is not supported
208
+ ValueError: If the model type is not supported.
198
209
 
199
210
  Returns:
200
- vm.VMModel: A VM Model instance
211
+ vm.VMModel: A VM Model instance.
201
212
  """
202
- # vm_model = model if isinstance(model, VMModel) else None
203
- # metadata = None
204
-
205
- # if not vm_model:
206
- # class_obj = get_model_class(model=model, predict_fn=predict_fn)
207
- # if not class_obj:
208
- # if not attributes:
209
- # raise UnsupportedModelError(
210
- # f"Model class {str(model.__class__)} is not supported at the moment."
211
- # )
212
- # elif not is_model_metadata(attributes):
213
- # raise UnsupportedModelError(
214
- # f"Model attributes {str(attributes)} are missing required keys 'architecture' and 'language'."
215
- # )
216
213
  vm_model = model if isinstance(model, VMModel) else None
217
214
  class_obj = get_model_class(model=model, predict_fn=predict_fn)
218
215
 
@@ -276,26 +273,18 @@ def init_r_model(
276
273
  input_id: str = "model",
277
274
  ) -> VMModel:
278
275
  """
279
- Initializes a VM Model for an R model
280
-
281
- R models must be saved to disk and the filetype depends on the model type...
282
- Currently we support the following model types:
283
-
284
- - LogisticRegression `glm` model in R: saved as an RDS file with `saveRDS`
285
- - LinearRegression `lm` model in R: saved as an RDS file with `saveRDS`
286
- - XGBClassifier: saved as a .json or .bin file with `xgb.save`
287
- - XGBRegressor: saved as a .json or .bin file with `xgb.save`
276
+ Initialize a VM Model from an R model.
288
277
 
289
278
  LogisticRegression and LinearRegression models are converted to sklearn models by extracting
290
279
  the coefficients and intercept from the R model. XGB models are loaded using the xgboost
291
- since xgb models saved in .json or .bin format can be loaded directly with either Python or R
280
+ since xgb models saved in .json or .bin format can be loaded directly with either Python or R.
292
281
 
293
282
  Args:
294
- model_path (str): The path to the R model saved as an RDS or XGB file
295
- model_type (str): The type of the model (one of R_MODEL_TYPES)
283
+ model_path (str): The path to the R model saved as an RDS or XGB file.
284
+ input_id (str): The input ID for the model. Defaults to "model".
296
285
 
297
286
  Returns:
298
- vm.vm.Model: A VM Model instance
287
+ VMModel: A VM Model instance.
299
288
  """
300
289
 
301
290
  # TODO: proper check for supported models
@@ -329,12 +318,12 @@ def init_r_model(
329
318
 
330
319
 
331
320
  def get_test_suite(
332
- test_suite_id: str = None,
333
- section: str = None,
334
- *args,
335
- **kwargs,
321
+ test_suite_id: Optional[str] = None,
322
+ section: Optional[str] = None,
323
+ *args: Any,
324
+ **kwargs: Any,
336
325
  ) -> TestSuite:
337
- """Gets a TestSuite object for the current project or a specific test suite
326
+ """Gets a TestSuite object for the current project or a specific test suite.
338
327
 
339
328
  This function provides an interface to retrieve the TestSuite instance for the
340
329
  current project or a specific TestSuite instance identified by test_suite_id.
@@ -348,8 +337,11 @@ def get_test_suite(
348
337
  section (str, optional): The section of the documentation template from which
349
338
  to retrieve the test suite. This only applies if test_suite_id is None.
350
339
  Defaults to None.
351
- args: Additional arguments to pass to the TestSuite
352
- kwargs: Additional keyword arguments to pass to the TestSuite
340
+ args: Additional arguments to pass to the TestSuite.
341
+ kwargs: Additional keyword arguments to pass to the TestSuite.
342
+
343
+ Returns:
344
+ TestSuite: The TestSuite instance.
353
345
  """
354
346
  if test_suite_id is None:
355
347
  if client_config.documentation_template is None:
@@ -365,31 +357,36 @@ def get_test_suite(
365
357
 
366
358
 
367
359
  def run_test_suite(
368
- test_suite_id, send=True, fail_fast=False, config=None, inputs=None, **kwargs
369
- ):
370
- """High Level function for running a test suite
360
+ test_suite_id: str,
361
+ send: bool = True,
362
+ fail_fast: bool = False,
363
+ config: Optional[Dict[str, Any]] = None,
364
+ inputs: Optional[Dict[str, Any]] = None,
365
+ **kwargs: Any,
366
+ ) -> TestSuite:
367
+ """High Level function for running a test suite.
371
368
 
372
369
  This function provides a high level interface for running a test suite. A test suite is
373
370
  a collection of tests. This function will automatically find the correct test suite
374
371
  class based on the test_suite_id, initialize each of the tests, and run them.
375
372
 
376
373
  Args:
377
- test_suite_id (str): The test suite name (e.g. 'classifier_full_suite')
374
+ test_suite_id (str): The test suite name. For example, 'classifier_full_suite'.
378
375
  config (dict, optional): A dictionary of parameters to pass to the tests in the
379
376
  test suite. Defaults to None.
380
377
  send (bool, optional): Whether to post the test results to the API. send=False
381
378
  is useful for testing. Defaults to True.
382
379
  fail_fast (bool, optional): Whether to stop running tests after the first failure. Defaults to False.
383
- inputs (dict, optional): A dictionary of test inputs to pass to the TestSuite e.g. `model`, `dataset`
384
- `models` etc. These inputs will be accessible by any test in the test suite. See the test
385
- documentation or `vm.describe_test()` for more details on the inputs required for each.
386
- **kwargs: backwards compatibility for passing in test inputs using keyword arguments
380
+ inputs (dict, optional): A dictionary of test inputs to pass to the TestSuite, such as `model`, `dataset`
381
+ `models`, etc. These inputs will be accessible by any test in the test suite. See the test
382
+ documentation or `vm.describe_test()` for more details on the inputs required for each. Defaults to None.
383
+ **kwargs: backwards compatibility for passing in test inputs using keyword arguments.
387
384
 
388
385
  Raises:
389
- ValueError: If the test suite name is not found or if there is an error initializing the test suite
386
+ ValueError: If the test suite name is not found or if there is an error initializing the test suite.
390
387
 
391
388
  Returns:
392
- TestSuite: the TestSuite instance
389
+ TestSuite: The TestSuite instance.
393
390
  """
394
391
  try:
395
392
  Suite: TestSuite = get_test_suite_by_id(test_suite_id)
@@ -414,14 +411,14 @@ def run_test_suite(
414
411
  return suite
415
412
 
416
413
 
417
- def preview_template():
418
- """Preview the documentation template for the current project
414
+ def preview_template() -> None:
415
+ """Preview the documentation template for the current project.
419
416
 
420
417
  This function will display the documentation template for the current project. If
421
418
  the project has not been initialized, then an error will be raised.
422
419
 
423
420
  Raises:
424
- ValueError: If the project has not been initialized
421
+ ValueError: If the project has not been initialized.
425
422
  """
426
423
  if client_config.documentation_template is None:
427
424
  raise MissingDocumentationTemplate(
@@ -432,9 +429,14 @@ def preview_template():
432
429
 
433
430
 
434
431
  def run_documentation_tests(
435
- section=None, send=True, fail_fast=False, inputs=None, config=None, **kwargs
436
- ):
437
- """Collect and run all the tests associated with a template
432
+ section: Optional[str] = None,
433
+ send: bool = True,
434
+ fail_fast: bool = False,
435
+ inputs: Optional[Dict[str, Any]] = None,
436
+ config: Optional[Dict[str, Any]] = None,
437
+ **kwargs: Any,
438
+ ) -> Union[TestSuite, Dict[str, TestSuite]]:
439
+ """Collect and run all the tests associated with a template.
438
440
 
439
441
  This function will analyze the current project's documentation template and collect
440
442
  all the tests associated with it into a test suite. It will then run the test
@@ -444,15 +446,15 @@ def run_documentation_tests(
444
446
  section (str or list, optional): The section(s) to preview. Defaults to None.
445
447
  send (bool, optional): Whether to send the results to the ValidMind API. Defaults to True.
446
448
  fail_fast (bool, optional): Whether to stop running tests after the first failure. Defaults to False.
447
- inputs (dict, optional): A dictionary of test inputs to pass to the TestSuite
448
- config: A dictionary of test parameters to override the defaults
449
- **kwargs: backwards compatibility for passing in test inputs using keyword arguments
449
+ inputs (dict, optional): A dictionary of test inputs to pass to the TestSuite.
450
+ config: A dictionary of test parameters to override the defaults.
451
+ **kwargs: backwards compatibility for passing in test inputs using keyword arguments.
450
452
 
451
453
  Returns:
452
454
  TestSuite or dict: The completed TestSuite instance or a dictionary of TestSuites if section is a list.
453
455
 
454
456
  Raises:
455
- ValueError: If the project has not been initialized
457
+ ValueError: If the project has not been initialized.
456
458
  """
457
459
  if client_config.documentation_template is None:
458
460
  raise MissingDocumentationTemplate(
@@ -487,24 +489,30 @@ def run_documentation_tests(
487
489
 
488
490
 
489
491
  def _run_documentation_section(
490
- template, section, send=True, fail_fast=False, config=None, inputs=None, **kwargs
491
- ):
492
- """Run all tests in a template section
492
+ template: str,
493
+ section: str,
494
+ send: bool = True,
495
+ fail_fast: bool = False,
496
+ config: Optional[Dict[str, Any]] = None,
497
+ inputs: Optional[Dict[str, Any]] = None,
498
+ **kwargs: Any,
499
+ ) -> TestSuite:
500
+ """Run all tests in a template section.
493
501
 
494
502
  This function will collect all tests used in a template section into a TestSuite and then
495
503
  run the TestSuite as usual.
496
504
 
497
505
  Args:
498
- template: A valid flat template
499
- section: The section of the template to run (if not provided, run all sections)
500
- send: Whether to send the results to the ValidMind API
506
+ template: A valid flat template.
507
+ section: The section of the template to run (if not provided, run all sections).
508
+ send: Whether to send the results to the ValidMind API.
501
509
  fail_fast (bool, optional): Whether to stop running tests after the first failure. Defaults to False.
502
- config: A dictionary of test parameters to override the defaults
503
- inputs: A dictionary of test inputs to pass to the TestSuite
504
- **kwargs: backwards compatibility for passing in test inputs using keyword arguments
510
+ config: A dictionary of test parameters to override the defaults.
511
+ inputs: A dictionary of test inputs to pass to the TestSuite.
512
+ **kwargs: backwards compatibility for passing in test inputs using keyword arguments.
505
513
 
506
514
  Returns:
507
- The completed TestSuite instance
515
+ The completed TestSuite instance.
508
516
  """
509
517
  test_suite = get_template_test_suite(template, section)
510
518
 
@@ -13,7 +13,7 @@ from dataclasses import dataclass
13
13
  @dataclass
14
14
  class ClientConfig:
15
15
  """
16
- Configuration class for the ValidMind API client. This is instantiated
16
+ Configuration class for the ValidMind API client. This class is instantiated
17
17
  when initializing the API client.
18
18
  """
19
19
 
@@ -25,7 +25,7 @@ class ClientConfig:
25
25
 
26
26
  def __post_init__(self):
27
27
  """
28
- Set additional attributes when initializing the class
28
+ Set additional attributes when initializing the class.
29
29
  """
30
30
  # check if running on notebook and set running_on_colab
31
31
  try:
@@ -36,7 +36,7 @@ class ClientConfig:
36
36
  self.running_on_colab = False
37
37
 
38
38
  def can_generate_llm_test_descriptions(self):
39
- """Returns True if the client can generate LLM based test descriptions"""
39
+ """Returns True if the client can generate LLM-based test descriptions."""
40
40
  return self.feature_flags.get("llm_test_descriptions", True)
41
41
 
42
42
 
@@ -5,6 +5,8 @@
5
5
  """
6
6
  Entrypoint for classification datasets.
7
7
  """
8
+ from typing import List
9
+
8
10
  import pandas as pd
9
11
 
10
12
  __all__ = [
@@ -13,7 +15,7 @@ __all__ = [
13
15
  ]
14
16
 
15
17
 
16
- def simple_preprocess_booleans(df, columns):
18
+ def simple_preprocess_booleans(df: pd.DataFrame, columns: List[str]) -> pd.DataFrame:
17
19
  """
18
20
  Preprocess boolean columns.
19
21
 
@@ -36,7 +38,9 @@ def simple_preprocess_booleans(df, columns):
36
38
  return df
37
39
 
38
40
 
39
- def simple_preprocess_categoricals(df, columns):
41
+ def simple_preprocess_categoricals(
42
+ df: pd.DataFrame, columns: List[str]
43
+ ) -> pd.DataFrame:
40
44
  """
41
45
  Preprocess categorical columns.
42
46
 
@@ -56,7 +60,7 @@ def simple_preprocess_categoricals(df, columns):
56
60
  return df
57
61
 
58
62
 
59
- def simple_preprocess_numericals(df, columns):
63
+ def simple_preprocess_numericals(df: pd.DataFrame, columns: List[str]) -> pd.DataFrame:
60
64
  """
61
65
  Preprocess numerical columns.
62
66
 
@@ -5,6 +5,7 @@
5
5
  import logging
6
6
  import os
7
7
  import warnings
8
+ from typing import Any, Dict, Optional, Tuple
8
9
 
9
10
  import numpy as np
10
11
  import pandas as pd
@@ -101,12 +102,15 @@ score_params = {
101
102
  }
102
103
 
103
104
 
104
- def load_data(source="online", verbose=True):
105
+ def load_data(source: str = "online", verbose: bool = True) -> pd.DataFrame:
105
106
  """
106
107
  Load data from either an online source or offline files, automatically dropping specified columns for offline data.
107
108
 
108
- :param source: 'online' for online data, 'offline' for offline files. Defaults to 'online'.
109
- :return: DataFrame containing the loaded data.
109
+ Args:
110
+ source: 'online' for online data, 'offline' for offline files. Defaults to 'online'.
111
+
112
+ Returns:
113
+ DataFrame: DataFrame containing the loaded data.
110
114
  """
111
115
 
112
116
  if source == "online":
@@ -136,7 +140,7 @@ def load_data(source="online", verbose=True):
136
140
  return df
137
141
 
138
142
 
139
- def _clean_data(df, verbose=True):
143
+ def _clean_data(df: pd.DataFrame, verbose: bool = True) -> pd.DataFrame:
140
144
  df = df.copy()
141
145
 
142
146
  # Drop columns not relevant for application scorecards
@@ -182,7 +186,7 @@ def _clean_data(df, verbose=True):
182
186
  return df
183
187
 
184
188
 
185
- def preprocess(df, verbose=True):
189
+ def preprocess(df: pd.DataFrame, verbose: bool = True) -> pd.DataFrame:
186
190
  df = df.copy()
187
191
 
188
192
  # Convert the target variable to integer type for modeling.
@@ -245,7 +249,7 @@ def preprocess(df, verbose=True):
245
249
  return df
246
250
 
247
251
 
248
- def _preprocess_term(df):
252
+ def _preprocess_term(df: pd.DataFrame) -> pd.DataFrame:
249
253
  df = df.copy()
250
254
 
251
255
  # Remove ' months' and convert to integer
@@ -254,7 +258,7 @@ def _preprocess_term(df):
254
258
  return df
255
259
 
256
260
 
257
- def _preprocess_emp_length(df):
261
+ def _preprocess_emp_length(df: pd.DataFrame) -> pd.DataFrame:
258
262
  df = df.copy()
259
263
 
260
264
  # Mapping string values to numbers
@@ -281,7 +285,7 @@ def _preprocess_emp_length(df):
281
285
  return df
282
286
 
283
287
 
284
- def feature_engineering(df, verbose=True):
288
+ def feature_engineering(df: pd.DataFrame, verbose: bool = True) -> pd.DataFrame:
285
289
  df = df.copy()
286
290
 
287
291
  # WoE encoding of numerical and categorical features
@@ -295,7 +299,7 @@ def feature_engineering(df, verbose=True):
295
299
  return df
296
300
 
297
301
 
298
- def woe_encoding(df, verbose=True):
302
+ def woe_encoding(df: pd.DataFrame, verbose: bool = True) -> pd.DataFrame:
299
303
  df = df.copy()
300
304
 
301
305
  woe = _woebin(df, verbose=verbose)
@@ -316,7 +320,7 @@ def woe_encoding(df, verbose=True):
316
320
  return df
317
321
 
318
322
 
319
- def _woe_to_bins(woe):
323
+ def _woe_to_bins(woe: Dict[str, Any]) -> Dict[str, Any]:
320
324
  # Select and rename columns
321
325
  transformed_df = woe[
322
326
  [
@@ -350,7 +354,7 @@ def _woe_to_bins(woe):
350
354
  return bins
351
355
 
352
356
 
353
- def _woebin(df, verbose=True):
357
+ def _woebin(df: pd.DataFrame, verbose: bool = True) -> Dict[str, Any]:
354
358
  """
355
359
  This function performs automatic binning using WoE.
356
360
  df: A pandas dataframe
@@ -380,7 +384,13 @@ def _woebin(df, verbose=True):
380
384
  return bins_df
381
385
 
382
386
 
383
- def split(df, validation_size=None, test_size=0.2, add_constant=False, verbose=True):
387
+ def split(
388
+ df: pd.DataFrame,
389
+ validation_split: Optional[float] = None,
390
+ test_size: float = 0.2,
391
+ add_constant: bool = False,
392
+ verbose: bool = True,
393
+ ) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
384
394
  """
385
395
  Split dataset into train, validation (optional), and test sets.
386
396
 
@@ -404,7 +414,7 @@ def split(df, validation_size=None, test_size=0.2, add_constant=False, verbose=T
404
414
  if add_constant:
405
415
  test_df = sm.add_constant(test_df)
406
416
 
407
- if validation_size is None:
417
+ if validation_split is None:
408
418
  if add_constant:
409
419
  train_val_df = sm.add_constant(train_val_df)
410
420
 
@@ -423,7 +433,7 @@ def split(df, validation_size=None, test_size=0.2, add_constant=False, verbose=T
423
433
  return train_val_df, test_df
424
434
 
425
435
  # Calculate validation size as proportion of remaining data
426
- val_size = validation_size / (1 - test_size)
436
+ val_size = validation_split / (1 - test_size)
427
437
  train_df, validation_df = train_test_split(
428
438
  train_val_df, test_size=val_size, random_state=42
429
439
  )
@@ -451,7 +461,7 @@ def split(df, validation_size=None, test_size=0.2, add_constant=False, verbose=T
451
461
  return train_df, validation_df, test_df
452
462
 
453
463
 
454
- def compute_scores(probabilities):
464
+ def compute_scores(probabilities: np.ndarray) -> np.ndarray:
455
465
  target_score = score_params["target_score"]
456
466
  target_odds = score_params["target_odds"]
457
467
  pdo = score_params["pdo"]
@@ -465,7 +475,9 @@ def compute_scores(probabilities):
465
475
  return scores
466
476
 
467
477
 
468
- def get_demo_test_config(x_test=None, y_test=None):
478
+ def get_demo_test_config(
479
+ x_test: Optional[np.ndarray] = None, y_test: Optional[np.ndarray] = None
480
+ ) -> Dict[str, Any]:
469
481
  """Get demo test configuration.
470
482
 
471
483
  Args:
@@ -4,6 +4,7 @@
4
4
 
5
5
  import os
6
6
  import textwrap
7
+ from typing import Optional, Tuple
7
8
 
8
9
  import pandas as pd
9
10
  from datasets import load_dataset
@@ -22,13 +23,18 @@ current_path = os.path.dirname(os.path.abspath(__file__))
22
23
  dataset_path = os.path.join(current_path, "datasets")
23
24
 
24
25
 
25
- def load_data(source="online", dataset_size=None):
26
+ def load_data(
27
+ source: str = "online", dataset_size: Optional[str] = None
28
+ ) -> Tuple[pd.DataFrame, pd.DataFrame]:
26
29
  """
27
30
  Load data from either online source or offline files.
28
31
 
29
- :param source: 'online' for online data, 'offline' for offline data. Defaults to 'online'.
30
- :param dataset_size: Applicable if source is 'offline'. '300k' or '500k' for dataset size. Defaults to None.
31
- :return: DataFrame containing the loaded data.
32
+ Args:
33
+ source: 'online' for online data, 'offline' for offline data. Defaults to 'online'.
34
+ dataset_size: Applicable if source is 'offline'. '300k' or '500k' for dataset size. Defaults to None.
35
+
36
+ Returns:
37
+ Tuple containing (train_df, test_df) DataFrames with the loaded data.
32
38
  """
33
39
  if source == "online":
34
40
  # Load online data without predictions
@@ -5,20 +5,25 @@
5
5
  """
6
6
  Entrypoint for regression datasets
7
7
  """
8
+ from typing import List
9
+
8
10
  import pandas as pd
9
11
 
10
- __all__ = [
12
+ __all__: List[str] = [
11
13
  "fred",
12
14
  "lending_club",
13
15
  ]
14
16
 
15
17
 
16
- def identify_frequencies(df):
18
+ def identify_frequencies(df: pd.DataFrame) -> pd.DataFrame:
17
19
  """
18
20
  Identify the frequency of each series in the DataFrame.
19
21
 
20
- :param df: Time-series DataFrame
21
- :return: DataFrame with two columns: 'Variable' and 'Frequency'
22
+ Args:
23
+ df: Time-series DataFrame.
24
+
25
+ Returns:
26
+ DataFrame with two columns: "Variable" and "Frequency".
22
27
  """
23
28
  frequencies = []
24
29
  for column in df.columns:
@@ -36,7 +41,19 @@ def identify_frequencies(df):
36
41
  return freq_df
37
42
 
38
43
 
39
- def resample_to_common_frequency(df, common_frequency="MS"):
44
+ def resample_to_common_frequency(
45
+ df: pd.DataFrame, common_frequency: str = "MS"
46
+ ) -> pd.DataFrame:
47
+ """
48
+ Resample time series data to a common frequency.
49
+
50
+ Args:
51
+ df: Time-series DataFrame.
52
+ common_frequency: Target frequency for resampling. Defaults to "MS" (month start).
53
+
54
+ Returns:
55
+ DataFrame with data resampled to the common frequency.
56
+ """
40
57
  # Make sure the index is a datetime index
41
58
  if not isinstance(df.index, pd.DatetimeIndex):
42
59
  df.index = pd.to_datetime(df.index)