Skip to content

Find and read SHAP explanations

When you need it

Use SHAP to inspect which transformed features influenced a fitted model's output. It explains model behavior; it is not a quality gate or proof that a feature causes an outcome. Evaluation charts answer a different question: how well predictions match known outcomes.

Quick setup leaves SHAP off and does not ask the SHAP questions. If you cannot find a shap_* task, first check how the project was generated. Detailed setup asks shap_enabled, default false.

flowchart LR
    A["Enable explainability and dependencies"] --> B["Fit the model"]
    B --> C["Apply saved preprocessing with required history"]
    C --> D["Compute bounded SHAP values"]
    D --> E["MLflow: explanations.json and explanations.html"]
    E --> F["shap_model or shap_name: display saved report"]

shap_name stands for each concrete shap_<name> task of a competition or model set. The SHAP leaf displays an existing report. Computation happens during fit; opening the leaf does not retrain or explain new score requests.

What to edit

For a new project, choose detailed setup, enable shap_enabled and set its three budgets. This adds the config, dependencies and matching report tasks. For an existing project, complete all three changes below.

Enable computation and dependencies

Merge this fragment into config/training.yml:

defaults:
  explainability:
    method: shap
    max_samples: 100
    max_features: 30
    max_display_samples: 3

These settings apply to each single model, competition candidate or model-set branch. A named model's explainability mapping replaces the shared mapping; include every override you need. Omit the field or set it to null to disable computation. The example uses the generated defaults. The direct Core config defaults to 10 display samples, capped by max_samples, if that key is absent.

Keep these exact template dependencies in deployment/train-requirements.txt:

shap==0.49.1
matplotlib==3.10.0

The generated training environment installs that file on serverless and policy clusters. Scoring does not compute SHAP and does not need these packages for that purpose. A local installation alone does not update deployed job libraries.

Add the report leaf if it was omitted

Projects generated with SHAP off omit src/jobs/shap_report.py and the SHAP tasks. Generate a separate project with the same layout and SHAP enabled, then review and copy the missing notebook, training requirements and relevant task fragment as described in project upgrades.

For a single-model project, the task fragment under the existing train job's tasks is:

- <<: *lifecycle_task
  task_key: shap_model
  depends_on:
    - task_key: train_and_tune
  notebook_task:
    notebook_path: ../src/jobs/shap_report.py
    base_parameters:
      <<: *lifecycle_parameters
      reference_json: '{{tasks.train_and_tune.values.reference_json}}'
      tracking_uri: '{{tasks.initialize_run.values.tracking_uri}}'

This is a fragment for a generated graph: its two YAML anchors already exist there. For competition/model-set branches, use shap_<name>, depend on train_<name> and reference that exact task's reference_json. Keep the SHAP task as an independent leaf with no outgoing dependencies. refresh_training_graph.py can replicate an existing SHAP leaf when branches change; it does not invent a leaf if the graph has none.

Budget Allowed value Effect
max_samples 1–200; generated default 100 Maximum training rows used for SHAP computation. Larger values can be expensive, especially for generic explainers.
max_features Positive integer; default 30; no fixed upper bound Guard on transformed input width. It does not select the top features or drop columns; exceeding your configured value produces unavailable.
max_display_samples 0–50, no greater than max_samples; generated default 3 Number of saved sample waterfalls. Zero keeps global importance without sample waterfalls.

Budgets apply per fitted model: eight candidates can each compute an explanation. Samples are training inputs transformed with saved preprocessing; holdout labels, record keys and time/target metadata are not explanation features.

Set defaults.explainability.max_features in config/training.yml to cover the features produced by preprocessing. For example, four numeric inputs plus 111 one-hot columns produce 115 model features, so max_features: 115 admits that model. A value such as 200 leaves room for a wider fitted model. The setting controls the allowed width, not the number of features displayed in a chart. Higher values can increase SHAP computation time and memory use; use max_samples to choose how many training rows to explain.

Row-independent steps can preprocess only the sampled rows. Steps that need other rows, such as LagFeatures or RollingAggregate, first preprocess the complete training population supplied by the training job, then select the SHAP sample. For example, a sampled May record keeps April's lag even when April is not selected for explanation. An undeclared context also takes this conservative path. The job's training row/byte limits still bound that population; max_samples bounds SHAP computation, not context preprocessing. When more rows were preprocessed than the SHAP limit, preprocessing_rows records their count.

