2  Step1: Repeatability

2.1 Repeatability - Random Forest

Code
library(randomForest)
randomForest 4.7-1.2
Type rfNews() to see new features/changes/bug fixes.
Code
library(DALEX)
Welcome to DALEX (version: 2.4.3).
Find examples and detailed introduction at: http://ema.drwhy.ai/
Code
library(iml)
library(mlbench)
library(caret)
Loading required package: ggplot2

Attaching package: 'ggplot2'
The following object is masked from 'package:randomForest':

    margin
Loading required package: lattice
Code
data(PimaIndiansDiabetes)
df <- na.omit(PimaIndiansDiabetes)
set.seed(5293)

train_idx <- createDataPartition(df$diabetes, p = 0.8, list = FALSE)
train_data <- df[train_idx, ]
test_data <- df[-train_idx, ]

lime_results <- list()
shap_results <- list()

for (i in 1:10) {
  set.seed(i)
  rf_model <- randomForest(diabetes ~ ., data = train_data, ntree = 100)

  # LIME
  explainer_lime <- DALEX::explain(
    rf_model,
    data = train_data[, -ncol(train_data)],
    y = train_data$diabetes
  )
  lime_expl <- predict_parts(
    explainer_lime,
    new_observation = test_data[1, -ncol(test_data)],
    type = "break_down"
  )
  lime_results[[i]] <- lime_expl

  # SHAP
  X <- train_data[, -ncol(train_data)]
  predictor <- iml::Predictor$new(
    rf_model,
    data = X,
    y = train_data$diabetes,
    type = "prob"
  )
  shap <- iml::Shapley$new(predictor, x.interest = test_data[1, -ncol(test_data)])
  shap_results[[i]] <- shap$results
}
Preparation of a new explainer is initiated
  -> model label       :  randomForest  (  default  )
  -> data              :  615  rows  8  cols 
  -> target variable   :  615  values 
  -> predict function  :  yhat.randomForest  will be used (  default  )
  -> predicted values  :  No value for predict function target column. (  default  )
  -> model_info        :  package randomForest , ver. 4.7.1.2 , task classification (  default  ) 
  -> model_info        :  Model info detected classification task but 'y' is a factor .  (  WARNING  )
  -> model_info        :  By deafult classification tasks supports only numercical 'y' parameter. 
  -> model_info        :  Consider changing to numerical vector with 0 and 1 values.
  -> model_info        :  Otherwise I will not be able to calculate residuals or loss function.
  -> predicted values  :  numerical, min =  0 , mean =  0.3471545 , max =  0.99  
  -> residual function :  difference between y and yhat (  default  )
Warning in Ops.factor(y, predict_function(model, data)): '-' not meaningful for
factors
  -> residuals         :  numerical, min =  NA , mean =  NA , max =  NA  
  A new explainer has been created!  
Preparation of a new explainer is initiated
  -> model label       :  randomForest  (  default  )
  -> data              :  615  rows  8  cols 
  -> target variable   :  615  values 
  -> predict function  :  yhat.randomForest  will be used (  default  )
  -> predicted values  :  No value for predict function target column. (  default  )
  -> model_info        :  package randomForest , ver. 4.7.1.2 , task classification (  default  ) 
  -> model_info        :  Model info detected classification task but 'y' is a factor .  (  WARNING  )
  -> model_info        :  By deafult classification tasks supports only numercical 'y' parameter. 
  -> model_info        :  Consider changing to numerical vector with 0 and 1 values.
  -> model_info        :  Otherwise I will not be able to calculate residuals or loss function.
  -> predicted values  :  numerical, min =  0 , mean =  0.3489431 , max =  0.98  
  -> residual function :  difference between y and yhat (  default  )
Warning in Ops.factor(y, predict_function(model, data)): '-' not meaningful for
factors
  -> residuals         :  numerical, min =  NA , mean =  NA , max =  NA  
  A new explainer has been created!  
