# Random forest: which features led to a certain prediction?

I have trained a random forest classifier using the sklearn Python package, and used it to classify a datapoint with a certain feature vector.

Let's assume that the random forest has only one tree, that this is a binary classification task, and the data point has been labeled as class '0', while I was expecting it to be '1'. How can I check which features were responsible for such classification? Is there a way to get the list of split-thresholds for each feature?

How can this be generalised to the multiclass case, with multiple trees?

• A question like "Is there a way to get the list of split-thresholds for each feature?" is not about the algorithm itself, but about the implementation of the algorithm in a particular language of software. You don't specify what tools you are using, so it is impossible to answer. – Matthew Drury Jul 28 '17 at 15:43
• Also, random forest does not assign hard classes for predictions, it assigns probabilities. The hard class assignment comes about because you threshold the probabilities at some level, how did you choose this level? – Matthew Drury Jul 28 '17 at 15:45
• "You don't specify what tools you are using" As written, I am using Python package sklearn, specifically: scikit-learn.org/stable/modules/generated/… Which by the way returns the hard class prediction. – User User Jul 28 '17 at 17:00
• Sorry about that, I'm conditioned to look at the tags to see what tools the asker is using. My apologies. – Matthew Drury Jul 28 '17 at 17:04
• sklearn only returns hard classification if you use the predict method instead of predict_proba. The first method calls the second and then compares to 0.5. This is my largest issue with sklearn, this is just almost always the wrong thing to do, and the predict methods should be removed IMO. In any case, if you read the documentation of random forest in sklearn, you will see that it computes predictions as the average over the trees average lables in the leaf nodes of the individual trees. – Matthew Drury Jul 28 '17 at 17:06

In the canonical implementation of random forest (R's randomForest package), there is a way to produce a local importance matrix that tells you which feature(s) have contributed to the model's prediction.

library(randomForest)
set.seed(71)
iris.rf <- randomForest(Species ~ ., data=iris, importance=TRUE,
localImp=TRUE,
proximity=TRUE)

locImp = iris.rf\$localImportance
dim(locImp)
[1]   4 150


The rows of locImp are the features, columns the observations. So locImp[,1] gives,

Sepal.Length  Sepal.Width Petal.Length  Petal.Width
0.02564103   0.01025641   0.32307692   0.37435897


That says Petal.Width has the most weight in predicting setosa on the first observation.

There are several ways of interpreting random forest predictions. ELI5 package (http://eli5.readthedocs.io/en/latest/overview.html) implements a number of those. The most relevant ones for random forests would be TreeInterpreter (http://blog.datadive.net/interpreting-random-forests/) and LIME (https://arxiv.org/abs/1602.04938)

Those will not give you split thresholds, but they will tell you which features were most important for classifying a particular example. These should be taken with a grain of salt, as the results can be counter-intuitive in some cases (e.g. if you use a decision tree to learn the XOR function).

For a single tree I guess you can just plot the output tree of the trained model and can visualize which decision node is giving that output of zero instead of 1. Visualisation would be difficult with multiple trees.