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, IngestiblesMixin

The 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:

Performance

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:

WronglyClassified

class explabox.Explabox(ingestibles=None, locale='en', **kwargs)

Bases: Readable, IngestiblesMixin

Use 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, IngestiblesMixin

The 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, IngestiblesMixin

The 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:

Descriptives

instances(split='test', **kwargs)

Get the instances of the given split.

Parameters:

split (str, optional) – Split to select. Defaults to “test”.

Returns:

Instances in the split.

Return type:

Dataset

class explabox.Exposer(data=None, model=None, ingestibles=None, **kwargs)

Bases: Readable, IngestiblesMixin

The 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:

SuccessTest

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:

SuccessTest

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:

MeanScore | MultipleReturn

Returns:

Mean score for one label or all selected labels.

Return type:

Union[MeanScore, MultipleReturn]

Parameters:
  • pattern (str) –

  • selected_labels (LT | List[LT] | None) –

class explabox.Ingestible(data=None, model=None, splits={'test': 'test', 'train': 'train', 'validation': 'validation'})

Bases: dict

Parameters:
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:

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.

class explabox.mixins.ModelMixin

Bases: object

property is_classifier: bool

Whether the included model is a classifier (True) or not (False).