Model Explainability: Feature Importance, Partial Dependence, and SHAP
"Why did the model say that?" is actually three different questions in disguise — and each one needs a different tool.
Advanced
| Question | Tool |
|---|---|
| Which features did the model rely on most, overall? | Feature importance |
| How does one specific feature affect predictions, across its whole range? | Partial dependence plots |
| For this one prediction, right here, how much did each feature contribute? | SHAP values |
model.feature_importances_, built into tree-based models
from how much each feature reduced impurity across all their splits.
Permutation importance answers the same question a different, more general
way, and works for any model, not just trees:
1. take the trained model and the validation set (never the training set)
2. record its baseline performance (accuracy, F1, whatever metric matters)
3. for each feature, one at a time:
a. randomly shuffle just that column's values across the validation rows
(everything else, including the target, stays in place)
b. re-score the model on this corrupted data
c. importance = how much performance dropped from the baseline
4. repeat the shuffles a few times per feature and average, to smooth out randomness
touches_slow_suite destroys any real relationship between that
column and the actual outcome, without touching the model itself — if the model leaned on it
heavily, performance craters; if it barely mattered, performance barely moves. Occasionally a
feature shows a slightly negative importance — the shuffled version scored better by
chance — which just means that feature's true importance was close to zero and the difference
is noise, more common on small validation sets where there's more room for a lucky shuffle.
lines_changed matters a lot; it says nothing about
the shape of that relationship. A partial dependence plot (PDP) fills
that in: hold every other feature fixed, sweep lines_changed across its full
range of observed values, and at each value, ask the model for its predicted failure
probability. Repeat across many rows and average, then plot predicted probability against
lines_changed.
lines_changed and hour_of_day together —
to surface interaction effects that neither feature's individual PDP would show.
sum(SHAP value for every feature) = prediction_for_this_run - baseline_prediction
touches_slow_suite, +0.20 to an
unusually large lines_changed, and -0.05 to a normally low-risk
hour_of_day — numbers that add up exactly to the gap between this run's 85%
prediction and the baseline. That's a genuinely different, more actionable answer than "this
feature matters on average" — it's "this feature is why this prediction, specifically,
came out the way it did," the same kind of per-decision accountability a bank needs to explain
a loan rejection or a healthcare model needs to justify a risk score.
feature_importances_ this page's permutation-importance section builds on and
generalizes beyond.