For models with fitted exclusion steps, such as IQR or PowerTransformer, SHAP uses only sampled rows accepted by those saved steps. The report records sampled_rows, explained_rows, excluded_rows and excluded_by_reason; sample_count is the accepted count. For example, 100 sampled rows with 11 IQR exclusions produce explanations for 89 rows and an outlier:<step> count of 11. The HTML shows these counts too. At least two rows must survive; otherwise the result is unavailable with reason too_few_rows_after_exclusions. The sample is not topped up. This describes the fitted preprocessing population, not custom scoring eligibility or business outputs. Models without exclusion steps retain their existing evidence fields.

The command

From the generated project root, after merging all required files:

uv pip install -r deployment/train-requirements.txt
python src/tools/smoke.py
python src/tools/preview.py --action train
databricks bundle validate --strict -t test --profile YOUR_PROFILE
databricks bundle deploy -t test --profile YOUR_PROFILE
databricks bundle run train -t test --profile YOUR_PROFILE

Use your target/profile. Smoke and preview check declarations, not SHAP computation. New settings affect a new fitting run; old runs are not backfilled.

What you should see

Start with Workflows > Jobs > your train run > training_report > Output > Where to look for the saved per-model report links and statuses. For the full explanation, open:

Layout Notebook output MLflow artifacts
Single model shap_model > Output Fitting run > Artifacts > explanations.json and explanations.html
Competition Each shap_<name> > Output Each candidate's fitting run; the selected winner's report is also copied to the parent with its child-run provenance
Model set Each shap_<name> > Output That branch's fitting run, not one explanation of the combined business output

The portable HTML contains embedded PNG images, run/model identity and a workspace-relative MLflow link. It needs no JavaScript or CDN; a downloaded copy's relative link needs the original workspace to navigate back to the run. It may contain transformed sample feature values, so use the experiment's existing access and retention controls.

Read mean absolute importance as average contribution magnitude on the sample: a taller bar means more influence, not a positive or negative effect. Read a waterfall from its base value through the feature contributions to the explained output. Red contributions increase it; blue contributions decrease it. The units belong to the explainer: a classifier can show raw scores/log-odds rather than probability percentage points. Do not compare unrelated models' bars without matching output units and sample populations.

Binary sample plots use class index 1. For multiclass explanations the helper uses the predicted class when available (otherwise class 0); global magnitude averages absolute contributions over classes. A sample number is a position in the report, not a business key. Correlated features and training-population choices affect attribution; SHAP is not causal evidence.

Common errors and fixes

Symptom or saved reason What it means and what to do
No shap_* task Quick/default setup omitted it. Add config, pinned dependencies, notebook and task, then validate/deploy; the YAML flag alone cannot create a task.
No explanation artifact Check whether explainability was off in the fitting run, or whether fit failed before saving it. Absence alone is not a successful explanation.
feature_limit_exceeded Transformed width exceeds the guard. Inspect encoded/generated columns; raise the guard only within 100, or train a deliberately smaller feature set.
empty_training_frame, missing_input_columns No usable training sample or missing saved input columns. Repair the source/split/feature contract before retraining.
too_few_rows_after_exclusions Fewer than two sampled rows survived the fitted exclusion steps. Read the counts and reasons; check the data and fitted thresholds before changing the sample budget.
inference_transform_unavailable, row_count_changed, feature_schema_mismatch Saved preprocessing cannot produce the expected row-preserving feature frame. Inspect the transform and context requirements.
model_unavailable, shap_unavailable No usable estimator/explainer result. Check training logs, model compatibility and installed dependencies; a supported training model need not be supported by the selected SHAP explainer.
shap_feature_schema_mismatch, invalid_shap_result Returned SHAP columns or finite JSON values do not match the saved contract. Keep the failure evidence and investigate the estimator/dependency combination.
report_status: unavailable Numerical evidence may exist while rendering failed. Inspect report_reason, the JSON artifact and plotting dependencies.
SHAP leaf fails after fitting The independent leaf can fail the overall job without undoing a model decision or retraining. Inspect saved artifacts before retrying; do not repair a lifecycle invocation merely to regenerate a chart.

status: completed means SHAP values were saved, not that the model is accurate or suitable for promotion. Unavailable explanations preserve their reason and do not replace the saved evaluation metrics or quality policy.