Preparation of a new explainer is initiated
  -> model label       :  randomForest  (  default  )
  -> data              :  615  rows  8  cols 
  -> target variable   :  615  values 
  -> predict function  :  yhat.randomForest  will be used (  default  )
  -> predicted values  :  No value for predict function target column. (  default  )
  -> model_info        :  package randomForest , ver. 4.7.1.2 , task classification (  default  ) 
  -> model_info        :  Model info detected classification task but 'y' is a factor .  (  WARNING  )
  -> model_info        :  By deafult classification tasks supports only numercical 'y' parameter. 
  -> model_info        :  Consider changing to numerical vector with 0 and 1 values.
  -> model_info        :  Otherwise I will not be able to calculate residuals or loss function.
  -> predicted values  :  numerical, min =  0 , mean =  0.3501789 , max =  0.99  
  -> residual function :  difference between y and yhat (  default  )
Warning in Ops.factor(y, predict_function(model, data)): '-' not meaningful for
factors
  -> residuals         :  numerical, min =  NA , mean =  NA , max =  NA  
  A new explainer has been created!  
Preparation of a new explainer is initiated
  -> model label       :  randomForest  (  default  )
  -> data              :  615  rows  8  cols 
  -> target variable   :  615  values 
  -> predict function  :  yhat.randomForest  will be used (  default  )
  -> predicted values  :  No value for predict function target column. (  default  )
  -> model_info        :  package randomForest , ver. 4.7.1.2 , task classification (  default  ) 
  -> model_info        :  Model info detected classification task but 'y' is a factor .  (  WARNING  )
  -> model_info        :  By deafult classification tasks supports only numercical 'y' parameter. 
  -> model_info        :  Consider changing to numerical vector with 0 and 1 values.
  -> model_info        :  Otherwise I will not be able to calculate residuals or loss function.
  -> predicted values  :  numerical, min =  0 , mean =  0.3503252 , max =  0.98  
  -> residual function :  difference between y and yhat (  default  )
Warning in Ops.factor(y, predict_function(model, data)): '-' not meaningful for
factors
  -> residuals         :  numerical, min =  NA , mean =  NA , max =  NA  
  A new explainer has been created!  
Preparation of a new explainer is initiated
  -> model label       :  randomForest  (  default  )
  -> data              :  615  rows  8  cols 
  -> target variable   :  615  values 
  -> predict function  :  yhat.randomForest  will be used (  default  )
  -> predicted values  :  No value for predict function target column. (  default  )
  -> model_info        :  package randomForest , ver. 4.7.1.2 , task classification (  default  ) 
  -> model_info        :  Model info detected classification task but 'y' is a factor .  (  WARNING  )
  -> model_info        :  By deafult classification tasks supports only numercical 'y' parameter. 
  -> model_info        :  Consider changing to numerical vector with 0 and 1 values.
  -> model_info        :  Otherwise I will not be able to calculate residuals or loss function.
  -> predicted values  :  numerical, min =  0 , mean =  0.3474309 , max =  0.99  
  -> residual function :  difference between y and yhat (  default  )
Warning in Ops.factor(y, predict_function(model, data)): '-' not meaningful for
factors
  -> residuals         :  numerical, min =  NA , mean =  NA , max =  NA  
  A new explainer has been created!  
Preparation of a new explainer is initiated
  -> model label       :  randomForest  (  default  )
  -> data              :  615  rows  8  cols 
  -> target variable   :  615  values 
  -> predict function  :  yhat.randomForest  will be used (  default  )
  -> predicted values  :  No value for predict function target column. (  default  )
  -> model_info        :  package randomForest , ver. 4.7.1.2 , task classification (  default  ) 
  -> model_info        :  Model info detected classification task but 'y' is a factor .  (  WARNING  )
  -> model_info        :  By deafult classification tasks supports only numercical 'y' parameter. 
  -> model_info        :  Consider changing to numerical vector with 0 and 1 values.
  -> model_info        :  Otherwise I will not be able to calculate residuals or loss function.
  -> predicted values  :  numerical, min =  0 , mean =  0.3496748 , max =  0.99  
  -> residual function :  difference between y and yhat (  default  )
