validmind 2.5.24__py3-none-any.whl → 2.6.7__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 +8 -17
- validmind/__version__.py +1 -1
- validmind/ai/test_descriptions.py +66 -85
- validmind/ai/test_result_description/context.py +2 -2
- validmind/ai/utils.py +26 -1
- validmind/api_client.py +43 -79
- validmind/client.py +5 -7
- validmind/client_config.py +1 -1
- validmind/datasets/__init__.py +1 -1
- validmind/datasets/classification/customer_churn.py +7 -5
- validmind/datasets/nlp/__init__.py +2 -2
- validmind/errors.py +6 -10
- validmind/html_templates/content_blocks.py +18 -16
- validmind/logging.py +21 -16
- validmind/tests/__init__.py +28 -5
- validmind/tests/__types__.py +186 -170
- validmind/tests/_store.py +7 -21
- validmind/tests/comparison.py +362 -0
- validmind/tests/data_validation/ACFandPACFPlot.py +44 -73
- validmind/tests/data_validation/ADF.py +49 -83
- validmind/tests/data_validation/AutoAR.py +59 -96
- validmind/tests/data_validation/AutoMA.py +59 -96
- validmind/tests/data_validation/AutoStationarity.py +66 -114
- validmind/tests/data_validation/ClassImbalance.py +48 -117
- validmind/tests/data_validation/DatasetDescription.py +180 -209
- validmind/tests/data_validation/DatasetSplit.py +50 -75
- validmind/tests/data_validation/DescriptiveStatistics.py +59 -85
- validmind/tests/data_validation/{DFGLSArch.py → DickeyFullerGLS.py} +44 -76
- validmind/tests/data_validation/Duplicates.py +21 -90
- validmind/tests/data_validation/EngleGrangerCoint.py +53 -75
- validmind/tests/data_validation/HighCardinality.py +32 -80
- validmind/tests/data_validation/HighPearsonCorrelation.py +29 -97
- validmind/tests/data_validation/IQROutliersBarPlot.py +63 -94
- validmind/tests/data_validation/IQROutliersTable.py +40 -80
- validmind/tests/data_validation/IsolationForestOutliers.py +41 -63
- validmind/tests/data_validation/KPSS.py +33 -81
- validmind/tests/data_validation/LaggedCorrelationHeatmap.py +47 -95
- validmind/tests/data_validation/MissingValues.py +17 -58
- validmind/tests/data_validation/MissingValuesBarPlot.py +61 -87
- validmind/tests/data_validation/PhillipsPerronArch.py +56 -79
- validmind/tests/data_validation/RollingStatsPlot.py +50 -81
- validmind/tests/data_validation/SeasonalDecompose.py +102 -184
- validmind/tests/data_validation/Skewness.py +27 -64
- validmind/tests/data_validation/SpreadPlot.py +34 -57
- validmind/tests/data_validation/TabularCategoricalBarPlots.py +46 -65
- validmind/tests/data_validation/TabularDateTimeHistograms.py +23 -45
- validmind/tests/data_validation/TabularNumericalHistograms.py +27 -46
- validmind/tests/data_validation/TargetRateBarPlots.py +54 -93
- validmind/tests/data_validation/TimeSeriesFrequency.py +48 -133
- validmind/tests/data_validation/TimeSeriesHistogram.py +24 -3
- validmind/tests/data_validation/TimeSeriesLinePlot.py +29 -47
- validmind/tests/data_validation/TimeSeriesMissingValues.py +59 -135
- validmind/tests/data_validation/TimeSeriesOutliers.py +54 -171
- validmind/tests/data_validation/TooManyZeroValues.py +21 -70
- validmind/tests/data_validation/UniqueRows.py +23 -62
- validmind/tests/data_validation/WOEBinPlots.py +83 -109
- validmind/tests/data_validation/WOEBinTable.py +28 -69
- validmind/tests/data_validation/ZivotAndrewsArch.py +33 -75
- validmind/tests/data_validation/nlp/CommonWords.py +49 -57
- validmind/tests/data_validation/nlp/Hashtags.py +27 -49
- validmind/tests/data_validation/nlp/LanguageDetection.py +7 -13
- validmind/tests/data_validation/nlp/Mentions.py +32 -63
- validmind/tests/data_validation/nlp/PolarityAndSubjectivity.py +89 -14
- validmind/tests/data_validation/nlp/Punctuations.py +63 -47
- validmind/tests/data_validation/nlp/Sentiment.py +4 -0
- validmind/tests/data_validation/nlp/StopWords.py +62 -91
- validmind/tests/data_validation/nlp/TextDescription.py +116 -159
- validmind/tests/data_validation/nlp/Toxicity.py +12 -4
- validmind/tests/decorator.py +33 -242
- validmind/tests/load.py +212 -153
- validmind/tests/model_validation/BertScore.py +13 -7
- validmind/tests/model_validation/BleuScore.py +4 -0
- validmind/tests/model_validation/ClusterSizeDistribution.py +24 -47
- validmind/tests/model_validation/ContextualRecall.py +3 -0
- validmind/tests/model_validation/FeaturesAUC.py +43 -74
- validmind/tests/model_validation/MeteorScore.py +3 -0
- validmind/tests/model_validation/RegardScore.py +5 -1
- validmind/tests/model_validation/RegressionResidualsPlot.py +54 -75
- validmind/tests/model_validation/embeddings/ClusterDistribution.py +10 -33
- validmind/tests/model_validation/embeddings/CosineSimilarityDistribution.py +11 -29
- validmind/tests/model_validation/embeddings/DescriptiveAnalytics.py +19 -31
- validmind/tests/model_validation/embeddings/EmbeddingsVisualization2D.py +40 -49
- validmind/tests/model_validation/embeddings/StabilityAnalysisKeyword.py +29 -15
- validmind/tests/model_validation/embeddings/StabilityAnalysisRandomNoise.py +25 -11
- validmind/tests/model_validation/embeddings/StabilityAnalysisSynonyms.py +28 -13
- validmind/tests/model_validation/embeddings/StabilityAnalysisTranslation.py +67 -38
- validmind/tests/model_validation/embeddings/utils.py +53 -0
- validmind/tests/model_validation/ragas/AnswerCorrectness.py +37 -32
- validmind/tests/model_validation/ragas/{AspectCritique.py → AspectCritic.py} +33 -27
- validmind/tests/model_validation/ragas/ContextEntityRecall.py +44 -41
- validmind/tests/model_validation/ragas/ContextPrecision.py +40 -35
- validmind/tests/model_validation/ragas/ContextPrecisionWithoutReference.py +133 -0
- validmind/tests/model_validation/ragas/ContextRecall.py +40 -35
- validmind/tests/model_validation/ragas/Faithfulness.py +42 -30
- validmind/tests/model_validation/ragas/NoiseSensitivity.py +59 -35
- validmind/tests/model_validation/ragas/{AnswerRelevance.py → ResponseRelevancy.py} +52 -41
- validmind/tests/model_validation/ragas/{AnswerSimilarity.py → SemanticSimilarity.py} +39 -34
- validmind/tests/model_validation/sklearn/AdjustedMutualInformation.py +13 -16
- validmind/tests/model_validation/sklearn/AdjustedRandIndex.py +13 -16
- validmind/tests/model_validation/sklearn/ClassifierPerformance.py +51 -89
- validmind/tests/model_validation/sklearn/ClusterCosineSimilarity.py +31 -61
- validmind/tests/model_validation/sklearn/ClusterPerformanceMetrics.py +118 -83
- validmind/tests/model_validation/sklearn/CompletenessScore.py +13 -16
- validmind/tests/model_validation/sklearn/ConfusionMatrix.py +62 -94
- validmind/tests/model_validation/sklearn/FeatureImportance.py +7 -8
- validmind/tests/model_validation/sklearn/FowlkesMallowsScore.py +12 -15
- validmind/tests/model_validation/sklearn/HomogeneityScore.py +12 -15
- validmind/tests/model_validation/sklearn/HyperParametersTuning.py +23 -53
- validmind/tests/model_validation/sklearn/KMeansClustersOptimization.py +60 -74
- validmind/tests/model_validation/sklearn/MinimumAccuracy.py +16 -84
- validmind/tests/model_validation/sklearn/MinimumF1Score.py +22 -72
- validmind/tests/model_validation/sklearn/MinimumROCAUCScore.py +29 -78
- validmind/tests/model_validation/sklearn/ModelsPerformanceComparison.py +52 -82
- validmind/tests/model_validation/sklearn/OverfitDiagnosis.py +51 -145
- validmind/tests/model_validation/sklearn/PermutationFeatureImportance.py +60 -78
- validmind/tests/model_validation/sklearn/PopulationStabilityIndex.py +130 -172
- validmind/tests/model_validation/sklearn/PrecisionRecallCurve.py +26 -55
- validmind/tests/model_validation/sklearn/ROCCurve.py +43 -77
- validmind/tests/model_validation/sklearn/RegressionPerformance.py +41 -94
- validmind/tests/model_validation/sklearn/RobustnessDiagnosis.py +47 -136
- validmind/tests/model_validation/sklearn/SHAPGlobalImportance.py +164 -208
- validmind/tests/model_validation/sklearn/SilhouettePlot.py +54 -99
- validmind/tests/model_validation/sklearn/TrainingTestDegradation.py +50 -124
- validmind/tests/model_validation/sklearn/VMeasure.py +12 -15
- validmind/tests/model_validation/sklearn/WeakspotsDiagnosis.py +225 -281
- validmind/tests/model_validation/statsmodels/AutoARIMA.py +40 -45
- validmind/tests/model_validation/statsmodels/KolmogorovSmirnov.py +22 -47
- validmind/tests/model_validation/statsmodels/Lilliefors.py +17 -28
- validmind/tests/model_validation/statsmodels/RegressionFeatureSignificance.py +37 -81
- validmind/tests/model_validation/statsmodels/RegressionModelForecastPlot.py +37 -105
- validmind/tests/model_validation/statsmodels/RegressionModelForecastPlotLevels.py +62 -166
- validmind/tests/model_validation/statsmodels/RegressionModelSensitivityPlot.py +57 -119
- validmind/tests/model_validation/statsmodels/RegressionModelSummary.py +20 -57
- validmind/tests/model_validation/statsmodels/RegressionPermutationFeatureImportance.py +47 -80
- validmind/tests/ongoing_monitoring/PredictionCorrelation.py +2 -0
- validmind/tests/ongoing_monitoring/TargetPredictionDistributionPlot.py +4 -2
- validmind/tests/output.py +120 -0
- validmind/tests/prompt_validation/Bias.py +55 -98
- validmind/tests/prompt_validation/Clarity.py +56 -99
- validmind/tests/prompt_validation/Conciseness.py +63 -101
- validmind/tests/prompt_validation/Delimitation.py +48 -89
- validmind/tests/prompt_validation/NegativeInstruction.py +62 -96
- validmind/tests/prompt_validation/Robustness.py +80 -121
- validmind/tests/prompt_validation/Specificity.py +61 -95
- validmind/tests/prompt_validation/ai_powered_test.py +2 -2
- validmind/tests/run.py +314 -496
- validmind/tests/test_providers.py +109 -79
- validmind/tests/utils.py +91 -0
- validmind/unit_metrics/__init__.py +16 -155
- validmind/unit_metrics/classification/F1.py +1 -0
- validmind/unit_metrics/classification/Precision.py +1 -0
- validmind/unit_metrics/classification/ROC_AUC.py +1 -0
- validmind/unit_metrics/classification/Recall.py +1 -0
- validmind/unit_metrics/regression/AdjustedRSquaredScore.py +1 -0
- validmind/unit_metrics/regression/GiniCoefficient.py +1 -0
- validmind/unit_metrics/regression/HuberLoss.py +1 -0
- validmind/unit_metrics/regression/KolmogorovSmirnovStatistic.py +1 -0
- validmind/unit_metrics/regression/MeanAbsoluteError.py +1 -0
- validmind/unit_metrics/regression/MeanAbsolutePercentageError.py +1 -0
- validmind/unit_metrics/regression/MeanBiasDeviation.py +1 -0
- validmind/unit_metrics/regression/MeanSquaredError.py +1 -0
- validmind/unit_metrics/regression/QuantileLoss.py +1 -0
- validmind/unit_metrics/regression/RSquaredScore.py +2 -1
- validmind/unit_metrics/regression/RootMeanSquaredError.py +1 -0
- validmind/utils.py +66 -17
- validmind/vm_models/__init__.py +2 -17
- validmind/vm_models/dataset/dataset.py +31 -4
- validmind/vm_models/figure.py +7 -37
- validmind/vm_models/model.py +3 -0
- validmind/vm_models/result/__init__.py +7 -0
- validmind/vm_models/result/result.jinja +21 -0
- validmind/vm_models/result/result.py +337 -0
- validmind/vm_models/result/utils.py +160 -0
- validmind/vm_models/test_suite/runner.py +16 -54
- validmind/vm_models/test_suite/summary.py +3 -3
- validmind/vm_models/test_suite/test.py +43 -77
- validmind/vm_models/test_suite/test_suite.py +8 -40
- validmind-2.6.7.dist-info/METADATA +137 -0
- {validmind-2.5.24.dist-info → validmind-2.6.7.dist-info}/RECORD +182 -189
- validmind/tests/data_validation/AutoSeasonality.py +0 -190
- validmind/tests/metadata.py +0 -59
- validmind/tests/model_validation/embeddings/StabilityAnalysis.py +0 -176
- validmind/tests/model_validation/ragas/ContextUtilization.py +0 -161
- validmind/tests/model_validation/sklearn/ClusterPerformance.py +0 -80
- validmind/unit_metrics/composite.py +0 -238
- validmind/vm_models/test/metric.py +0 -98
- validmind/vm_models/test/metric_result.py +0 -61
- validmind/vm_models/test/output_template.py +0 -55
- validmind/vm_models/test/result_summary.py +0 -76
- validmind/vm_models/test/result_wrapper.py +0 -488
- validmind/vm_models/test/test.py +0 -103
- validmind/vm_models/test/threshold_test.py +0 -106
- validmind/vm_models/test/threshold_test_result.py +0 -75
- validmind/vm_models/test_context.py +0 -259
- validmind-2.5.24.dist-info/METADATA +0 -118
- {validmind-2.5.24.dist-info → validmind-2.6.7.dist-info}/LICENSE +0 -0
- {validmind-2.5.24.dist-info → validmind-2.6.7.dist-info}/WHEEL +0 -0
- {validmind-2.5.24.dist-info → validmind-2.6.7.dist-info}/entry_points.txt +0 -0
@@ -1,75 +0,0 @@
|
|
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
|
-
"""
|
6
|
-
ThresholdTestResult models
|
7
|
-
"""
|
8
|
-
from dataclasses import dataclass
|
9
|
-
from typing import List, Optional
|
10
|
-
|
11
|
-
from .result_summary import ResultSummary
|
12
|
-
|
13
|
-
|
14
|
-
@dataclass
|
15
|
-
class ThresholdTestResult:
|
16
|
-
"""
|
17
|
-
ThresholdTestResult model
|
18
|
-
"""
|
19
|
-
|
20
|
-
values: dict
|
21
|
-
test_name: Optional[str] = None # Optionally allow a name for an individual test
|
22
|
-
column: Optional[
|
23
|
-
str
|
24
|
-
] = None # Optionally track the results for an individual column
|
25
|
-
passed: Optional[bool] = None # Optionally per-result pass/fail
|
26
|
-
|
27
|
-
def serialize(self):
|
28
|
-
"""
|
29
|
-
Serializes the ThresholdTestResult to a dictionary so it can be sent to the API
|
30
|
-
"""
|
31
|
-
test_result = {
|
32
|
-
"values": self.values,
|
33
|
-
}
|
34
|
-
|
35
|
-
if self.test_name is not None:
|
36
|
-
test_result["test_name"] = self.test_name
|
37
|
-
|
38
|
-
if self.column is not None:
|
39
|
-
test_result["column"] = self.column
|
40
|
-
|
41
|
-
if self.passed is not None:
|
42
|
-
test_result["passed"] = self.passed
|
43
|
-
|
44
|
-
return test_result
|
45
|
-
|
46
|
-
|
47
|
-
@dataclass
|
48
|
-
class ThresholdTestResults:
|
49
|
-
"""
|
50
|
-
ThresholdTestResults model
|
51
|
-
"""
|
52
|
-
|
53
|
-
test_name: str
|
54
|
-
ref_id: str
|
55
|
-
params: dict
|
56
|
-
passed: bool
|
57
|
-
results: List[ThresholdTestResult]
|
58
|
-
summary: Optional[ResultSummary]
|
59
|
-
|
60
|
-
def serialize(self):
|
61
|
-
"""
|
62
|
-
Serializes the ThresholdTestResults to a dictionary so it can be sent to the API
|
63
|
-
"""
|
64
|
-
test_results = {
|
65
|
-
"test_name": self.test_name,
|
66
|
-
"ref_id": self.ref_id,
|
67
|
-
"params": self.params,
|
68
|
-
"passed": self.passed,
|
69
|
-
"results": [result.serialize() for result in self.results],
|
70
|
-
}
|
71
|
-
|
72
|
-
if self.summary is not None:
|
73
|
-
test_results["summary"] = self.summary.serialize()
|
74
|
-
|
75
|
-
return test_results
|
@@ -1,259 +0,0 @@
|
|
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
|
-
"""
|
6
|
-
TestContext
|
7
|
-
"""
|
8
|
-
|
9
|
-
# TODO: lets think about refactoring this file since it deals with both the `TestContext` and the `TestInput`.
|
10
|
-
# TestInput was previously used for both storing a global "context" for running tests to be able to
|
11
|
-
# share data, as well as for storing the inputs to those tests.
|
12
|
-
# We've since split this into two separate concepts.
|
13
|
-
# https://app.shortcut.com/validmind/story/2468/allow-arbitrary-test-context
|
14
|
-
# There is more changes to come around how we handle test inputs, so once we iron out that, we can refactor
|
15
|
-
|
16
|
-
from dataclasses import dataclass
|
17
|
-
from typing import ClassVar, List, Optional
|
18
|
-
|
19
|
-
from validmind.input_registry import input_registry
|
20
|
-
|
21
|
-
from ..errors import MissingRequiredTestInputError
|
22
|
-
from ..logging import get_logger
|
23
|
-
from .dataset.dataset import VMDataset
|
24
|
-
from .model import VMModel
|
25
|
-
|
26
|
-
# More human readable context names for error messages
|
27
|
-
CONTEXT_NAMES = {
|
28
|
-
"dataset": "Dataset",
|
29
|
-
"model": "Model",
|
30
|
-
"models": "Models",
|
31
|
-
"model.train_ds": "Model Training Dataset",
|
32
|
-
"model.test_ds": "Model Testing Dataset",
|
33
|
-
"model.validation_ds": "Model Validation Dataset",
|
34
|
-
"train_ds": "Training Dataset",
|
35
|
-
"test_ds": "Testing Dataset",
|
36
|
-
"validation_ds": "Validation Dataset",
|
37
|
-
}
|
38
|
-
|
39
|
-
logger = get_logger(__name__)
|
40
|
-
|
41
|
-
|
42
|
-
@dataclass
|
43
|
-
class TestContext:
|
44
|
-
"""
|
45
|
-
Holds context that can be used by tests to run.
|
46
|
-
Allows us to store data that needs to be reused
|
47
|
-
across different tests/metrics such as shared dataset metrics, etc.
|
48
|
-
"""
|
49
|
-
|
50
|
-
# Custom context data that can be set by metrics or tests using this context
|
51
|
-
context_data: Optional[dict] = None
|
52
|
-
|
53
|
-
# TODO: here for backwards compatibility, remove this when appropriate
|
54
|
-
dataset: VMDataset = None
|
55
|
-
model: VMModel = None
|
56
|
-
models: List[VMModel] = None
|
57
|
-
|
58
|
-
def set_context_data(self, key, value):
|
59
|
-
if self.context_data is None:
|
60
|
-
self.context_data = {}
|
61
|
-
|
62
|
-
self.context_data[key] = value
|
63
|
-
|
64
|
-
def get_context_data(self, key):
|
65
|
-
if self.context_data is None:
|
66
|
-
return None
|
67
|
-
|
68
|
-
return self.context_data.get(key)
|
69
|
-
|
70
|
-
|
71
|
-
class TestInput:
|
72
|
-
"""Holds models, datasets and other arbitrary inputs for test(s)
|
73
|
-
|
74
|
-
Attributes:
|
75
|
-
dataset (VMDataset): Single dataset for dataset-only tests
|
76
|
-
model (VMModel): Single model for model-related tests
|
77
|
-
models (List[VMModel]): Multiple models for model comparison tests
|
78
|
-
... (any): Any other arbitrary inputs that can be used by tests
|
79
|
-
"""
|
80
|
-
|
81
|
-
def __init__(self, inputs):
|
82
|
-
"""Initialize with either a dictionary of inputs"""
|
83
|
-
for key, value in inputs.items():
|
84
|
-
# 1) retrieve input object from input registry if an input_id string is provided
|
85
|
-
# 2) check the input_id type if a list of inputs (mix of strings and objects) is provided
|
86
|
-
# 3) if its a dict, it should contain the `input_id` key as well as other options
|
87
|
-
if isinstance(value, str):
|
88
|
-
value = input_registry.get(key=value)
|
89
|
-
elif isinstance(value, list) or isinstance(value, tuple):
|
90
|
-
value = [
|
91
|
-
input_registry.get(key=v) if isinstance(v, str) else v
|
92
|
-
for v in value
|
93
|
-
]
|
94
|
-
elif isinstance(value, dict):
|
95
|
-
assert "input_id" in value, (
|
96
|
-
"Input dictionary must contain an 'input_id' key "
|
97
|
-
"to retrieve the input object from the input registry."
|
98
|
-
)
|
99
|
-
value = input_registry.get(key=value.get("input_id")).with_options(
|
100
|
-
**{k: v for k, v in value.items() if k != "input_id"}
|
101
|
-
)
|
102
|
-
|
103
|
-
setattr(self, key, value)
|
104
|
-
|
105
|
-
def __getitem__(self, key):
|
106
|
-
"""Allow accessing inputs via `self.inputs["input_name"]`"""
|
107
|
-
return getattr(self, key)
|
108
|
-
|
109
|
-
def __repr__(self):
|
110
|
-
"""Human-readable string representation of the object."""
|
111
|
-
attrs = ",\n ".join(
|
112
|
-
f"{key}={value!r}" for key, value in self.__dict__.items()
|
113
|
-
)
|
114
|
-
return f"{self.__class__.__name__}(\n {attrs}\n)"
|
115
|
-
|
116
|
-
|
117
|
-
class InputAccessTrackerProxy:
|
118
|
-
"""Proxy object to track TestInput attribute access on a per-test basis"""
|
119
|
-
|
120
|
-
def __init__(self, inputs):
|
121
|
-
self._inputs = inputs
|
122
|
-
self._accessed = set()
|
123
|
-
|
124
|
-
def __getattr__(self, name):
|
125
|
-
# Track access only if the attribute actually exists in the inputs
|
126
|
-
if hasattr(self._inputs, name):
|
127
|
-
input = getattr(self._inputs, name)
|
128
|
-
# if the input is a list of inputs, track each input individually
|
129
|
-
if isinstance(input, list) or isinstance(input, tuple):
|
130
|
-
for i in input:
|
131
|
-
self._accessed.add(i.input_id)
|
132
|
-
else:
|
133
|
-
self._accessed.add(input.input_id)
|
134
|
-
return getattr(self._inputs, name)
|
135
|
-
|
136
|
-
raise AttributeError(
|
137
|
-
f"'{type(self._inputs).__name__}' object has no attribute '{name}'"
|
138
|
-
)
|
139
|
-
|
140
|
-
def get_accessed(self):
|
141
|
-
# Provide the list of accessed input names
|
142
|
-
return list(self._accessed)
|
143
|
-
|
144
|
-
|
145
|
-
@dataclass
|
146
|
-
class TestUtils:
|
147
|
-
"""Utility methods for classes that receive a TestContext"""
|
148
|
-
|
149
|
-
required_inputs: ClassVar[List[str]]
|
150
|
-
|
151
|
-
context: Optional[TestContext] = None
|
152
|
-
inputs: Optional[TestInput] = None # gets overwritten to be a proxy when accessed
|
153
|
-
|
154
|
-
def __getattribute__(self, name):
|
155
|
-
# Intercept attribute access
|
156
|
-
if name == "inputs":
|
157
|
-
inputs = super().__getattribute__(name)
|
158
|
-
|
159
|
-
# when accessing inputs for the first time, wrap them in tracker proxy
|
160
|
-
if inputs is not None and not isinstance(inputs, InputAccessTrackerProxy):
|
161
|
-
inputs = InputAccessTrackerProxy(inputs)
|
162
|
-
super().__setattr__(name, inputs) # overwrite to avoid re-wrapping
|
163
|
-
|
164
|
-
return inputs
|
165
|
-
|
166
|
-
return super().__getattribute__(name)
|
167
|
-
|
168
|
-
def get_accessed_inputs(self):
|
169
|
-
"""Return a list of inputs that were accessed for this test"""
|
170
|
-
if isinstance(self.inputs, InputAccessTrackerProxy):
|
171
|
-
return self.inputs.get_accessed()
|
172
|
-
|
173
|
-
return []
|
174
|
-
|
175
|
-
def _get_input_dict(self):
|
176
|
-
"""Return a dictionary of all inputs"""
|
177
|
-
if isinstance(self.inputs, InputAccessTrackerProxy):
|
178
|
-
return self.inputs._inputs.__dict__
|
179
|
-
|
180
|
-
return self.inputs.__dict__
|
181
|
-
|
182
|
-
def _get_legacy_input(self, key):
|
183
|
-
"""Retrieve an input from the Test Input or, for backwards compatibility,
|
184
|
-
the Test Context
|
185
|
-
|
186
|
-
We should remove this once we all tests (including customer tests) are
|
187
|
-
using `self.inputs.<input_name>` instead of `self.<input_name>`.
|
188
|
-
"""
|
189
|
-
try:
|
190
|
-
_input = getattr(self.inputs, key)
|
191
|
-
except AttributeError:
|
192
|
-
# in case any code is still manually creating a TestContext instead of
|
193
|
-
# a TestInput, we'll still support that for now by checking there
|
194
|
-
_input = getattr(self.context, key)
|
195
|
-
|
196
|
-
return _input
|
197
|
-
|
198
|
-
@property
|
199
|
-
def dataset(self):
|
200
|
-
"""[DEPRECATED] Returns the input dataset for the test"""
|
201
|
-
logger.warning(
|
202
|
-
"Accesing the input dataset using `self.dataset` is deprecated. "
|
203
|
-
"Use `self.inputs.dataset` instead."
|
204
|
-
)
|
205
|
-
return self._get_legacy_input("dataset")
|
206
|
-
|
207
|
-
@property
|
208
|
-
def model(self):
|
209
|
-
"""[DEPRECATED] Returns the input model for the test"""
|
210
|
-
logger.warning(
|
211
|
-
"Accesing the input model using `self.model` is deprecated. "
|
212
|
-
"Use `self.inputs.model` instead."
|
213
|
-
)
|
214
|
-
return self._get_legacy_input("model")
|
215
|
-
|
216
|
-
@property
|
217
|
-
def models(self):
|
218
|
-
"""[DEPRECATED] Returns the input models for the test"""
|
219
|
-
logger.warning(
|
220
|
-
"Accesing the input models using `self.models` is deprecated. "
|
221
|
-
"Use `self.inputs.models` instead."
|
222
|
-
)
|
223
|
-
return self._get_legacy_input("models")
|
224
|
-
|
225
|
-
def validate_inputs(self):
|
226
|
-
"""
|
227
|
-
Validates that the required inputs are present in the test input object.
|
228
|
-
|
229
|
-
Raises:
|
230
|
-
MissingRequiredTestInputError: If a required context element is missing.
|
231
|
-
"""
|
232
|
-
|
233
|
-
def recursive_attr_check(obj, attr_chain):
|
234
|
-
"""
|
235
|
-
Recursively checks if the given object has the specified attribute chain.
|
236
|
-
|
237
|
-
Args:
|
238
|
-
obj: The object to check.
|
239
|
-
attr_chain: A string representing the attribute chain, separated by dots.
|
240
|
-
|
241
|
-
Returns:
|
242
|
-
True if the object has the attribute chain, False otherwise.
|
243
|
-
"""
|
244
|
-
attrs = attr_chain.split(".")
|
245
|
-
if not hasattr(obj, attrs[0]) or getattr(obj, attrs[0]) is None:
|
246
|
-
return False
|
247
|
-
return len(attrs) == 1 or recursive_attr_check(
|
248
|
-
getattr(obj, attrs[0]),
|
249
|
-
".".join(attrs[1:]),
|
250
|
-
)
|
251
|
-
|
252
|
-
required_inputs = self.required_inputs or []
|
253
|
-
for element in required_inputs:
|
254
|
-
if not recursive_attr_check(self.inputs, element):
|
255
|
-
context_name = CONTEXT_NAMES.get(element, element)
|
256
|
-
raise MissingRequiredTestInputError(
|
257
|
-
f"{context_name} '{element}' is a required input and must be "
|
258
|
-
"passed as part of the test inputs dictionary."
|
259
|
-
)
|
@@ -1,118 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.1
|
2
|
-
Name: validmind
|
3
|
-
Version: 2.5.24
|
4
|
-
Summary: ValidMind Library
|
5
|
-
License: Commercial License
|
6
|
-
Author: Andres Rodriguez
|
7
|
-
Author-email: andres@validmind.ai
|
8
|
-
Requires-Python: >=3.8.1,<3.12
|
9
|
-
Classifier: License :: Other/Proprietary License
|
10
|
-
Classifier: Programming Language :: Python :: 3
|
11
|
-
Classifier: Programming Language :: Python :: 3.9
|
12
|
-
Classifier: Programming Language :: Python :: 3.10
|
13
|
-
Classifier: Programming Language :: Python :: 3.11
|
14
|
-
Provides-Extra: all
|
15
|
-
Provides-Extra: huggingface
|
16
|
-
Provides-Extra: llm
|
17
|
-
Provides-Extra: pytorch
|
18
|
-
Provides-Extra: r-support
|
19
|
-
Requires-Dist: aiohttp[speedups]
|
20
|
-
Requires-Dist: arch
|
21
|
-
Requires-Dist: bert-score (>=0.3.13)
|
22
|
-
Requires-Dist: catboost
|
23
|
-
Requires-Dist: datasets (>=2.10.0,<3.0.0)
|
24
|
-
Requires-Dist: evaluate
|
25
|
-
Requires-Dist: ipywidgets
|
26
|
-
Requires-Dist: kaleido (>=0.2.1,!=0.2.1.post1)
|
27
|
-
Requires-Dist: langchain-openai (>=0.1.8) ; extra == "all" or extra == "llm"
|
28
|
-
Requires-Dist: langdetect
|
29
|
-
Requires-Dist: latex2mathml (>=3.77.0)
|
30
|
-
Requires-Dist: llvmlite ; python_version >= "3.8" and python_full_version <= "3.11.0"
|
31
|
-
Requires-Dist: matplotlib
|
32
|
-
Requires-Dist: mistune (>=3.0.2,<4.0.0)
|
33
|
-
Requires-Dist: nest-asyncio (>=1.6.0,<2.0.0)
|
34
|
-
Requires-Dist: nltk (>=3.8.1,<4.0.0)
|
35
|
-
Requires-Dist: numba (<0.59.0)
|
36
|
-
Requires-Dist: numpy
|
37
|
-
Requires-Dist: openai (>=1)
|
38
|
-
Requires-Dist: pandas (>=1.1,<=2.0.3)
|
39
|
-
Requires-Dist: plotly
|
40
|
-
Requires-Dist: plotly-express
|
41
|
-
Requires-Dist: polars
|
42
|
-
Requires-Dist: pycocoevalcap (>=1.2,<2.0) ; extra == "all" or extra == "llm"
|
43
|
-
Requires-Dist: python-dotenv
|
44
|
-
Requires-Dist: ragas (>=0.1.19) ; extra == "all" or extra == "llm"
|
45
|
-
Requires-Dist: rouge (>=1)
|
46
|
-
Requires-Dist: rpy2 (>=3.5.10,<4.0.0) ; extra == "all" or extra == "r-support"
|
47
|
-
Requires-Dist: scikit-learn
|
48
|
-
Requires-Dist: scipy
|
49
|
-
Requires-Dist: scorecardpy (>=0.1.9.6,<0.2.0.0)
|
50
|
-
Requires-Dist: seaborn
|
51
|
-
Requires-Dist: sentencepiece (>=0.2.0,<0.3.0) ; extra == "all" or extra == "huggingface" or extra == "llm"
|
52
|
-
Requires-Dist: sentry-sdk (>=1.24.0,<2.0.0)
|
53
|
-
Requires-Dist: shap (==0.44.1)
|
54
|
-
Requires-Dist: statsmodels
|
55
|
-
Requires-Dist: tabulate (>=0.8.9,<0.9.0)
|
56
|
-
Requires-Dist: textblob (>=0.18.0.post0,<0.19.0)
|
57
|
-
Requires-Dist: torch (>=1.10.0) ; extra == "all" or extra == "llm" or extra == "pytorch"
|
58
|
-
Requires-Dist: tqdm
|
59
|
-
Requires-Dist: transformers (>=4.32.0,<5.0.0) ; extra == "all" or extra == "huggingface" or extra == "llm"
|
60
|
-
Requires-Dist: xgboost (>=1.5.2,<3)
|
61
|
-
Requires-Dist: ydata-profiling
|
62
|
-
Description-Content-Type: text/markdown
|
63
|
-
|
64
|
-
# ValidMind Library
|
65
|
-
|
66
|
-
ValidMind’s Python Library contains a suite of developer tools and methods designed to automate
|
67
|
-
the documentation and validation of your models.
|
68
|
-
|
69
|
-
The Library is designed to be model agnostic. If your model is built in Python, ValidMind's
|
70
|
-
Python library will provide all the standard functionality without requiring your developers to rewrite any functions.
|
71
|
-
|
72
|
-
The Library provides a rich suite of documentation tools and test suites, from documenting
|
73
|
-
descriptions of your dataset to testing your models for weak spots and overfit areas. The Developer
|
74
|
-
Framework helps you automate the generation of model documentation by feeding the ValidMind platform with
|
75
|
-
documentation artifacts and test results to the ValidMind platform.
|
76
|
-
|
77
|
-
## Installation
|
78
|
-
|
79
|
-
To install the ValidMind Library and all optional dependencies, run:
|
80
|
-
|
81
|
-
```bash
|
82
|
-
pip install validmind[all]
|
83
|
-
```
|
84
|
-
|
85
|
-
To install the Library without optional dependencies (core functionality only), run:
|
86
|
-
|
87
|
-
```bash
|
88
|
-
pip install validmind
|
89
|
-
```
|
90
|
-
|
91
|
-
### Extra dependencies
|
92
|
-
|
93
|
-
The Library has optional dependencies that can be installed separately to support additional model types and tests.
|
94
|
-
|
95
|
-
- **LLM Support**: To be able to run tests for Large Language Models (LLMs), install the `llm` extra:
|
96
|
-
|
97
|
-
```bash
|
98
|
-
pip install validmind[llm]
|
99
|
-
```
|
100
|
-
|
101
|
-
- **PyTorch Models**: To use pytorch models with the Library, install the `torch` extra:
|
102
|
-
|
103
|
-
```bash
|
104
|
-
pip install validmind[torch]
|
105
|
-
```
|
106
|
-
|
107
|
-
- **Hugging Face Transformers**: To use Hugging Face Transformers models with the Library, install the `transformers` extra:
|
108
|
-
|
109
|
-
```bash
|
110
|
-
pip install validmind[transformers]
|
111
|
-
```
|
112
|
-
|
113
|
-
- **R Models**: To use R models with the Library, install the `r` extra:
|
114
|
-
|
115
|
-
```bash
|
116
|
-
pip install validmind[r-support]
|
117
|
-
```
|
118
|
-
|
File without changes
|
File without changes
|
File without changes
|