<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/interpretable-machine-learning-with-iml-and-mlr/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://mlr-org.github.io/interpretable-machine-learning-iml-and-mlr/"> mlr-org</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>Machine learning models repeatedly outperform interpretable, parametric models like the linear regression model.<br>
The gains in performance have a price: The models operate as black boxes which are not interpretable.</p>
<p>Fortunately, there are many methods that can make machine learning models interpretable.<br>
The R package <code>iml</code> provides tools for analysing any black box machine learning model:</p>
<p><span></span></p>
<ul>
<li>
<p>Feature importance: Which were the most important features?</p>
</li>
<li>
<p>Feature effects: How does a feature influence the prediction? (Partial dependence plots and individual conditional expectation curves)</p>
</li>
<li>
<p>Explanations for single predictions: How did the feature values of a single data point affect its prediction? (LIME and Shapley value)</p>
</li>
<li>
<p>Surrogate trees: Can we approximate the underlying black box model with a short decision tree?</p>
</li>
<li>
<p>The iml package works for any classification and regression machine learning model: random forests, linear models, neural networks, xgboost, etc.</p>
</li>
</ul>
<p>This blog post shows you how to use the <code>iml</code> package to analyse machine learning models.<br>
While the <code>mlr</code> package makes it super easy to train machine learning models, the <code>iml</code> package makes it easy to extract insights about the learned black box machine learning models.</p>
<p>If you want to learn more about the technical details of all the methods, read the <a rel="nofollow" href="https://christophm.github.io/interpretable-ml-book/agnostic.html" target="_blank">Interpretable Machine Learning book</a>.</p>
<p><img alt="Time for Interpretable Machine Learning" src="https://i0.wp.com/mlr-org.github.io/images/2018-04-30-interpretable-machine-learning-iml-and-mlr/iml-bear.jpg?w=456&ssl=1" data-recalc-dims="1"></p>
<p>Let’s explore the <code>iml</code>-toolbox for interpreting an <code>mlr</code> machine learning model with concrete examples!</p>
<h2>Data: Boston Housing</h2>
<p>We’ll use the <code>MASS::Boston</code> dataset to demonstrate the abilities of the iml package. This dataset contains median house values from Boston neighbourhoods.</p>
<figure>
<pre><code data-lang="r"><span>data</span><span>(</span><span>&quot;Boston&quot;</span><span>,</span><span> </span><span>package</span><span> </span><span>=</span><span> </span><span>&quot;MASS&quot;</span><span>)</span><span>
</span><span>head</span><span>(</span><span>Boston</span><span>)</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">#>      crim zn indus chas   nox    rm  age    dis rad tax ptratio
#> 1 0.00632 18  2.31    0 0.538 6.575 65.2 4.0900   1 296    15.3
#> 2 0.02731  0  7.07    0 0.469 6.421 78.9 4.9671   2 242    17.8
#> 3 0.02729  0  7.07    0 0.469 7.185 61.1 4.9671   2 242    17.8
#> 4 0.03237  0  2.18    0 0.458 6.998 45.8 6.0622   3 222    18.7
#> 5 0.06905  0  2.18    0 0.458 7.147 54.2 6.0622   3 222    18.7
#> 6 0.02985  0  2.18    0 0.458 6.430 58.7 6.0622   3 222    18.7
#>    black lstat medv
#> 1 396.90  4.98 24.0
#> 2 396.90  9.14 21.6
#> 3 392.83  4.03 34.7
#> 4 394.63  2.94 33.4
#> 5 396.90  5.33 36.2
#> 6 394.12  5.21 28.7</code></pre>
</figure>
<h2>Fitting the machine learning model</h2>
<p>First we train a randomForest to predict the Boston median housing value:</p>
<figure>
<pre><code data-lang="r"><span>library</span><span>(</span><span>&quot;mlr&quot;</span><span>)</span><span>
</span><span>data</span><span>(</span><span>&quot;Boston&quot;</span><span>,</span><span> </span><span>package</span><span> </span><span>=</span><span> </span><span>&quot;MASS&quot;</span><span>)</span><span>
</span><span># create an mlr task and model</span><span>
</span><span>tsk</span><span> </span><span>=</span><span> </span><span>makeRegrTask</span><span>(</span><span>data</span><span> </span><span>=</span><span> </span><span>Boston</span><span>,</span><span> </span><span>target</span><span> </span><span>=</span><span> </span><span>&quot;medv&quot;</span><span>)</span><span>
</span><span>lrn</span><span> </span><span>=</span><span> </span><span>makeLearner</span><span>(</span><span>&quot;regr.randomForest&quot;</span><span>,</span><span> </span><span>ntree</span><span> </span><span>=</span><span> </span><span>100</span><span>)</span><span>
</span><span>mod</span><span> </span><span>=</span><span> </span><span>train</span><span>(</span><span>lrn</span><span>,</span><span> </span><span>tsk</span><span>)</span></code></pre>
</figure>
<h2>Using the iml Predictor container</h2>
<p>We create a <code>Predictor</code> object, that holds the model and the data. The <code>iml</code> package uses R6 classes: New objects can be created by calling <code>Predictor$new()</code>.<br>
<code>Predictor</code> works best with mlr models (<code>WrappedModel</code>-class), but it is also possible to use models from other packages.</p>
<figure>
<pre><code data-lang="r"><span>library</span><span>(</span><span>&quot;iml&quot;</span><span>)</span><span>
</span><span>X</span><span> </span><span>=</span><span> </span><span>Boston</span><span>[</span><span>which</span><span>(</span><span>names</span><span>(</span><span>Boston</span><span>)</span><span> </span><span>!=</span><span> </span><span>&quot;medv&quot;</span><span>)]</span><span>
</span><span>predictor</span><span> </span><span>=</span><span> </span><span>Predictor</span><span>$</span><span>new</span><span>(</span><span>mod</span><span>,</span><span> </span><span>data</span><span> </span><span>=</span><span> </span><span>X</span><span>,</span><span> </span><span>y</span><span> </span><span>=</span><span> </span><span>Boston</span><span>$</span><span>medv</span><span>)</span></code></pre>
</figure>
<h2>Feature importance</h2>
<p>We can measure how important each feature was for the predictions with <code>FeatureImp</code>. The feature importance measure works by shuffling each feature and measuring how much the performance drops. For this regression task we choose to measure the loss in performance with the mean absolute error (‘mae’); another choice would be the mean squared error (‘mse’).</p>
<p>Once we created a new object of <code>FeatureImp</code>, the importance is automatically computed.<br>
We can call the <code>plot()</code> function of the object or look at the results in a data.frame.</p>
<figure>
<pre><code data-lang="r"><span>imp</span><span> </span><span>=</span><span> </span><span>FeatureImp</span><span>$</span><span>new</span><span>(</span><span>predictor</span><span>,</span><span> </span><span>loss</span><span> </span><span>=</span><span> </span><span>&quot;mae&quot;</span><span>)</span><span>
</span><span>plot</span><span>(</span><span>imp</span><span>)</span></code></pre>
</figure>
<p><img alt="plot of chunk unnamed-chunk-5" src="https://mlr-org.github.io/figures/2018-04-30-interpretable-machine-learning-iml-and-mlr/unnamed-chunk-5-1.svg"></p>
<figure>
<pre><code data-lang="r"><span>imp</span><span>$</span><span>results</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">#>    feature original.error permutation.error importance
#> 1    lstat       0.929379         4.3533565   4.684156
#> 2       rm       0.929379         3.0678264   3.300942
#> 3      nox       0.929379         1.6636358   1.790051
#> 4      dis       0.929379         1.6288497   1.752622
#> 5     crim       0.929379         1.6115494   1.734007
#> 6  ptratio       0.929379         1.5988103   1.720300
#> 7    indus       0.929379         1.4023210   1.508880
#> 8      tax       0.929379         1.3150335   1.414959
#> 9      age       0.929379         1.2712218   1.367819
#> 10   black       0.929379         1.1936640   1.284367
#> 11     rad       0.929379         1.0826712   1.164941
#> 12    chas       0.929379         0.9753240   1.049436
#> 13      zn       0.929379         0.9585688   1.031408</code></pre>
</figure>
<h2>Partial dependence</h2>
<p>Besides learning which features were important, we are interested in how the features influence the predicted outcome. The <code>Partial</code> class implements partial dependence plots and individual conditional expectation curves. Each individual line represents the predictions (y-axis) for one data point when we change one of the features (e.g. ‘lstat’ on the x-axis). The highlighted line is the point-wise average of the individual lines and equals the partial dependence plot. The marks on the x-axis indicates the distribution of the ‘lstat’ feature, showing how relevant a region is for interpretation (little or no points mean that we should not over-interpret this region).</p>
<figure>
<pre><code data-lang="r"><span>pdp.obj</span><span> </span><span>=</span><span> </span><span>Partial</span><span>$</span><span>new</span><span>(</span><span>predictor</span><span>,</span><span> </span><span>feature</span><span> </span><span>=</span><span> </span><span>&quot;lstat&quot;</span><span>)</span><span>
</span><span>plot</span><span>(</span><span>pdp.obj</span><span>)</span></code></pre>
</figure>
<p><img alt="plot of chunk unnamed-chunk-6" src="https://mlr-org.github.io/figures/2018-04-30-interpretable-machine-learning-iml-and-mlr/unnamed-chunk-6-1.svg"></p>
<p>If we want to compute the partial dependence curves for another feature, we can simply reset the feature.<br>
Also, we can center the curves at a feature value of our choice, which makes it easier to see the trend of the curves:</p>
<figure>
<pre><code data-lang="r"><span>pdp.obj</span><span>$</span><span>set.feature</span><span>(</span><span>&quot;rm&quot;</span><span>)</span><span>
</span><span>pdp.obj</span><span>$</span><span>center</span><span>(</span><span>min</span><span>(</span><span>Boston</span><span>$</span><span>rm</span><span>))</span><span>
</span><span>plot</span><span>(</span><span>pdp.obj</span><span>)</span></code></pre>
</figure>
<p><img alt="plot of chunk unnamed-chunk-7" src="https://mlr-org.github.io/figures/2018-04-30-interpretable-machine-learning-iml-and-mlr/unnamed-chunk-7-1.svg"></p>
<h2>Surrogate model</h2>
<p>Another way to make the models more interpretable is to replace the black box with a simpler model – a decision tree. We take the predictions of the black box model (in our case the random forest) and train a decision tree on the original features and the predicted outcome.<br>
The plot shows the terminal nodes of the fitted tree.<br>
The maxdepth parameter controls how deep the tree can grow and therefore how interpretable it is.</p>
<figure>
<pre><code data-lang="r"><span>tree</span><span> </span><span>=</span><span> </span><span>TreeSurrogate</span><span>$</span><span>new</span><span>(</span><span>predictor</span><span>,</span><span> </span><span>maxdepth</span><span> </span><span>=</span><span> </span><span>2</span><span>)</span><span>
</span><span>plot</span><span>(</span><span>tree</span><span>)</span></code></pre>
</figure>
<p><img alt="plot of chunk unnamed-chunk-8" src="https://mlr-org.github.io/figures/2018-04-30-interpretable-machine-learning-iml-and-mlr/unnamed-chunk-8-1.svg"></p>
<p>We can use the tree to make predictions:</p>
<figure>
<pre><code data-lang="r"><span>head</span><span>(</span><span>tree</span><span>$</span><span>predict</span><span>(</span><span>Boston</span><span>))</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">#>     .y.hat
#> 1 28.43299
#> 2 21.74169
#> 3 28.43299
#> 4 28.43299
#> 5 28.43299
#> 6 28.43299</code></pre>
</figure>
<h2>Explain single predictions with a local model</h2>
<p>Global surrogate model can improve the understanding of the global model behaviour.<br>
We can also fit a model locally to understand an individual prediction better. The local model fitted by <code>LocalModel</code> is a linear regression model and the data points are weighted by how close they are to the data point for wich we want to explain the prediction.</p>
<figure>
<pre><code data-lang="r"><span>lime.explain</span><span> </span><span>=</span><span> </span><span>LocalModel</span><span>$</span><span>new</span><span>(</span><span>predictor</span><span>,</span><span> </span><span>x.interest</span><span> </span><span>=</span><span> </span><span>X</span><span>[</span><span>1</span><span>,])</span><span>
</span><span>lime.explain</span><span>$</span><span>results</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">#>               beta x.recoded    effect x.original feature
#> rm       4.3190928     6.575 28.398035      6.575      rm
#> ptratio -0.5285876    15.300 -8.087391       15.3 ptratio
#> lstat   -0.4273493     4.980 -2.128199       4.98   lstat
#>         feature.value
#> rm           rm=6.575
#> ptratio  ptratio=15.3
#> lstat      lstat=4.98</code></pre>
</figure>
<figure>
<pre><code data-lang="r"><span>plot</span><span>(</span><span>lime.explain</span><span>)</span></code></pre>
</figure>
<p><img alt="plot of chunk unnamed-chunk-10" src="https://mlr-org.github.io/figures/2018-04-30-interpretable-machine-learning-iml-and-mlr/unnamed-chunk-10-1.svg"></p>
<h2>Explain single predictions with game theory</h2>
<p>An alternative for explaining individual predictions is a method from coalitional game theory named Shapley value.<br>
Assume that for one data point, the feature values play a game together, in which they get the prediction as a payout. The Shapley value tells us how to fairly distribute the payout among the feature values.</p>
<figure>
<pre><code data-lang="r"><span>shapley</span><span> </span><span>=</span><span> </span><span>Shapley</span><span>$</span><span>new</span><span>(</span><span>predictor</span><span>,</span><span> </span><span>x.interest</span><span> </span><span>=</span><span> </span><span>X</span><span>[</span><span>1</span><span>,])</span><span>
</span><span>plot</span><span>(</span><span>shapley</span><span>)</span></code></pre>
</figure>
<p><img alt="plot of chunk unnamed-chunk-11" src="https://mlr-org.github.io/figures/2018-04-30-interpretable-machine-learning-iml-and-mlr/unnamed-chunk-11-1.svg"></p>
<p>We can reuse the object to explain other data points:</p>
<figure>
<pre><code data-lang="r"><span>shapley</span><span>$</span><span>explain</span><span>(</span><span>x.interest</span><span> </span><span>=</span><span> </span><span>X</span><span>[</span><span>2</span><span>,])</span><span>
</span><span>plot</span><span>(</span><span>shapley</span><span>)</span></code></pre>
</figure>
<p><img alt="plot of chunk unnamed-chunk-12" src="https://mlr-org.github.io/figures/2018-04-30-interpretable-machine-learning-iml-and-mlr/unnamed-chunk-12-1.svg"></p>
<p>The results in data.frame form can be extracted like this:</p>
<figure>
<pre><code data-lang="r"><span>results</span><span> </span><span>=</span><span> </span><span>shapley</span><span>$</span><span>results</span><span>
</span><span>head</span><span>(</span><span>results</span><span>)</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">#>   feature         phi      phi.var feature.value
#> 1    crim -0.02168342  1.071941296  crim=0.02731
#> 2      zn -0.00016250  0.006865947          zn=0
#> 3   indus -0.27755494  0.492201863    indus=7.07
#> 4    chas -0.01886100  0.016614559        chas=0
#> 5     nox  0.33932047  0.925398396     nox=0.469
#> 6      rm -1.19031582 13.544574195      rm=6.421</code></pre>
</figure>
<p>The <code>iml</code> package is available on <a rel="nofollow" href="https://cran.r-project.org/web/packages/iml/index.html" target="_blank">CRAN</a> and on <a rel="nofollow" href="https://github.com/christophM/iml" target="_blank">Github</a>.</p>
	<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://mlr-org.github.io/interpretable-machine-learning-iml-and-mlr/"> mlr-org</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a rel="nofollow" href="https://www.r-project.org/" title="The R Project for Statistical Computing">R</a> news and <a rel="nofollow" href="https://www.r-bloggers.com/search/tutorial" title="R tutorials">tutorials</a> on topics such as: <a rel="nofollow" href="https://www.r-bloggers.com/search/data%20science" title="Data science">Data science</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data" title="Big Data">Big Data, <a rel="nofollow" href="https://www.r-users.com/" title="R jobs">R jobs</a>, visualization (<a rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2" title="ggplot and ggplot2 tutorials">ggplot2</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/boxplot" title="Boxplots using lattice and ggplot2 tutorials">Boxplots</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/map" title="Maps and gis">maps</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/animation" title="Animation in R">animation</a>), programming (<a rel="nofollow" href="https://www.r-bloggers.com/search/RStudio" title="RStudio IDE for R">RStudio</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/sweave" title="Sweave and literate programming">Sweave</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX" title="LaTeX in R">LaTeX</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/SQL" title="SQL and databases">SQL</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/eclipse" title="Eclipse IDE for R">Eclipse</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/git" title="git and github, Version Control System">git</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/hadoop" title="Large data in R using Hadoop">hadoop</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping" title="Web Scraping of google, facebook, yahoo, twitter and more using R">Web Scraping</a>) statistics (<a rel="nofollow" href="https://www.r-bloggers.com/search/regression" title="Regressions and ANOVA analysis tutorials">regression</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/PCA" title="principal component analysis tutorial">PCA</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/time+series" title="Time series">time series</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/trading" title="finance trading">trading</a>) and more...
<img width="1" alt="" src="http://feeds.feedburner.com/~r/RBloggers/~4/mABxYb8LCLg" height="1"></a></div>