Warning in Ops.factor(y, predict_function(model, data)): '-' not meaningful for
factors
  -> residuals         :  numerical, min =  NA , mean =  NA , max =  NA  
  A new explainer has been created!  
Preparation of a new explainer is initiated
  -> model label       :  randomForest  (  default  )
  -> data              :  615  rows  8  cols 
  -> target variable   :  615  values 
  -> predict function  :  yhat.randomForest  will be used (  default  )
  -> predicted values  :  No value for predict function target column. (  default  )
  -> model_info        :  package randomForest , ver. 4.7.1.2 , task classification (  default  ) 
  -> model_info        :  Model info detected classification task but 'y' is a factor .  (  WARNING  )
  -> model_info        :  By deafult classification tasks supports only numercical 'y' parameter. 
  -> model_info        :  Consider changing to numerical vector with 0 and 1 values.
  -> model_info        :  Otherwise I will not be able to calculate residuals or loss function.
  -> predicted values  :  numerical, min =  0 , mean =  0.3470244 , max =  0.98  
  -> residual function :  difference between y and yhat (  default  )
Warning in Ops.factor(y, predict_function(model, data)): '-' not meaningful for
factors
  -> residuals         :  numerical, min =  NA , mean =  NA , max =  NA  
  A new explainer has been created!  
Preparation of a new explainer is initiated
  -> model label       :  randomForest  (  default  )
  -> data              :  615  rows  8  cols 
  -> target variable   :  615  values 
  -> predict function  :  yhat.randomForest  will be used (  default  )
  -> predicted values  :  No value for predict function target column. (  default  )
  -> model_info        :  package randomForest , ver. 4.7.1.2 , task classification (  default  ) 
  -> model_info        :  Model info detected classification task but 'y' is a factor .  (  WARNING  )
  -> model_info        :  By deafult classification tasks supports only numercical 'y' parameter. 
  -> model_info        :  Consider changing to numerical vector with 0 and 1 values.
  -> model_info        :  Otherwise I will not be able to calculate residuals or loss function.
  -> predicted values  :  numerical, min =  0 , mean =  0.3438699 , max =  0.98  
  -> residual function :  difference between y and yhat (  default  )
Warning in Ops.factor(y, predict_function(model, data)): '-' not meaningful for
factors
  -> residuals         :  numerical, min =  NA , mean =  NA , max =  NA  
  A new explainer has been created!  
Preparation of a new explainer is initiated
  -> model label       :  randomForest  (  default  )
  -> data              :  615  rows  8  cols 
  -> target variable   :  615  values 
  -> predict function  :  yhat.randomForest  will be used (  default  )
  -> predicted values  :  No value for predict function target column. (  default  )
  -> model_info        :  package randomForest , ver. 4.7.1.2 , task classification (  default  ) 
  -> model_info        :  Model info detected classification task but 'y' is a factor .  (  WARNING  )
  -> model_info        :  By deafult classification tasks supports only numercical 'y' parameter. 
  -> model_info        :  Consider changing to numerical vector with 0 and 1 values.
  -> model_info        :  Otherwise I will not be able to calculate residuals or loss function.
  -> predicted values  :  numerical, min =  0 , mean =  0.3456748 , max =  0.99  
  -> residual function :  difference between y and yhat (  default  )
Warning in Ops.factor(y, predict_function(model, data)): '-' not meaningful for
factors
  -> residuals         :  numerical, min =  NA , mean =  NA , max =  NA  
  A new explainer has been created!  
