explabox
The Explabox aims to support data scientists and machine learning (ML) engineers in explaining, testing and documenting AI/ML models, developed in-house or acquired externally. The explabox turns your ingestibles (AI/ML model and/or dataset) into digestibles (statistics, explanations or sensitivity insights)!
- To install run:
$ pip3 install explabox
Currently, the main interface for working with the Explabox is Jupyter Notebook. For more help, read the documentation at https://explabox.rtfd.io.
Explabox is developed by the Dutch National Police Lab AI (NPAI), and released under the GNU Lesser General Public License v3.0 (GNU LGPLv3).
- class explabox.Examiner(data=None, model=None, ingestibles=None, **kwargs)
Bases:
Readable,ModelMixin,IngestiblesMixinThe Examiner calculates quantitative metrics on how the model performs.
The Examiner requires ‘data’ and ‘model’ defined. It is included in the Explabox under the .examine property.
Examples
Construct the examiner:
>>> from explabox.examine import Examiner >>> examiner = Explainer(data=data, model=model)
Calculate model performance metrics on the validation set:
>>> examiner(split='validation')
See all wrongly classified examples in the test set:
>>> examiner.wrongly_classified(split='test')
- Parameters:
data (Optional[Environment], optional) – Data for ingestibles. Defaults to None.
model (Optional[AbstractClassifier], optional) – Model for ingestibles. Defaults to None.
ingestibles (Optional[Ingestible], optional) – Ingestible. Defaults to None.
- performance(split='test', **kwargs)
Determine performance metrics, the amount of predictions for each label in the test set and the values for the confusion matrix for each label in the test set.
- Parameters:
split (str, optional) – Split to calculate metrics on. Defaults to ‘test’.
- Returns:
Performance metrics of your model on the split.
- Return type:
- wrongly_classified(split='test', **kwargs)
Give all wrongly classified samples.
- Parameters:
split (str, optional) – Name of split. Defaults to ‘test’.
- Returns:
Wrongly classified examples in this split.
- Return type:
- class explabox.Explabox(ingestibles=None, locale='en', **kwargs)
Bases:
Readable,IngestiblesMixinUse the Explabox to .explore, .examine, .expose and .explain your AI model.
Example
>>> from explabox import Explabox >>> box = Explabox(data=data, model=model)
- Parameters:
ingestibles (Optional[Ingestible], optional) – Ingestibles (data and model). Defaults to None.
locale (str, optional) – Language of dataset. Defaults to ‘en’.
**kwargs – Arguments used to construct an Ingestible (if the ingestibles argument is None).
- class explabox.Explainer(data=None, model=None, ingestibles=None, **kwargs)
Bases:
Readable,IngestiblesMixinThe Explainer creates explanations corresponding to a model and dataset (with ground-truth labels).
With the Explainer you can use explainble AI (XAI) methods for explaining the whole dataset (global), model behavior on the dataset (global), and specific predictions/decisions (local).
The Explainer requires ‘data’ and ‘model’ defined. It is included in the Explabox under the .explain property.
Examples
Construct the explainer:
>>> from explabox.explain import Explainer >>> explainer = Explainer(data=data, model=model)
Get a local explanation with LIME (https://github.com/marcotcr/lime) and kernelSHAP (https://github.com/slundberg/shap):
>>> explainer.explain_prediction('I love this so much!', methods=['lime', 'kernel_shap'])
See the top-25 tokens for predicted classifier labels on the test set:
>>> explainer.token_frequency(k=25, explain_model=True, splits='test')
Select the top-5 prototypical examples in the train set:
>>> explainer.prototypes(n=5, splits='train')
- Parameters:
data (Optional[Environment], optional) – Data for ingestibles. Defaults to None.
model (Optional[AbstractClassifier], optional) – Model for ingestibles. Defaults to None.
ingestibles (Optional[Ingestible], optional) – Ingestible. Defaults to None.
- explain_prediction(sample, *args, methods=['lime'], **kwargs)
Explain specific sample locally.
- Parameters:
sample (
Union[int,str]) – Identifier of sample in dataset (int) or input (str).methods (
Union[str,List[str]]) – List of methods to get explanations from. Choose from ‘lime’, ‘shap’, ‘baylime’, ‘tree’, ‘rules’, ‘foil_tree’.*args – Positional arguments passed to local explanation technique.
**kwargs – Keyword arguments passed to local explanation technique.
- Returns:
Explanations for each selected method, unless method is unknown (returns None).
- Return type:
Optional[MultipleReturn]
- prototypes(method='mmdcritic', n=5, splits='test', embedder=<class 'text_explainability.data.embedding.TfidfVectorizer'>, labelwise=False, seed=0)
Select n prototypes (representative samples) for the given split(s).
- Parameters:
method (str, optional) – Method(s) to apply. Choose from [‘mmdcritic’, ‘kmedoids’]. Defaults to ‘mmdcritic’.
n (int, optional) – Number of prototypes to generate. Defaults to 5.
splits (Union[str, List[str]], optional) – Name(s) of split(s). Defaults to “test”.
embedder (Optional[Embedder], optional) – Embedder used. Defaults to TfidfVectorizer.
labelwise (bool, optional) – Select for each label. Defaults to False.
seed (int, optional) – Seed for reproducibility. Defaults to 0.
- Raises:
ValueError – Unknown method selected.
- Returns:
Prototypes for each methods and split.
- Return type:
Union[Instances, MultipleReturn]
- prototypes_criticisms(n_prototypes=5, n_criticisms=3, splits='test', embedder=<class 'text_explainability.data.embedding.TfidfVectorizer'>, labelwise=False, **kwargs)
Select n prototypes (representative samples) and n criticisms (outliers) for the given split(s).
- Parameters:
n_prototypes (int, optional) – Number of prototypes to generate. Defaults to 5.
n_criticsms (int, optional) – Number of criticisms to generate. Defaults to 3.
splits (Union[str, List[str]], optional) – Name(s) of split(s). Defaults to “test”.
embedder (Optional[Embedder], optional) – Embedder used. Defaults to TfidfVectorizer.
labelwise (bool, optional) – Select for each label. Defaults to False.
n_criticisms (int) –
- Returns:
Prototypes for each methods and split.
- Return type:
Union[Instances, MultipleReturn]
- token_frequency(splits='test', explain_model=True, labelwise=True, k=25, filter_words=<Proxy at 0x74f8fe7fd640 wrapping ['de', 'het', 'een'] at 0x74f8fe7cc180 with factory <function lazy.<locals>.<lambda>>>, lower=True, seed=0, **count_vectorizer_kwargs)
Show the top-k number of tokens for each ground-truth or predicted label.
- Parameters:
splits (Union[str, List[str]], optional) – Split names to get the explanation for. Defaults to ‘test’.
explain_model (bool, optional) – Whether to explain the model (True) or ground-truth labels (False). Defaults to True.
labelwise (bool, optional) – Whether to summarize the counts for each label seperately. Defaults to True.
k (Optional[int], optional) – Limit to the top-k words per label, or all words if None. Defaults to 25.
filter_words (List[str], optional) – Words to filter out from top-k. Defaults to [‘a’, ‘an’, ‘the’].
lower (bool, optional) – Whether to make all tokens lowercase. Defaults to True.
seed (int, optional) –
**count_vectorizer_kwargs – Optional arguments passed to CountVectorizer/FastCountVectorizer.
- Returns:
Each label with corresponding top words and their frequency
- Return type:
Union[FeatureList, MultipleReturn]
- token_information(splits='test', explain_model=True, k=25, filter_words=<Proxy at 0x74f8fe7fd940 wrapping ['de', 'het', 'een'] at 0x74f8fe7d4d00 with factory <function lazy.<locals>.<lambda>>>, lower=True, seed=0, **count_vectorizer_kwargs)
Show the top-k token mutual information for a dataset or model.
- Parameters:
splits (Union[str, List[str]], optional) – Split names to get the explanation for. Defaults to ‘test’.
explain_model (bool, optional) – Whether to explain the model (True) or ground-truth labels (False). Defaults to True.
labelwise (bool, optional) – Whether to summarize the counts for each label seperately. Defaults to True.
k (Optional[int], optional) – Limit to the top-k words per label, or all words if None. Defaults to 25.
filter_words (List[str], optional) – Words to filter out from top-k. Defaults to [‘a’, ‘an’, ‘the’].
lower (bool, optional) – Whether to make all tokens lowercase. Defaults to True.
seed (int, optional) –
**count_vectorizer_kwargs – Optional arguments passed to CountVectorizer/FastCountVectorizer.
- Returns:
- k labels, sorted based on their mutual information with
the output (predictive model labels or ground-truth labels)
- Return type:
Union[FeatureList, MultipleReturn]
- class explabox.Explorer(data=None, ingestibles=None, **kwargs)
Bases:
Readable,IngestiblesMixinThe Explorer explores your data by providing descriptive statistics.
The Explorer requires ‘data’ defined. It is included in the Explabox under the .explore property.
Examples
Get dataset descriptives:
>>> from explabox.explore import Explorer >>> explorer = Explorer(data=data) >>> explorer()
Show the first 10 instances of the test split
>>> from explabox.explore import Explorer >>> explorer = Explorer(data=data) >>> explorer.instances(split="test")[:10]
- Parameters:
data (Optional[Environment], optional) – Data for ingestibles. Defaults to None.
ingestibles (Optional[Ingestible], optional) – Ingestible. Defaults to None.
- descriptives(**kwargs)
Describe features such as the amount per label for the train, test and model predictions and text data specific features such as the maximum/minimum/mean amount of words in a sample and the standard deviation.
- Returns:
Descriptive statistics of each split.
- Return type:
- class explabox.Exposer(data=None, model=None, ingestibles=None, **kwargs)
Bases:
Readable,IngestiblesMixinThe Exposer exposes your model and/or data, by performing sensitivity tests.
With the Exposer you can see model sensitivity to random inputs (robustness), test model generalizability (robustness), and see the effect of adjustments of attributes in the inputs (e.g. swapping male pronouns for female pronouns; fairness), for the dataset as a whole (global) as well as for individual instances (local).
The Exposer requires ‘data’ and ‘model’ defined. It is included in the Explabox under the .expose property.
Examples
See how performance of a model on the test dataset is affected when text is randomly changed to uppercase:
>>> from explabox.expose import Exposer >>> exposer = Exposer(data=data, model=model) >>> exposer.compare_metric(splits='test', perturbation='random_upper')
- Parameters:
data (Optional[Environment], optional) – Data for ingestibles. Defaults to None.
model (Optional[AbstractClassifier], optional) – Model for ingestibles. Defaults to None.
ingestibles (Optional[Ingestible], optional) – Ingestible. Defaults to None.
- compare_metric(perturbation, splits='test')
Compare metrics for each ground-truth label and attribute after applying a dataset-wide perturbation.
Examples
Compare metric of model performance (e.g. accuracy, precision) before and after mapping each instance in the test dataset to uppercase:
>>> box.expose.compare_metric(splits='test', peturbation='upper')
Add ‘!!!’ to the end of each text in the ‘train’ and ‘test’ split and see how it affects performance:
>>> from explabox.expose.text import OneToOnePerturbation >>> perturbation_fn = OneToOnePerturbation(lambda x: f'{x}!!!') >>> box.expose.compare_metrics(splits=['train', 'test'], perturbation=perturbation_fn)
- Parameters:
perturbation (Union[OneToOnePerturbation, str]) – Custom perturbation or one of the default ones, picked by their string: ‘lower’, ‘upper’, ‘random_lower’, ‘random_upper’, ‘add_typos’, ‘random_case_swap’, ‘swap_random’ (swap characters), ‘delete_random’ (delete characters), ‘repeat’ (repeats twice).
splits (Union[str, List[str]], optional) – Split to apply the perturbation to. Defaults to “test”.
- Raises:
ValueError – Unknown perturbation.
- Returns:
- Original label (before perturbation), perturbed label (after
perturbation) and metrics for label-attribute pair.
- Return type:
Union[LabelMetrics, MultipleReturn]
- input_space(generators, n_samples=100, min_length=0, max_length=100, seed=0, **kwargs)
Test the robustness of a machine learning model to different input types (safety).
Example
Test a pretrained black-box model for its robustness to 1000 random strings (length 0 to 500), containing whitespace characters, ASCII (upper, lower and numbers), emojis and Russian Cyrillic characters:
>>> from explabox import Explabox, RandomEmojis, RandomCyrillic >>> box = Explabox(data=data, model=model) >>> box.expose.input_space(generators=['whitespace', ... 'ascii', ... RandomEmojis(base=True), ... RandomCyrillic('ru')], ... n_samples=1000, ... min_length=0, ... max_length=500)
- Parameters:
generators (Union[str, RandomString, List[Union[RandomString, str]]]) – Random character generators. If ‘all’ select all generators. For strings choose from ‘ascii’, ‘emojis, ‘whitespace’, ‘spaces’, ‘ascii_upper’, ‘ascii_lower’, ‘digits’, ‘punctuation’, ‘cyrillic’.
n_samples (int, optional) – Number of test samples. Defaults to 100.
min_length (int, optional) – Input minimum length. Defaults to 0.
max_length (int, optional) – Input maximum length. Defaults to 100.
seed (Optional[int], optional) – Seed for reproducibility purposes. Defaults to 0.
- Returns:
Percentage of success cases, list of succeeded/failed instances
- Return type:
- invariance(pattern, expectation, **kwargs)
Test for the failure rate under invariance.
Example
Test if predictions remain ‘positive’ for 50 samples of the pattern ‘I {like|love} {name} from {city}!’:
>>> from explabox import Explabox >>> box = Explabox(data=data, model=model) >>> box.expose.invariance('I {like|love} {name} from {city}!', expectation='positive', n_samples=50)
- Parameters:
pattern (str) – String pattern to generate examples from.
expectation (Optional[LT], optional) – Expected outcome values. Defaults to None.
**kwargs – Optional arguments passed onto the data.generate.from_pattern() function.
- Returns:
Percentage of success cases, list of succeeded (invariant)/failed (variant) instances
- Return type:
- mean_score(pattern, selected_labels='all', **kwargs)
Calculate mean (probability) score for the given labels, for data generated from a pattern.
Example
Calculate the mean score for the ‘positive’ label for ‘I {like|love} {name} from {city}!’:
>>> from explabox import Explabox >>> box = Explabox(data=data, model=model) >>> box.expose.mean_score('I {like|love} {name} from {city}!', selected_labels='positive', seed=0)
- Parameters:
pattern (str) – Pattern to generate instance from.
selected_labels (Optional[Union[LT, List[LT]]], optional) – Label name to select(s). If None or ‘all’ it is replaced by all labels. Defaults to ‘all’.
**kwargs – Optional arguments passed onto the data.generate.from_pattern() function.
- Return type:
- Returns:
Mean score for one label or all selected labels.
- Return type:
Union[MeanScore, MultipleReturn]
- Parameters:
- class explabox.Ingestible(data=None, model=None, splits={'test': 'test', 'train': 'train', 'validation': 'validation'})
Bases:
dict- Parameters:
data (Environment | None) –
model (AbstractClassifier | None) –
- check_requirements(elements=['data', 'model'])
Check if the required elements are in the ingestibles.
- Parameters:
elements (List[str], optional) – Elements to check. Defaults to [‘data’, ‘model’].
- Raises:
ValueError – The required element is not in the ingestibles.
- Returns:
True if all requirements are included.
- Return type:
bool
- property data
- get_named_split(name, validate=False)
Get split by name.
- Parameters:
name (KT) – Name of split.
validate (bool, optional) – Return None if no split is found or throw an error. Defaults to False.
- Raises:
ValueError – Unknown split
- Returns:
Provider of split if it exists, else None.
- Return type:
Optional[InstanceProvider]
- property labels
Labelprovider.
- property labelset
Label names.
- property model
Predictive model.
- property splits
Names of splits.
- property test
Test data split.
- property train
Train data split.
- property validation
Validation data split.
- explabox.get_locale()
Get current locale.
- Returns:
Current locale.
- Return type:
str
- explabox.import_data(dataset, data_cols, label_cols, label_map=None, method='infer', _to_instancelib=True, **read_kwargs)
Import data in an instancelib Environment.
Examples
Import from an online .csv file with data in the ‘text’ column and labels in ‘category’:
>>> from genbase import import_data >>> ds = import_data('https://storage.googleapis.com/dataset-uploader/bbc/bbc-text.csv', data_cols='text', label_cols='category')
Convert a pandas DataFrame to instancelib Environment:
>>> from genbase import import_data >>> import pandas as pd >>> df = pd.read_csv('https://storage.googleapis.com/dataset-uploader/bbc/bbc-text.csv') >>> ds = import_data(df, data_cols='text', label_cols='category')
Download a .zip file and convert each file in the zip to an instancelib Environment:
>>> from genbase import import_data >>> ds = import_data('https://archive.ics.uci.edu/ml/machine-learning-databases/00462/drugsCom_raw.zip', data_cols='review', label_cols='rating')
Convert a huggingface dataset (sst2) to an instancelib Environment:
>>> from genbase import import_data >>> from datasets import load_dataset >>> ds = import_data(load_dataset('glue', 'sst2'), data_cols='sentence', label_cols='label')
- Parameters:
dataset (_type_) – Dataset to import.
data_cols (Union[KT, List[KT]]) – Name of column(s) containing data.
label_cols (Union[KT, List[KT]]) – Name of column(s) containing labels.
label_map (Optional[Union[Callable, dict]], optional) – Label renaming dictionary/function. Defaults to None.
method (Method, optional) – Method used to import data. Choose from ‘infer’, ‘glob’, ‘pandas’. Defaults to ‘infer’.
_to_instancelib (bool, optional) – Whether to convert the final result to instancelib. Defaults to True.
**read_kwargs – Optional arguments passed to reading call.
- Raises:
ImportError – Unable to import file.
ValueError – Invalid type of method.
NotImplementedError – Import not yet implemented.
- Returns:
Environment for each file or dataset provided.
- Return type:
Union[il.Environment, pd.DataFrame]
- explabox.import_model(model, environment=None, train='train', label_map=None)
Import a model from file or from a Python object.
Examples
Make a scikit-learn text classifier and train it on SST2
>>> from genbase import import_data, import_model >>> from datasets import load_dataset >>> ds = import_data(load_dataset('glue', 'sst2'), data_cols='sentence', label_cols='label') >>> from sklearn.pipeline import Pipeline >>> from sklearn.naive_bayes import MultinomialNB >>> from sklearn.feature_extraction.text import TfidfVectorizer >>> pipeline = Pipeline([('tfidf', TfidfVectorizer()), ... ('clf', MultinomialNB())]) >>> import_model(pipeline, ds, train='train')
- Load a pretrained ONNX model downloaded from
https://github.com/mpbron/instancelib-onnx/blob/main/example_models/data-model.onnx
>>> from genbase import import_model >>> import_model('data-model.onnx', label_map={0: 'Bedrijfsnieuws', 1: 'Games', 2: 'Smartphones'})
- Parameters:
model – Model or path to model to import.
environment (Optional[Environment], optional) – Environment corresponding to model (with dataset and ground-truth labels), used for importing models and/or training them.
train (Union[int, float, str, InstanceProvider], optional) – Train split size, name in environment or provider. Defaults to ‘train’.
label_map (Optional[Dict[LT, LT]], optional) – Conversion of label IDs to named labels. Defaults to None.
- Raises:
ImportError – Unable to import model or file.
NotImplementedError – Type of model is not yet supported.
- Returns:
Instancelib wrapped model.
- Return type:
AbstractClassifier
- explabox.rename_labels(provider, mapping)
Rename labels in a labelprovider or environment.
- Parameters:
provider (Union[il.Environment, il.LabelProvider]) – Provider to rename labels in.
mapping (Union[Callable, dict]) – Rename function or dictionary containing label mapping.
- Returns:
Original provider with labels remapped.
- Return type:
Union[il.Environment, il.LabelProvider]
- explabox.set_locale(locale)
Set current locale (choose from en, nl).
- Parameters:
locale (str) – Locale to change to.
- Return type:
None
- explabox.train_test_split(environment, train_size, train_name='train', test_name='test')
Split an environment into training and test data, and save it to the original environment.
- Parameters:
environment (instancelib.Environment) – Environment containing all data (environment.dataset), including labels (environment.labels).
train_size (Union[int, float]) – Size of training data, as a proportion [0, 1] or number of instances > 1.
train_name (str, optional) – Name of train split. Defaults to ‘train’.
test_name (str, optional) – Name of train split. Defaults to ‘test’.
- Returns:
- Environment with named splits train_name (containing training data) and test_name
(containing test data)
- Return type:
instancelib.Environment
Subpackages:
- explabox.digestibles
- explabox.examine
- explabox.explain
- explabox.explore
- explabox.expose
ExposerLabelMetricsMeanScoreSuccessTest- explabox.expose.text
ExposerLabelMetricsMeanScoreOneToManyPerturbationOneToOnePerturbationRandomAsciiRandomCyrillicRandomDigitsRandomEmojisRandomSpacesRandomStringRandomUpperRandomWhitespaceSuccessTestcompare_accuracy()compare_metric()compare_precision()compare_recall()- explabox.expose.text.characters module
- explabox.expose.text.sentences module
- explabox.expose.text.words module
- explabox.ingestibles
- explabox.ui
- explabox.utils
Submodules:
explabox.config module
Configuration for default paths and variables.
explabox.mixins module
Extensions to classes.
- class explabox.mixins.IngestiblesMixin
Bases:
object- check_requirements(elements=['data', 'model'])
Check if the required elements are in the ingestibles.
- Parameters:
elements (List[str], optional) – Elements to check. Defaults to [‘data’, ‘model’].
- Raises:
ValueError – The required element is not in the ingestibles.
- Returns:
True if all requirements are included.
- Return type:
bool
- property data
All data.
- property labels
Labelprovider.
- property labelset
Names of labels.
- property model
Predictive model.
- property splits
Named splits.