knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.path = "man/figures/README-", fig.height = 3, fig.width = 8 ) options(width = 200) set.seed(12345)
The counterfactuals package provides various (model-agnostic) counterfactual explanation methods via a unified R6-based interface.
Counterfactual explanation methods address questions of the form: "For input $\mathbf{x^{\star}}$, the model predicted $y$. What needs to be changed in $\mathbf{x^{\star}}$ for the model to predict a desired outcome $\tilde{y}$ instead?". \ Denied loan applications serve as a common example; here a counterfactual explanation (or counterfactual for short) could be: "The loan was denied because the amount of €30k is too high given the income. If the amount had been €20k, the loan would have been granted."
For an introduction to counterfactual explanation methods, we recommend Chapter 9.3 of the Interpretable Machine Learning book by Christoph Molnar. The package is based on the R code underlying the paper Multi-Objective Counterfactual Explanations (MOC).
The following counterfactual explanation methods are currently implemented:
You can install the development version from GitHub with:
# install.packages("devtools") devtools::install_github("dandls/counterfactuals")
In this example, we train a randomForest on the iris dataset and examine how a given virginica observation
would have to change in order to be classified as versicolor.
library(counterfactuals) library(randomForest) library(iml)
First, we train a randomForest model to predict the target variable Species, omitting one observation from the training
data, which is x_interest (the observation $x^{\star}$ for which we want to find counterfactuals).
rf = randomForest(Species ~ ., data = iris[-150L, ])
We then create an iml::Predictor object, which serves as
a wrapper for different model types; it contains the model and the data for its analysis.
predictor = Predictor$new(rf, type = "prob")
For x_interest, the model predicts a probability of 8% for class versicolor.
x_interest = iris[150L, ] predictor$predict(x_interest)
Now, we examine what needs to be changed in x_interest so that the model predicts a probability of at least 50% for class versicolor.
Here, we want to apply WhatIf and since it is a classification task, we create a WhatIfClassif object.
wi_classif = WhatIfClassif$new(predictor, n_counterfactuals = 5L)
Then, we use the find_counterfactuals() method to find counterfactuals for x_interest.
cfactuals = wi_classif$find_counterfactuals( x_interest, desired_class = "versicolor", desired_prob = c(0.5, 1) )
cfactuals is a Counterfactuals object that contains the counterfactuals and has several methods for their
evaluation and visualization.
cfactuals
The counterfactuals are stored in the data field.
cfactuals$data
With the evaluate() method, we can evaluate the counterfactuals using various quality measures.
cfactuals$evaluate()
One visualization option is to plot the frequency of feature changes across all counterfactuals using the
plot_freq_of_feature_changes() method.
cfactuals$plot_freq_of_feature_changes()
Another visualization option is a parallel plot---created with the plot_parallel() method---that connects the (scaled)
feature values of each counterfactual and highlights x_interest in blue.
cfactuals$plot_parallel()
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.