Preparation of a new explainer is initiated
  -> model label       :  randomForest  (  default  )
  -> data              :  615  rows  8  cols 
  -> target variable   :  615  values 
  -> predict function  :  yhat.randomForest  will be used (  default  )
  -> predicted values  :  No value for predict function target column. (  default  )
  -> model_info        :  package randomForest , ver. 4.7.1.2 , task classification (  default  ) 
  -> model_info        :  Model info detected classification task but 'y' is a factor .  (  WARNING  )
  -> model_info        :  By deafult classification tasks supports only numercical 'y' parameter. 
  -> model_info        :  Consider changing to numerical vector with 0 and 1 values.
  -> model_info        :  Otherwise I will not be able to calculate residuals or loss function.
  -> predicted values  :  numerical, min =  0 , mean =  0.3498374 , max =  0.99  
  -> residual function :  difference between y and yhat (  default  )
Warning in Ops.factor(y, predict_function(model, data)): '-' not meaningful for
factors
  -> residuals         :  numerical, min =  NA , mean =  NA , max =  NA  
  A new explainer has been created!  
Code
# LIME

library(dplyr)

Attaching package: 'dplyr'
The following object is masked from 'package:DALEX':

    explain
The following object is masked from 'package:randomForest':

    combine
The following objects are masked from 'package:stats':

    filter, lag
The following objects are masked from 'package:base':

    intersect, setdiff, setequal, union
Code
library(ggplot2)

lime_df <- lapply(1:10, function(i) {
  df_i <- lime_results[[i]]
  data.frame(
    seed = i,
    variable = df_i$variable_name,
    contribution = df_i$contribution
  )
}) |> bind_rows()


lime_df_clean <- lime_df |>
  filter(variable != "intercept" & variable != "") |>
  mutate(variable = factor(variable))  

lime_summary_clean <- lime_df_clean |>
  group_by(variable) |>
  summarise(
    mean_contribution = mean(contribution),
    sd_contribution = sd(contribution),
    .groups = "drop"
  )

print(lime_summary_clean)
# A tibble: 8 × 3
  variable mean_contribution sd_contribution
  <fct>                <dbl>           <dbl>
1 age                0.0457          0.0117 
2 glucose           -0.156           0.00608
3 insulin           -0.0409          0.0115 
4 mass              -0.0291          0.00747
5 pedigree           0.00408         0.0148 
6 pregnant          -0.0203          0.00815
7 pressure          -0.00941         0.0105 
8 triceps            0.0251          0.0166 
Code
library(ggplot2)

ggplot(lime_df_clean, aes(x = variable, y = contribution)) +
  geom_boxplot(fill = "red") +
  labs(title = "Distribution of LIME Contributions",
       x = "Variable", y = "Contribution") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Code
ggplot(lime_summary_clean, aes(x = reorder(variable, -sd_contribution), y = sd_contribution)) +
  geom_col(fill = "blue") +
  labs(title = "Standard Deviation of LIME Explanations",
       x = "Variable", y = "Standard Deviation") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Code
# SHAP

library(dplyr)
library(ggplot2)

shap_df <- do.call(rbind, lapply(1:10, function(i) {
  df_i <- shap_results[[i]]
  df_i$seed <- i
  df_i
}))

shap_df <- shap_df |>
  rename(variable = feature,
         contribution = phi) |>
  dplyr::select(variable, contribution, seed)

shap_df <- shap_df |>
  filter(variable != "intercept" & variable != "") |>
  mutate(variable = factor(variable))  


shap_summary <- shap_df |>
  group_by(variable) |>
  summarise(
    mean_contribution = mean(contribution),
    sd_contribution = sd(contribution),
    .groups = "drop"
  )

print(shap_summary)
# A tibble: 8 × 3
  variable mean_contribution sd_contribution
  <fct>                <dbl>           <dbl>
