liveBook · Manning

Counterfactual explanation

As explained in Outlier Detection in Python

A counterfactual explanation is a hypothetical minimally changed input whose model outcome differs from that of the original input.

A counterfactual explanation identifies the smallest changes to an input that would produce a different model outcome. For outlier detection, it shows the minimum change needed for an outlier record to become an inlier. section 13.2.4

Constructing a counterfactual explanation typically involves:

  • Select an outlier, preferably one close to the inlier threshold, so the required changes are easier to interpret. section 13.2.4
  • Prepare feature representations carefully: specify categorical and numeric variables, use ordinal encoding where appropriate, and scale values so column magnitudes are comparable. section 13.2.4
  • Provide a probability-like prediction interface when the detector lacks predict_proba(), then generate several minimally changed alternatives. section 13.2.4
  • Interpret the changed features as candidate causes, while remembering that counterfactuals may not fully reveal feature interactions or the detector’s complete logic. section 13.2.5

Abalone outlier

For an IsolationForest outlier in encoded and scaled abalone data, three counterfactuals alter only one feature at a time: Viscera_weight, Shucked_weight, or Length. Stronger outliers generally require changes to multiple features before becoming inliers. section 13.2.4

Listing 13.9 Generating counterfactual explanations using DiCE
import pandas as pd
import numpy as np
from sklearn.preprocessing import RobustScaler, OrdinalEncoder
from sklearn.datasets import fetch_openml
from sklearn.ensemble import IsolationForest
import dice_ml
 
np.random.seed(0)
 
data = fetch_openml('abalone', version=1, parser='auto')           #1
df = pd.DataFrame(data.data, columns=data.feature_names)
df = pd.DataFrame(OrdinalEncoder().fit_transform(df), columns=df.columns) 
df = pd.DataFrame(RobustScaler().fit_transform(df), columns=df.columns)
orig_features = list(df.columns)
 
det = IsolationForest()                                            #2
det.fit(df)
df['IF Score'] = det.score_samples(df)
 
class IF_wrapper:                                                  #3
    def __init__(self, det, cutoff):
      self.det = det
      self.cutoff = cutoff
 
    def predict_proba(self, x):
      return self.det.score_samples(x) < self.cutoff
 
if_wrapped = IF_wrapper(det, -0.6)                                 #4
 
df['IF Outlier'] = df['IF Score'] < -0.6                           #5
 
d = dice_ml.Data(                                                  #6
    dataframe=df[orig_features + ['IF Outlier']],
    continuous_features=['Sex', 'Length', 'Diameter', 'Height', 
                         'Whole_weight', 'Shucked_weight', 
                         'Viscera_weight'],
    outcome_name='IF Outlier')
 
m = dice_ml.Model(model=if_wrapped, backend='sklearn')
exp = dice_ml.Dice(d, m, method='random')
query_instance = df.loc[2810:2810][orig_features]
dice_exp = exp.generate_counterfactuals(
     query_instance, total_CFs=4, desired_class="opposite")        #7
dice_exp.visualize_as_dataframe()

The DiCE listing demonstrates data preparation, IsolationForest wrapping, and counterfactual generation. section 13.2.4

How Outlier Detection in Python covers it

How deep it goes
Provides an implementation workflow with encoding, scaling, model wrapping, and generated alternatives, but stops short of complete detector interpretation.
Examples
Uses an encoded and scaled abalone outlier whose counterfactuals modify Length, Shucked_weight, or Viscera_weight.
What it assumes
Assumes a fitted detector, relevant features, encoded data, comparable feature scales, and a probability-like prediction interface.
What you can do after
Apply it via DiCE to generate alternative records that cross an outlier detector’s inlier threshold.
How it connects
Connects counterfactuals with explainable AI, outlier detection, IsolationForest, proxy models, feature importances, and ALE plots.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Outlier Detection in Python. The section links point to the parts of the book it draws on.