diff --git a/R/commonMachineLearningRegression.R b/R/commonMachineLearningRegression.R
index 764ec77a..4578963d 100644
--- a/R/commonMachineLearningRegression.R
+++ b/R/commonMachineLearningRegression.R
@@ -750,6 +750,67 @@
}
}
+.mlPredictionsToMatrix <- function(predictions) {
+ if (is.data.frame(predictions) || is.matrix(predictions)) {
+ return(as.matrix(predictions))
+ }
+ if (is.array(predictions)) {
+ if (length(dim(predictions)) == 3) {
+ return(predictions[, , dim(predictions)[3], drop = FALSE])
+ }
+ return(as.matrix(predictions))
+ }
+ if (is.atomic(predictions)) {
+ return(matrix(predictions, ncol = 1))
+ }
+ return(NULL)
+}
+
+.mlSinglePredictorShapFallback <- function(observation, explainer, purpose, predictedLabel = NULL, classLevels = NULL) {
+ trainPredictions <- explainer$predict_function(explainer$model, explainer$data)
+ casePrediction <- explainer$predict_function(explainer$model, observation)
+
+ if (purpose == "regression") {
+ casePrediction <- as.numeric(casePrediction)[1]
+ basePrediction <- mean(as.numeric(trainPredictions), na.rm = TRUE)
+ return(list(
+ predicted = casePrediction,
+ base = basePrediction,
+ contribution = casePrediction - basePrediction
+ ))
+ }
+
+ trainPredictions <- .mlPredictionsToMatrix(trainPredictions)
+ casePrediction <- .mlPredictionsToMatrix(casePrediction)
+
+ if (is.null(trainPredictions) || is.null(casePrediction) || ncol(casePrediction) < 1) {
+ stop("Could not compute fallback additive explanations for classification.")
+ }
+
+ predictedIndex <- which.max(casePrediction[1, ])
+ predictedProb <- casePrediction[1, predictedIndex]
+ baseProb <- mean(trainPredictions[, predictedIndex], na.rm = TRUE)
+
+ if (!is.null(predictedLabel)) {
+ label <- predictedLabel
+ } else {
+ labels <- classLevels
+ if (is.null(labels) || length(labels) < predictedIndex) {
+ labels <- colnames(casePrediction)
+ }
+ if (is.null(labels) || length(labels) < predictedIndex) {
+ labels <- as.character(seq_len(ncol(casePrediction)))
+ }
+ label <- labels[predictedIndex]
+ }
+
+ return(list(
+ predicted = paste0(label, " (", round(predictedProb, 3), ")"),
+ base = baseProb,
+ contribution = predictedProb - baseProb
+ ))
+}
+
.mlTableShap <- function(dataset, options, jaspResults, ready, position, purpose, model = NULL) {
if (!is.null(jaspResults[["tableShap"]]) || !options[["tableShap"]]) {
return()
@@ -807,7 +868,32 @@
p <- try({
for (i in seq_along(from:to)) {
out[i, 1] <- (from:to)[i]
- shap <- DALEX::predict_parts(explainer, new_observation = as.data.frame(x_test[(from:to)[i], predictors, drop = FALSE]))
+ observation <- as.data.frame(x_test[(from:to)[i], predictors, drop = FALSE])
+ shap <- try(DALEX::predict_parts(explainer, new_observation = observation), silent = TRUE)
+
+ if (isTryError(shap)) {
+ fallbackRequired <- length(predictors) == 1 &&
+ is.numeric(x_test[[predictors[1]]]) &&
+ grepl("replacement has 1 row, data has", .extractErrorMessage(shap), fixed = TRUE)
+
+ if (!fallbackRequired) {
+ stop(shap)
+ }
+
+ fallback <- .mlSinglePredictorShapFallback(
+ observation = observation,
+ explainer = explainer,
+ purpose = purpose,
+ predictedLabel = if (purpose == "classification" && !is.null(model)) as.character(predictions[i]) else NULL,
+ classLevels = if (purpose == "classification" && is.null(model)) levels(result[["test"]][, options[["target"]]]) else NULL
+ )
+
+ out[i, 2] <- fallback[["predicted"]]
+ out[i, 3] <- fallback[["base"]]
+ out[i, 4] <- fallback[["contribution"]]
+ next
+ }
+
if (purpose == "regression") {
out[i, 2] <- shap[which(shap[["variable"]] == "prediction"), "contribution"]
} else {
diff --git a/tests/testthat/_snaps/mlclassificationboosting/data-split.new.svg b/tests/testthat/_snaps/mlclassificationboosting/data-split.new.svg
new file mode 100644
index 00000000..689c5b50
--- /dev/null
+++ b/tests/testthat/_snaps/mlclassificationboosting/data-split.new.svg
@@ -0,0 +1,44 @@
+
+
diff --git a/tests/testthat/_snaps/mlclassificationboosting/relative-influence-plot.new.svg b/tests/testthat/_snaps/mlclassificationboosting/relative-influence-plot.new.svg
new file mode 100644
index 00000000..1293ceb8
--- /dev/null
+++ b/tests/testthat/_snaps/mlclassificationboosting/relative-influence-plot.new.svg
@@ -0,0 +1,81 @@
+
+
diff --git a/tests/testthat/_snaps/mlclassificationdecisiontree/data-split.new.svg b/tests/testthat/_snaps/mlclassificationdecisiontree/data-split.new.svg
new file mode 100644
index 00000000..b254084a
--- /dev/null
+++ b/tests/testthat/_snaps/mlclassificationdecisiontree/data-split.new.svg
@@ -0,0 +1,44 @@
+
+
diff --git a/tests/testthat/_snaps/mlclassificationdecisiontree/decision-tree-plot.new.svg b/tests/testthat/_snaps/mlclassificationdecisiontree/decision-tree-plot.new.svg
new file mode 100644
index 00000000..43ac1390
--- /dev/null
+++ b/tests/testthat/_snaps/mlclassificationdecisiontree/decision-tree-plot.new.svg
@@ -0,0 +1,77 @@
+
+
diff --git a/tests/testthat/_snaps/mlclassificationknn/data-split.new.svg b/tests/testthat/_snaps/mlclassificationknn/data-split.new.svg
new file mode 100644
index 00000000..689c5b50
--- /dev/null
+++ b/tests/testthat/_snaps/mlclassificationknn/data-split.new.svg
@@ -0,0 +1,44 @@
+
+
diff --git a/tests/testthat/_snaps/mlclassificationlda/data-split.new.svg b/tests/testthat/_snaps/mlclassificationlda/data-split.new.svg
new file mode 100644
index 00000000..c71e60c8
--- /dev/null
+++ b/tests/testthat/_snaps/mlclassificationlda/data-split.new.svg
@@ -0,0 +1,42 @@
+
+
diff --git a/tests/testthat/_snaps/mlclassificationlda/linear-discriminant-matrix-subplot-1.new.svg b/tests/testthat/_snaps/mlclassificationlda/linear-discriminant-matrix-subplot-1.new.svg
new file mode 100644
index 00000000..8671359b
--- /dev/null
+++ b/tests/testthat/_snaps/mlclassificationlda/linear-discriminant-matrix-subplot-1.new.svg
@@ -0,0 +1,34 @@
+
+
diff --git a/tests/testthat/_snaps/mlclassificationlda/linear-discriminant-matrix-subplot-2.new.svg b/tests/testthat/_snaps/mlclassificationlda/linear-discriminant-matrix-subplot-2.new.svg
new file mode 100644
index 00000000..0e26527a
--- /dev/null
+++ b/tests/testthat/_snaps/mlclassificationlda/linear-discriminant-matrix-subplot-2.new.svg
@@ -0,0 +1,34 @@
+
+
diff --git a/tests/testthat/_snaps/mlclassificationlda/linear-discriminant-matrix-subplot-3.new.svg b/tests/testthat/_snaps/mlclassificationlda/linear-discriminant-matrix-subplot-3.new.svg
new file mode 100644
index 00000000..2f335974
--- /dev/null
+++ b/tests/testthat/_snaps/mlclassificationlda/linear-discriminant-matrix-subplot-3.new.svg
@@ -0,0 +1,34 @@
+
+
diff --git a/tests/testthat/_snaps/mlclassificationlda/linear-discriminant-matrix-subplot-4.new.svg b/tests/testthat/_snaps/mlclassificationlda/linear-discriminant-matrix-subplot-4.new.svg
new file mode 100644
index 00000000..5ef6e498
--- /dev/null
+++ b/tests/testthat/_snaps/mlclassificationlda/linear-discriminant-matrix-subplot-4.new.svg
@@ -0,0 +1,59 @@
+
+
diff --git a/tests/testthat/_snaps/mlclassificationlda/linear-discriminant-matrix-subplot-5.new.svg b/tests/testthat/_snaps/mlclassificationlda/linear-discriminant-matrix-subplot-5.new.svg
new file mode 100644
index 00000000..4cbffa76
--- /dev/null
+++ b/tests/testthat/_snaps/mlclassificationlda/linear-discriminant-matrix-subplot-5.new.svg
@@ -0,0 +1,227 @@
+
+
diff --git a/tests/testthat/_snaps/mlclassificationlda/linear-discriminant-matrix-subplot-6.new.svg b/tests/testthat/_snaps/mlclassificationlda/linear-discriminant-matrix-subplot-6.new.svg
new file mode 100644
index 00000000..eb5317c1
--- /dev/null
+++ b/tests/testthat/_snaps/mlclassificationlda/linear-discriminant-matrix-subplot-6.new.svg
@@ -0,0 +1,34 @@
+
+
diff --git a/tests/testthat/_snaps/mlclassificationlda/linear-discriminant-matrix-subplot-8.new.svg b/tests/testthat/_snaps/mlclassificationlda/linear-discriminant-matrix-subplot-8.new.svg
new file mode 100644
index 00000000..fb2ecf61
--- /dev/null
+++ b/tests/testthat/_snaps/mlclassificationlda/linear-discriminant-matrix-subplot-8.new.svg
@@ -0,0 +1,59 @@
+
+
diff --git a/tests/testthat/_snaps/mlclassificationlogisticmultinomial/data-split-1.new.svg b/tests/testthat/_snaps/mlclassificationlogisticmultinomial/data-split-1.new.svg
new file mode 100644
index 00000000..3af22552
--- /dev/null
+++ b/tests/testthat/_snaps/mlclassificationlogisticmultinomial/data-split-1.new.svg
@@ -0,0 +1,42 @@
+
+
diff --git a/tests/testthat/_snaps/mlclassificationlogisticmultinomial/data-split-2.new.svg b/tests/testthat/_snaps/mlclassificationlogisticmultinomial/data-split-2.new.svg
new file mode 100644
index 00000000..a1148ca2
--- /dev/null
+++ b/tests/testthat/_snaps/mlclassificationlogisticmultinomial/data-split-2.new.svg
@@ -0,0 +1,42 @@
+
+
diff --git a/tests/testthat/_snaps/mlclassificationnaivebayes/data-split.new.svg b/tests/testthat/_snaps/mlclassificationnaivebayes/data-split.new.svg
new file mode 100644
index 00000000..fa95a138
--- /dev/null
+++ b/tests/testthat/_snaps/mlclassificationnaivebayes/data-split.new.svg
@@ -0,0 +1,42 @@
+
+
diff --git a/tests/testthat/_snaps/mlclassificationrandomforest/data-split.new.svg b/tests/testthat/_snaps/mlclassificationrandomforest/data-split.new.svg
new file mode 100644
index 00000000..689c5b50
--- /dev/null
+++ b/tests/testthat/_snaps/mlclassificationrandomforest/data-split.new.svg
@@ -0,0 +1,44 @@
+
+
diff --git a/tests/testthat/_snaps/mlclassificationrandomforest/mean-decrease-in-accuracy.new.svg b/tests/testthat/_snaps/mlclassificationrandomforest/mean-decrease-in-accuracy.new.svg
new file mode 100644
index 00000000..5a280d98
--- /dev/null
+++ b/tests/testthat/_snaps/mlclassificationrandomforest/mean-decrease-in-accuracy.new.svg
@@ -0,0 +1,77 @@
+
+
diff --git a/tests/testthat/_snaps/mlclassificationrandomforest/total-increase-in-node-purity.new.svg b/tests/testthat/_snaps/mlclassificationrandomforest/total-increase-in-node-purity.new.svg
new file mode 100644
index 00000000..e2c5db28
--- /dev/null
+++ b/tests/testthat/_snaps/mlclassificationrandomforest/total-increase-in-node-purity.new.svg
@@ -0,0 +1,81 @@
+
+
diff --git a/tests/testthat/_snaps/mlclassificationsvm/data-split.new.svg b/tests/testthat/_snaps/mlclassificationsvm/data-split.new.svg
new file mode 100644
index 00000000..b254084a
--- /dev/null
+++ b/tests/testthat/_snaps/mlclassificationsvm/data-split.new.svg
@@ -0,0 +1,44 @@
+
+
diff --git a/tests/testthat/_snaps/mlclusteringdensitybased/all-predictors.new.svg b/tests/testthat/_snaps/mlclusteringdensitybased/all-predictors.new.svg
new file mode 100644
index 00000000..780d3aad
--- /dev/null
+++ b/tests/testthat/_snaps/mlclusteringdensitybased/all-predictors.new.svg
@@ -0,0 +1,340 @@
+
+
diff --git a/tests/testthat/_snaps/mlclusteringdensitybased/k-distance-plot.new.svg b/tests/testthat/_snaps/mlclusteringdensitybased/k-distance-plot.new.svg
new file mode 100644
index 00000000..4f63f741
--- /dev/null
+++ b/tests/testthat/_snaps/mlclusteringdensitybased/k-distance-plot.new.svg
@@ -0,0 +1,70 @@
+
+
diff --git a/tests/testthat/_snaps/mlclusteringfuzzycmeans/all-predictors.new.svg b/tests/testthat/_snaps/mlclusteringfuzzycmeans/all-predictors.new.svg
new file mode 100644
index 00000000..b5db25f8
--- /dev/null
+++ b/tests/testthat/_snaps/mlclusteringfuzzycmeans/all-predictors.new.svg
@@ -0,0 +1,287 @@
+
+
diff --git a/tests/testthat/_snaps/mlclusteringhierarchical/all-predictors.new.svg b/tests/testthat/_snaps/mlclusteringhierarchical/all-predictors.new.svg
new file mode 100644
index 00000000..655679df
--- /dev/null
+++ b/tests/testthat/_snaps/mlclusteringhierarchical/all-predictors.new.svg
@@ -0,0 +1,456 @@
+
+
diff --git a/tests/testthat/_snaps/mlclusteringhierarchical/dendogram.new.svg b/tests/testthat/_snaps/mlclusteringhierarchical/dendogram.new.svg
new file mode 100644
index 00000000..04115d17
--- /dev/null
+++ b/tests/testthat/_snaps/mlclusteringhierarchical/dendogram.new.svg
@@ -0,0 +1,745 @@
+
+
diff --git a/tests/testthat/_snaps/mlclusteringkmeans/all-predictors-2.new.svg b/tests/testthat/_snaps/mlclusteringkmeans/all-predictors-2.new.svg
new file mode 100644
index 00000000..d9271b15
--- /dev/null
+++ b/tests/testthat/_snaps/mlclusteringkmeans/all-predictors-2.new.svg
@@ -0,0 +1,395 @@
+
+
diff --git a/tests/testthat/_snaps/mlclusteringkmeans/all-predictors-3.new.svg b/tests/testthat/_snaps/mlclusteringkmeans/all-predictors-3.new.svg
new file mode 100644
index 00000000..0e7ec666
--- /dev/null
+++ b/tests/testthat/_snaps/mlclusteringkmeans/all-predictors-3.new.svg
@@ -0,0 +1,346 @@
+
+
diff --git a/tests/testthat/_snaps/mlclusteringkmeans/all-predictors.new.svg b/tests/testthat/_snaps/mlclusteringkmeans/all-predictors.new.svg
new file mode 100644
index 00000000..1be56706
--- /dev/null
+++ b/tests/testthat/_snaps/mlclusteringkmeans/all-predictors.new.svg
@@ -0,0 +1,344 @@
+
+
diff --git a/tests/testthat/_snaps/mlclusteringmodelbased/all-predictors.new.svg b/tests/testthat/_snaps/mlclusteringmodelbased/all-predictors.new.svg
new file mode 100644
index 00000000..efb20b5d
--- /dev/null
+++ b/tests/testthat/_snaps/mlclusteringmodelbased/all-predictors.new.svg
@@ -0,0 +1,234 @@
+
+
diff --git a/tests/testthat/_snaps/mlclusteringrandomforest/all-predictors.new.svg b/tests/testthat/_snaps/mlclusteringrandomforest/all-predictors.new.svg
new file mode 100644
index 00000000..b86a5421
--- /dev/null
+++ b/tests/testthat/_snaps/mlclusteringrandomforest/all-predictors.new.svg
@@ -0,0 +1,234 @@
+
+
diff --git a/tests/testthat/_snaps/mlregressionboosting/data-split.new.svg b/tests/testthat/_snaps/mlregressionboosting/data-split.new.svg
new file mode 100644
index 00000000..689c5b50
--- /dev/null
+++ b/tests/testthat/_snaps/mlregressionboosting/data-split.new.svg
@@ -0,0 +1,44 @@
+
+
diff --git a/tests/testthat/_snaps/mlregressionboosting/relative-influence-plot.new.svg b/tests/testthat/_snaps/mlregressionboosting/relative-influence-plot.new.svg
new file mode 100644
index 00000000..53e8d6e5
--- /dev/null
+++ b/tests/testthat/_snaps/mlregressionboosting/relative-influence-plot.new.svg
@@ -0,0 +1,79 @@
+
+
diff --git a/tests/testthat/_snaps/mlregressiondecisiontree/data-split.new.svg b/tests/testthat/_snaps/mlregressiondecisiontree/data-split.new.svg
new file mode 100644
index 00000000..b254084a
--- /dev/null
+++ b/tests/testthat/_snaps/mlregressiondecisiontree/data-split.new.svg
@@ -0,0 +1,44 @@
+
+
diff --git a/tests/testthat/_snaps/mlregressiondecisiontree/decision-tree-plot.new.svg b/tests/testthat/_snaps/mlregressiondecisiontree/decision-tree-plot.new.svg
new file mode 100644
index 00000000..ca57122f
--- /dev/null
+++ b/tests/testthat/_snaps/mlregressiondecisiontree/decision-tree-plot.new.svg
@@ -0,0 +1,162 @@
+
+
diff --git a/tests/testthat/_snaps/mlregressionknn/data-split.new.svg b/tests/testthat/_snaps/mlregressionknn/data-split.new.svg
new file mode 100644
index 00000000..689c5b50
--- /dev/null
+++ b/tests/testthat/_snaps/mlregressionknn/data-split.new.svg
@@ -0,0 +1,44 @@
+
+
diff --git a/tests/testthat/_snaps/mlregressionlinear/data-split.new.svg b/tests/testthat/_snaps/mlregressionlinear/data-split.new.svg
new file mode 100644
index 00000000..fa95a138
--- /dev/null
+++ b/tests/testthat/_snaps/mlregressionlinear/data-split.new.svg
@@ -0,0 +1,42 @@
+
+
diff --git a/tests/testthat/_snaps/mlregressionrandomforest/data-split.new.svg b/tests/testthat/_snaps/mlregressionrandomforest/data-split.new.svg
new file mode 100644
index 00000000..689c5b50
--- /dev/null
+++ b/tests/testthat/_snaps/mlregressionrandomforest/data-split.new.svg
@@ -0,0 +1,44 @@
+
+
diff --git a/tests/testthat/_snaps/mlregressionrandomforest/mean-decrease-in-accuracy.new.svg b/tests/testthat/_snaps/mlregressionrandomforest/mean-decrease-in-accuracy.new.svg
new file mode 100644
index 00000000..997ef645
--- /dev/null
+++ b/tests/testthat/_snaps/mlregressionrandomforest/mean-decrease-in-accuracy.new.svg
@@ -0,0 +1,81 @@
+
+
diff --git a/tests/testthat/_snaps/mlregressionrandomforest/total-increase-in-node-purity.new.svg b/tests/testthat/_snaps/mlregressionrandomforest/total-increase-in-node-purity.new.svg
new file mode 100644
index 00000000..f981e064
--- /dev/null
+++ b/tests/testthat/_snaps/mlregressionrandomforest/total-increase-in-node-purity.new.svg
@@ -0,0 +1,73 @@
+
+
diff --git a/tests/testthat/_snaps/mlregressionregularized/data-split.new.svg b/tests/testthat/_snaps/mlregressionregularized/data-split.new.svg
new file mode 100644
index 00000000..689c5b50
--- /dev/null
+++ b/tests/testthat/_snaps/mlregressionregularized/data-split.new.svg
@@ -0,0 +1,44 @@
+
+
diff --git a/tests/testthat/_snaps/mlregressionsvm/data-split.new.svg b/tests/testthat/_snaps/mlregressionsvm/data-split.new.svg
new file mode 100644
index 00000000..b254084a
--- /dev/null
+++ b/tests/testthat/_snaps/mlregressionsvm/data-split.new.svg
@@ -0,0 +1,44 @@
+
+