1 age               2.78e-18         0.0585 
2 glucose           4.17e-18         0.169  
3 insulin           7.77e-19         0.0168 
4 mass             -2.25e-18         0.0597 
5 pedigree          1.76e-18         0.0166 
6 pregnant          0                0.0306 
7 pressure         -2.60e-19         0.00953
8 triceps           1.71e-18         0.0231 
Code
ggplot(shap_df, aes(x = variable, y = contribution)) +
  geom_boxplot(fill = "green") +
  labs(title = "Distribution of SHAP Contributions",
       x = "Variable", y = "Contribution") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Code
ggplot(shap_summary, aes(x = reorder(variable, -sd_contribution), y = sd_contribution)) +
  geom_col(fill = "yellow") +
  labs(title = "Standard Deviation of SHAP Explanations",
       x = "Variable", y = "Standard Deviation") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

2.2 Repeatability Analysis - Random Forest

In this part, we trained a Random Forest classifier 10 times on the PimaIndiansDiabetes dataset. For each model, we used LIME and SHAP to explain the prediction of the same run Then we aggregated the feature-level contributions and calculated the mean and standard deviation across all runs to assess the repeatability of explanations.

The results show that LIME explanations vary significantly across runs, especially for features with moderate importance such as triceps and pedigree. In contrast, features like glucose exhibited relatively low standard deviation and consistent direction of contribution. For SHAP, although the mean contribution for most features was close to zero, the standard deviation was large for key features like glucose and mass. This suggests that SHAP may be more balanced in average attribution but more sensitive to model perturbations.

In summary, both LIME and SHAP explanations were affected by the choice of random seed, demonstrating non-negligible variability in feature attribution.

2.3 Repeatability - Logistic Regression

Code
#install.packages(c("mlbench", "caret", "DALEX", "DALEXtra", "iml", "lime","dplyr", "ggplot2", "ggpubr"), dependencies = TRUE)

library(mlbench)
library(caret)
library(DALEX)
library(DALEXtra)
library(iml)
library(lime)
library(dplyr)
library(ggplot2)
Code
model_type.glm <- function(x, ...) "classification"
predict_model.glm <- function(x, newdata, ...) {
  preds <- predict(x, newdata, type = "response")
  data.frame(`No` = 1 - preds, `Yes` = preds)
}


data(PimaIndiansDiabetes)
df <- na.omit(PimaIndiansDiabetes)
set.seed(5293)
df$diabetes <- factor(df$diabetes)
X <- df[, -ncol(df)]
y <- df$diabetes

lime_contributions <- list()
shap_contributions <- list()


train_idx <- createDataPartition(df$diabetes, p = 0.8, list = FALSE)
train_data <- df[train_idx, ]
test_data <- df[-train_idx, ]

In the first step, we evaluate the repeatability of LIME explanations by repeatedly training the model and generating explanations to understand their consistency.

We conduct self-sampling (bootstrap) on the training data to obtain multiple different training sets. Each time, we train the logistic regression model on the newly sampled data and run the LIME interpretation model prediction with the same test samples, and calculate the standard deviation of the contribution value of each feature in multiple runs.

Code
n_runs <- 10
lime_contribs <- list()

for (i in 1:n_runs) {
  boot_idx <- sample(nrow(train_data), replace = TRUE)
  boot_train <- train_data[boot_idx, ]

  logit_model <- glm(diabetes ~ ., data = boot_train, family = binomial)

  explainer <- DALEX::explain(
    model = logit_model,
    data = boot_train[, -ncol(boot_train)],
    y = as.numeric(boot_train$diabetes == "pos"),
    label = paste0("glm_", i),
    predict_function = function(m, d) predict(m, d, type = "response")
  )

  lime_result <- predict_parts(explainer, new_observation = test_data[1, -ncol(test_data)],
                               type = "break_down")
  lime_df <- lime_result %>%
    filter(variable != "intercept") %>%
    select(variable, contribution)

  lime_contribs[[i]] <- lime_df
}
Preparation of a new explainer is initiated
  -> model label       :  glm_1 
  -> data              :  615  rows  8  cols 
  -> target variable   :  615  values 
  -> predict function  :  function(m, d) predict(m, d, type = "response") 
  -> predicted values  :  No value for predict function target column. (  default  )
  -> model_info        :  package stats , ver. 4.4.2 , task classification (  default  ) 
  -> predicted values  :  numerical, min =  0.001490493 , mean =  0.3593496 , max =  0.9958617  
  -> residual function :  difference between y and yhat (  default  )
  -> residuals         :  numerical, min =  -0.9534075 , mean =  -3.827759e-13 , max =  0.9856082  
  A new explainer has been created!  
