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.
- validmind/__init__.py +6 -5
- validmind/__version__.py +1 -1
- validmind/ai/test_descriptions.py +17 -11
- validmind/ai/utils.py +2 -2
- validmind/api_client.py +75 -32
- validmind/client.py +108 -100
- validmind/client_config.py +3 -3
- validmind/datasets/classification/__init__.py +7 -3
- validmind/datasets/credit_risk/lending_club.py +28 -16
- validmind/datasets/nlp/cnn_dailymail.py +10 -4
- validmind/datasets/regression/__init__.py +22 -5
- validmind/errors.py +17 -7
- validmind/input_registry.py +1 -1
- validmind/logging.py +44 -35
- validmind/models/foundation.py +2 -2
- validmind/models/function.py +10 -3
- validmind/template.py +30 -22
- validmind/test_suites/__init__.py +2 -2
- validmind/tests/_store.py +13 -4
- validmind/tests/comparison.py +65 -33
- validmind/tests/data_validation/ACFandPACFPlot.py +4 -1
- validmind/tests/data_validation/AutoMA.py +1 -1
- validmind/tests/data_validation/BivariateScatterPlots.py +5 -1
- validmind/tests/data_validation/BoxPierce.py +3 -1
- validmind/tests/data_validation/ClassImbalance.py +4 -2
- validmind/tests/data_validation/DatasetDescription.py +3 -24
- validmind/tests/data_validation/DescriptiveStatistics.py +1 -1
- validmind/tests/data_validation/DickeyFullerGLS.py +1 -1
- validmind/tests/data_validation/FeatureTargetCorrelationPlot.py +1 -1
- validmind/tests/data_validation/HighCardinality.py +5 -1
- validmind/tests/data_validation/HighPearsonCorrelation.py +1 -1
- validmind/tests/data_validation/IQROutliersBarPlot.py +5 -3
- validmind/tests/data_validation/IQROutliersTable.py +5 -2
- validmind/tests/data_validation/IsolationForestOutliers.py +5 -4
- validmind/tests/data_validation/JarqueBera.py +2 -2
- validmind/tests/data_validation/LJungBox.py +2 -2
- validmind/tests/data_validation/LaggedCorrelationHeatmap.py +1 -1
- validmind/tests/data_validation/MissingValues.py +14 -10
- validmind/tests/data_validation/MissingValuesBarPlot.py +3 -1
- validmind/tests/data_validation/MutualInformation.py +2 -1
- validmind/tests/data_validation/PearsonCorrelationMatrix.py +1 -1
- validmind/tests/data_validation/ProtectedClassesCombination.py +2 -0
- validmind/tests/data_validation/ProtectedClassesDescription.py +2 -2
- validmind/tests/data_validation/ProtectedClassesDisparity.py +9 -5
- validmind/tests/data_validation/ProtectedClassesThresholdOptimizer.py +10 -2
- validmind/tests/data_validation/RollingStatsPlot.py +2 -1
- validmind/tests/data_validation/ScoreBandDefaultRates.py +4 -2
- validmind/tests/data_validation/SeasonalDecompose.py +1 -1
- validmind/tests/data_validation/ShapiroWilk.py +2 -2
- validmind/tests/data_validation/Skewness.py +7 -6
- validmind/tests/data_validation/SpreadPlot.py +1 -1
- validmind/tests/data_validation/TabularCategoricalBarPlots.py +1 -1
- validmind/tests/data_validation/TabularDateTimeHistograms.py +1 -1
- validmind/tests/data_validation/TargetRateBarPlots.py +4 -1
- validmind/tests/data_validation/TimeSeriesFrequency.py +1 -1
- validmind/tests/data_validation/TimeSeriesOutliers.py +7 -2
- validmind/tests/data_validation/WOEBinPlots.py +1 -1
- validmind/tests/data_validation/WOEBinTable.py +1 -1
- validmind/tests/data_validation/ZivotAndrewsArch.py +5 -2
- validmind/tests/data_validation/nlp/CommonWords.py +1 -1
- validmind/tests/data_validation/nlp/Hashtags.py +1 -1
- validmind/tests/data_validation/nlp/LanguageDetection.py +1 -1
- validmind/tests/data_validation/nlp/Mentions.py +1 -1
- validmind/tests/data_validation/nlp/PolarityAndSubjectivity.py +5 -1
- validmind/tests/data_validation/nlp/Punctuations.py +1 -1
- validmind/tests/data_validation/nlp/Sentiment.py +3 -1
- validmind/tests/data_validation/nlp/TextDescription.py +1 -1
- validmind/tests/data_validation/nlp/Toxicity.py +1 -1
- validmind/tests/decorator.py +14 -11
- validmind/tests/load.py +38 -24
- validmind/tests/model_validation/BertScore.py +7 -1
- validmind/tests/model_validation/BleuScore.py +7 -1
- validmind/tests/model_validation/ClusterSizeDistribution.py +3 -1
- validmind/tests/model_validation/ContextualRecall.py +9 -1
- validmind/tests/model_validation/FeaturesAUC.py +1 -1
- validmind/tests/model_validation/MeteorScore.py +7 -1
- validmind/tests/model_validation/ModelPredictionResiduals.py +5 -1
- validmind/tests/model_validation/RegardScore.py +6 -1
- validmind/tests/model_validation/RegressionResidualsPlot.py +10 -1
- validmind/tests/model_validation/RougeScore.py +3 -1
- validmind/tests/model_validation/TimeSeriesPredictionWithCI.py +2 -0
- validmind/tests/model_validation/TimeSeriesPredictionsPlot.py +10 -2
- validmind/tests/model_validation/TimeSeriesR2SquareBySegments.py +6 -2
- validmind/tests/model_validation/TokenDisparity.py +5 -1
- validmind/tests/model_validation/ToxicityScore.py +2 -0
- validmind/tests/model_validation/embeddings/ClusterDistribution.py +1 -1
- validmind/tests/model_validation/embeddings/CosineSimilarityComparison.py +5 -1
- validmind/tests/model_validation/embeddings/CosineSimilarityDistribution.py +5 -1
- validmind/tests/model_validation/embeddings/CosineSimilarityHeatmap.py +5 -1
- validmind/tests/model_validation/embeddings/DescriptiveAnalytics.py +2 -0
- validmind/tests/model_validation/embeddings/EmbeddingsVisualization2D.py +5 -1
- validmind/tests/model_validation/embeddings/EuclideanDistanceComparison.py +6 -2
- validmind/tests/model_validation/embeddings/EuclideanDistanceHeatmap.py +3 -1
- validmind/tests/model_validation/embeddings/PCAComponentsPairwisePlots.py +4 -1
- validmind/tests/model_validation/embeddings/StabilityAnalysisKeyword.py +5 -1
- validmind/tests/model_validation/embeddings/StabilityAnalysisRandomNoise.py +5 -1
- validmind/tests/model_validation/embeddings/StabilityAnalysisSynonyms.py +5 -1
- validmind/tests/model_validation/embeddings/StabilityAnalysisTranslation.py +5 -1
- validmind/tests/model_validation/embeddings/TSNEComponentsPairwisePlots.py +6 -1
- validmind/tests/model_validation/ragas/AnswerCorrectness.py +5 -3
- validmind/tests/model_validation/ragas/AspectCritic.py +4 -1
- validmind/tests/model_validation/ragas/ContextEntityRecall.py +5 -3
- validmind/tests/model_validation/ragas/ContextPrecision.py +5 -3
- validmind/tests/model_validation/ragas/ContextPrecisionWithoutReference.py +5 -3
- validmind/tests/model_validation/ragas/ContextRecall.py +5 -3
- validmind/tests/model_validation/ragas/Faithfulness.py +5 -3
- validmind/tests/model_validation/ragas/NoiseSensitivity.py +1 -1
- validmind/tests/model_validation/ragas/ResponseRelevancy.py +5 -3
- validmind/tests/model_validation/ragas/SemanticSimilarity.py +5 -3
- validmind/tests/model_validation/sklearn/AdjustedMutualInformation.py +9 -9
- validmind/tests/model_validation/sklearn/AdjustedRandIndex.py +9 -9
- validmind/tests/model_validation/sklearn/CalibrationCurve.py +5 -2
- validmind/tests/model_validation/sklearn/ClassifierThresholdOptimization.py +28 -5
- validmind/tests/model_validation/sklearn/ClusterCosineSimilarity.py +5 -1
- validmind/tests/model_validation/sklearn/ClusterPerformanceMetrics.py +24 -14
- validmind/tests/model_validation/sklearn/CompletenessScore.py +8 -9
- validmind/tests/model_validation/sklearn/ConfusionMatrix.py +22 -3
- validmind/tests/model_validation/sklearn/FeatureImportance.py +6 -2
- validmind/tests/model_validation/sklearn/FowlkesMallowsScore.py +12 -9
- validmind/tests/model_validation/sklearn/HomogeneityScore.py +14 -9
- validmind/tests/model_validation/sklearn/HyperParametersTuning.py +4 -2
- validmind/tests/model_validation/sklearn/KMeansClustersOptimization.py +6 -1
- validmind/tests/model_validation/sklearn/MinimumAccuracy.py +12 -7
- validmind/tests/model_validation/sklearn/MinimumF1Score.py +12 -7
- validmind/tests/model_validation/sklearn/MinimumROCAUCScore.py +21 -6
- validmind/tests/model_validation/sklearn/OverfitDiagnosis.py +11 -3
- validmind/tests/model_validation/sklearn/PermutationFeatureImportance.py +5 -1
- validmind/tests/model_validation/sklearn/PopulationStabilityIndex.py +5 -1
- validmind/tests/model_validation/sklearn/PrecisionRecallCurve.py +6 -1
- validmind/tests/model_validation/sklearn/ROCCurve.py +3 -1
- validmind/tests/model_validation/sklearn/RegressionErrors.py +6 -2
- validmind/tests/model_validation/sklearn/RegressionPerformance.py +13 -8
- validmind/tests/model_validation/sklearn/RegressionR2Square.py +8 -5
- validmind/tests/model_validation/sklearn/RobustnessDiagnosis.py +5 -1
- validmind/tests/model_validation/sklearn/SHAPGlobalImportance.py +34 -26
- validmind/tests/model_validation/sklearn/ScoreProbabilityAlignment.py +10 -2
- validmind/tests/model_validation/sklearn/SilhouettePlot.py +5 -1
- validmind/tests/model_validation/sklearn/VMeasure.py +12 -9
- validmind/tests/model_validation/sklearn/WeakspotsDiagnosis.py +15 -10
- validmind/tests/model_validation/statsmodels/CumulativePredictionProbabilities.py +5 -1
- validmind/tests/model_validation/statsmodels/DurbinWatsonTest.py +6 -1
- validmind/tests/model_validation/statsmodels/GINITable.py +8 -1
- validmind/tests/model_validation/statsmodels/KolmogorovSmirnov.py +2 -2
- validmind/tests/model_validation/statsmodels/PredictionProbabilitiesHistogram.py +6 -2
- validmind/tests/model_validation/statsmodels/RegressionCoeffs.py +8 -2
- validmind/tests/model_validation/statsmodels/RegressionFeatureSignificance.py +3 -1
- validmind/tests/model_validation/statsmodels/RegressionModelForecastPlot.py +7 -2
- validmind/tests/model_validation/statsmodels/RegressionModelForecastPlotLevels.py +2 -0
- validmind/tests/model_validation/statsmodels/RegressionModelSensitivityPlot.py +2 -0
- validmind/tests/model_validation/statsmodels/RegressionModelSummary.py +4 -2
- validmind/tests/model_validation/statsmodels/RegressionPermutationFeatureImportance.py +3 -1
- validmind/tests/ongoing_monitoring/CalibrationCurveDrift.py +11 -1
- validmind/tests/ongoing_monitoring/ClassificationAccuracyDrift.py +10 -2
- validmind/tests/ongoing_monitoring/ConfusionMatrixDrift.py +8 -1
- validmind/tests/ongoing_monitoring/CumulativePredictionProbabilitiesDrift.py +18 -2
- validmind/tests/ongoing_monitoring/FeatureDrift.py +9 -2
- validmind/tests/ongoing_monitoring/PredictionAcrossEachFeature.py +8 -2
- validmind/tests/ongoing_monitoring/PredictionCorrelation.py +13 -2
- validmind/tests/ongoing_monitoring/PredictionProbabilitiesHistogramDrift.py +13 -2
- validmind/tests/ongoing_monitoring/ROCCurveDrift.py +16 -2
- validmind/tests/ongoing_monitoring/ScoreBandsDrift.py +11 -2
- validmind/tests/ongoing_monitoring/TargetPredictionDistributionPlot.py +13 -2
- validmind/tests/output.py +66 -11
- validmind/tests/prompt_validation/Clarity.py +1 -1
- validmind/tests/prompt_validation/NegativeInstruction.py +1 -1
- validmind/tests/prompt_validation/Robustness.py +6 -1
- validmind/tests/prompt_validation/Specificity.py +1 -1
- validmind/tests/run.py +28 -14
- validmind/tests/test_providers.py +28 -35
- validmind/tests/utils.py +17 -4
- validmind/unit_metrics/__init__.py +1 -1
- validmind/utils.py +295 -31
- validmind/vm_models/dataset/dataset.py +19 -16
- validmind/vm_models/dataset/utils.py +5 -3
- validmind/vm_models/figure.py +6 -6
- validmind/vm_models/input.py +6 -5
- validmind/vm_models/model.py +5 -5
- validmind/vm_models/result/result.py +122 -43
- validmind/vm_models/result/utils.py +9 -28
- validmind/vm_models/test_suite/__init__.py +5 -0
- validmind/vm_models/test_suite/runner.py +5 -5
- validmind/vm_models/test_suite/summary.py +20 -2
- validmind/vm_models/test_suite/test.py +6 -6
- validmind/vm_models/test_suite/test_suite.py +10 -10
- {validmind-2.8.10.dist-info → validmind-2.8.20.dist-info}/METADATA +4 -5
- {validmind-2.8.10.dist-info → validmind-2.8.20.dist-info}/RECORD +189 -188
- {validmind-2.8.10.dist-info → validmind-2.8.20.dist-info}/WHEEL +1 -1
- {validmind-2.8.10.dist-info → validmind-2.8.20.dist-info}/LICENSE +0 -0
- {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
|
-
|
47
|
-
|
48
|
-
|
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:
|
51
|
-
text_column: str = None,
|
52
|
-
target_column: str = None,
|
53
|
-
feature_columns:
|
54
|
-
extra_columns:
|
55
|
-
class_labels:
|
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
|
73
|
-
model (VMModel): ValidMind model object
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
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:
|
177
|
-
predict_fn:
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
369
|
-
|
370
|
-
|
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
|
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
|
384
|
-
`models
|
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:
|
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
|
436
|
-
|
437
|
-
|
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
|
491
|
-
|
492
|
-
|
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
|
|
validmind/client_config.py
CHANGED
@@ -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
|
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(
|
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
|
-
:
|
109
|
-
|
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(
|
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
|
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 =
|
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(
|
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(
|
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
|
-
:
|
30
|
-
|
31
|
-
|
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
|
-
:
|
21
|
-
|
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(
|
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)
|