---
title: "iBreakDown plots for regression models"
author: "Dariusz Komosinski"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{iBreakDown plots for regression models}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  comment = "#>",
  warning = FALSE,
  fig.width = 6, fig.height = 6,
  message = FALSE
)
```

Here we will use the `dragons` data from [`DALEX`](https://github.com/pbiecek/DALEX) package to present the `iBreakDown` for regression models.

```{r}
# devtools::install_github("pbiecek/DALEX")
library(DALEX)
library(iBreakDown)

head(dragons)
new_observation <- dragons_test[1,]
new_observation
```

## Linear regression

First, we fit a model.

```{r}
m_lm <- lm(life_length ~ . , data = dragons)
```

To understand the factors that drive predictions for a single observation we use the `iBreakDown` package.

Now, we create an object of the `break_down` class. If we want to plot distributions of partial predictions, set `keep_distributions = TRUE`.

```{r}
bd_lm <- local_attributions(m_lm,
                            data = dragons_test,
                            new_observation =  new_observation,
                            keep_distributions = TRUE)
```

We can simply print the result.

```{r}
bd_lm
```

Or plot the result which is more clear.

```{r}
plot(bd_lm)
```

Use the `baseline` parameter to set the origin of plots.

```{r}
plot(bd_lm, baseline = 0)
```

Use the `plot_distributions` parameter to see distributions of partial predictions.

```{r}
plot(bd_lm, plot_distributions = TRUE)
```

For another types of models we proceed analogously. However, sometimes we need to create custom predict function (see `nnet` example).

## randomForest

```{r}
library(randomForest)

m_rf <- randomForest(life_length ~ . , data = dragons)

bd_rf <- local_attributions(m_rf,
                            data = dragons_test,
                            new_observation =  new_observation)

head(bd_rf)
plot(bd_rf)
```

## SVM

```{r}
library(e1071)

m_svm <- svm(life_length ~ . , data = dragons)

bd_svm <- local_attributions(m_svm,
                            data = dragons_test,
                            new_observation =  new_observation)

plot(bd_svm)
```

## knn

```{r}
library(caret)

m_knn <- knnreg(life_length ~ . , data = dragons)

bd_knn <- local_attributions(m_knn,
                            data = dragons_test,
                            new_observation =  new_observation)

plot(bd_knn)
```

## nnet

When you use `nnet` package for regression, remember to normalize the resposne variable, in such a way that it is from interval $(0,1)$.

In this case, creating custom predict function is also needed.

```{r}
library(nnet)

x <- max(abs(dragons$life_length))
digits <- floor(log10(x))
normalizing_factor <- round(x, -digits)
m_nnet <- nnet(life_length/normalizing_factor ~ . , data = dragons, size = 10, linout = TRUE)

p_fun <- function(model, new_observation){
  predict(model, newdata = new_observation)*normalizing_factor
}

bd_nnet <- local_attributions(m_nnet,
                            data = dragons_test,
                            new_observation =  new_observation,
                            predict_function = p_fun)

plot(bd_nnet)
```