Preparation of a new explainer is initiated
  -> model label       :  glm_2 
  -> data              :  615  rows  8  cols 
  -> target variable   :  615  values 
  -> predict function  :  function(m, d) predict(m, d, type = "response") 
  -> predicted values  :  No value for predict function target column. (  default  )
  -> model_info        :  package stats , ver. 4.4.2 , task classification (  default  ) 
  -> predicted values  :  numerical, min =  0.002668286 , mean =  0.3219512 , max =  0.978063  
  -> residual function :  difference between y and yhat (  default  )
  -> residuals         :  numerical, min =  -0.8972503 , mean =  -2.019077e-13 , max =  0.9888889  
  A new explainer has been created!  
Preparation of a new explainer is initiated
  -> model label       :  glm_3 
  -> data              :  615  rows  8  cols 
  -> target variable   :  615  values 
  -> predict function  :  function(m, d) predict(m, d, type = "response") 
  -> predicted values  :  No value for predict function target column. (  default  )
  -> model_info        :  package stats , ver. 4.4.2 , task classification (  default  ) 
  -> predicted values  :  numerical, min =  0.002188936 , mean =  0.3447154 , max =  0.9860676  
  -> residual function :  difference between y and yhat (  default  )
  -> residuals         :  numerical, min =  -0.8505019 , mean =  -5.432463e-15 , max =  0.9907279  
  A new explainer has been created!  
Preparation of a new explainer is initiated
  -> model label       :  glm_4 
  -> data              :  615  rows  8  cols 
  -> target variable   :  615  values 
  -> predict function  :  function(m, d) predict(m, d, type = "response") 
  -> predicted values  :  No value for predict function target column. (  default  )
  -> model_info        :  package stats , ver. 4.4.2 , task classification (  default  ) 
  -> predicted values  :  numerical, min =  0.0004471588 , mean =  0.3317073 , max =  0.9980853  
  -> residual function :  difference between y and yhat (  default  )
  -> residuals         :  numerical, min =  -0.94405 , mean =  -1.474228e-10 , max =  0.9947934  
  A new explainer has been created!  
Preparation of a new explainer is initiated
  -> model label       :  glm_5 
  -> data              :  615  rows  8  cols 
  -> target variable   :  615  values 
  -> predict function  :  function(m, d) predict(m, d, type = "response") 
  -> predicted values  :  No value for predict function target column. (  default  )
  -> model_info        :  package stats , ver. 4.4.2 , task classification (  default  ) 
  -> predicted values  :  numerical, min =  0.001453277 , mean =  0.3495935 , max =  0.9830114  
  -> residual function :  difference between y and yhat (  default  )
  -> residuals         :  numerical, min =  -0.9333344 , mean =  -2.370711e-15 , max =  0.9933661  
  A new explainer has been created!  
Preparation of a new explainer is initiated
  -> model label       :  glm_6 
  -> data              :  615  rows  8  cols 
  -> target variable   :  615  values 
  -> predict function  :  function(m, d) predict(m, d, type = "response") 
  -> predicted values  :  No value for predict function target column. (  default  )
  -> model_info        :  package stats , ver. 4.4.2 , task classification (  default  ) 
  -> predicted values  :  numerical, min =  0.004191668 , mean =  0.3447154 , max =  0.9763506  
  -> residual function :  difference between y and yhat (  default  )
  -> residuals         :  numerical, min =  -0.9545668 , mean =  -1.842577e-13 , max =  0.9958083  
  A new explainer has been created!  
Preparation of a new explainer is initiated
  -> model label       :  glm_7 
  -> data              :  615  rows  8  cols 
  -> target variable   :  615  values 
  -> predict function  :  function(m, d) predict(m, d, type = "response") 
  -> predicted values  :  No value for predict function target column. (  default  )
  -> model_info        :  package stats , ver. 4.4.2 , task classification (  default  ) 
  -> predicted values  :  numerical, min =  0.004528123 , mean =  0.3252033 , max =  0.9956203  
  -> residual function :  difference between y and yhat (  default  )
  -> residuals         :  numerical, min =  -0.9475119 , mean =  -9.104453e-15 , max =  0.983609  
  A new explainer has been created!  
Preparation of a new explainer is initiated
  -> model label       :  glm_8 
  -> data              :  615  rows  8  cols 
  -> target variable   :  615  values 
  -> predict function  :  function(m, d) predict(m, d, type = "response") 
  -> predicted values  :  No value for predict function target column. (  default  )
  -> model_info        :  package stats , ver. 4.4.2 , task classification (  default  ) 
  -> predicted values  :  numerical, min =  0.003427715 , mean =  0.3560976 , max =  0.9924571  
  -> residual function :  difference between y and yhat (  default  )
  -> residuals         :  numerical, min =  -0.9353339 , mean =  -3.663064e-16 , max =  0.9104446  
  A new explainer has been created!  
Preparation of a new explainer is initiated
  -> model label       :  glm_9 
  -> data              :  615  rows  8  cols 
  -> target variable   :  615  values 
  -> predict function  :  function(m, d) predict(m, d, type = "response") 
  -> predicted values  :  No value for predict function target column. (  default  )
  -> model_info        :  package stats , ver. 4.4.2 , task classification (  default  ) 
  -> predicted values  :  numerical, min =  0.007305473 , mean =  0.3658537 , max =  0.9946787  
  -> residual function :  difference between y and yhat (  default  )
  -> residuals         :  numerical, min =  -0.9522851 , mean =  -6.758618e-14 , max =  0.9577366  
  A new explainer has been created!  
Preparation of a new explainer is initiated
  -> model label       :  glm_10 
  -> data              :  615  rows  8  cols 
  -> target variable   :  615  values 
  -> predict function  :  function(m, d) predict(m, d, type = "response") 
  -> predicted values  :  No value for predict function target column. (  default  )
  -> model_info        :  package stats , ver. 4.4.2 , task classification (  default  ) 
  -> predicted values  :  numerical, min =  0.001906982 , mean =  0.3284553 , max =  0.9547832  
  -> residual function :  difference between y and yhat (  default  )
  -> residuals         :  numerical, min =  -0.9030004 , mean =  -1.521891e-15 , max =  0.9934916  
  A new explainer has been created!  
Code
lime_summary <- bind_rows(lime_contribs, .id = "run") %>%
  group_by(variable) %>%
  summarise(sd_contribution = sd(contribution), .groups = "drop")

library(ggplot2)
ggplot(lime_summary, aes(x = reorder(variable, -sd_contribution), y = sd_contribution)) +
  geom_col(fill = "steelblue") +
  labs(title = "LIME Repeatability (SD of Contributions)", x = "Variable", y = "SD") +
  theme_minimal()

2.4 Repeatability Analysis - Logistic Regression

The column height indicates the standard deviation of the LIME contribution for each feature across different model runs. A higher column means greater variation in the feature’s attribution, indicating worse repeatability, a lower column implies more consistent contributions, indicating greater stability.

We found that LIME explanations were more sensitive to training data changes for features like mass and glucose, which had the highest standard deviations in contribution across runs. However, features such as pressure, age, and pedigree showed very low variability, with consistently stable contributions across repeated model trainings. This suggests that for these features, LIME explanations are highly repeatable and robust.