Skip to main content

Stable feature importance explanations under collinearity — works with any model and attribution method

Project description

DASH: Diversified Aggregation of SHAP

PyPI ArXiv Python License: MIT

Stable feature importance when your features are correlated. SHAP rankings from a single model are partially random under collinearity — DASH fixes this by averaging explanations across independent models so the noise cancels and the signal remains. Works with any attribution method.

Install

pip install dash-shap

Quick Check — Is Your Model Affected?

from dash_shap import check
from sklearn.datasets import load_breast_cancer

data = load_breast_cancer()
result = check(data.data, data.target, task="binary",
               feature_names=list(data.feature_names))
print(result.report())
DASH Stability Check
========================================
Models trained: 25
Features: 30
Unstable pairs: 68
Correlated groups: 5

UNSTABLE PAIRS (rankings flip across retrains):
  worst radius vs worst perimeter: flip rate 48%, predicted 47%
  mean radius vs mean perimeter: flip rate 44%, predicted 43%
  ...

RECOMMENDATION: Use M=150 models for 5% flip rate target

TOP FEATURES (DASH consensus):
  1. worst concave points: 0.0831 (stable)
  2. worst perimeter: 0.0534 (UNSTABLE)
  3. worst radius: 0.0521 (UNSTABLE)
  ...

result.plot() shows the Importance-Stability plot. result.dash_importance() returns stable consensus rankings. result.to_dataframe() gives a full summary with SNR predictions.

Full Pipeline

For production use with diversity selection and full diagnostics:

from dash_shap import DASHPipeline
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split

X, y = load_breast_cancer(return_X_y=True)
X_temp, X_test, y_temp, y_test = train_test_split(X, y, test_size=0.15, random_state=42)
X_temp, X_ref, y_temp, _ = train_test_split(X_temp, y_temp, test_size=0.12, random_state=42)
X_train, X_val, y_train, y_val = train_test_split(X_temp, y_temp, test_size=0.18, random_state=42)

pipe = DASHPipeline(M=100, K=20, epsilon=0.05, epsilon_mode="relative",
                    task="binary", seed=42)
pipe.fit(X_train, y_train, X_val, y_val, X_ref=X_ref)

# Stable consensus importance
print(pipe.global_importance_)

# Importance-Stability plot: which features are stable vs. collinear?
pipe.plot_importance_stability()

# Feature Stability Index: per-feature stability scores
pipe.get_fsi().summary(top_k=10)

The IS plot places features in four quadrants:

Quadrant Importance Stability Action
I: Robust Drivers High Stable Report individually
II: Collinear Cluster High Unstable Report as a group
III: Unimportant Low Stable Safe to omit
IV: Fragile Low Unstable Investigate or drop

Using with Any Attribution Method

The default pipeline uses XGBoost + TreeSHAP, but DASH works with any attribution source — LIME, Integrated Gradients, attention maps, KernelSHAP, or custom methods:

# You have M attribution vectors from any source, shape (M, P)
# e.g., LIME importance from M independently trained neural networks
pipe = DASHPipeline(M=100, K=20, epsilon=0.05)
pipe.fit_from_attributions(attribution_matrices, val_scores)
print(pipe.global_importance_)

# Or use the lightweight stability workflow directly
from dash_shap import validate_from_attributions, consensus_from_attributions

results = validate_from_attributions(attribution_matrix)  # Z-tests + flip rates
stable = consensus_from_attributions(attribution_matrix)   # averaged importance

The underlying impossibility theorem is proved for all iterative optimizers (gradient boosting, Lasso, neural networks), so the resolution — independent model averaging — is equally general.

Extensions

After fitting, pipe.result_ is a DASHResult that supports additional analyses:

from dash_shap.extensions import (
    confidence_intervals, robust_certification, theory_bridge,
    causal_flags, audit_report, DriftMonitor, federated_consensus,
)

# Bootstrap confidence intervals on importance and FSI
ci = confidence_intervals(pipe.result_)
print(ci.summary())

# Certify which features are top-k across ALL models (worst-case guarantee)
cert = robust_certification(pipe.result_)
print(cert.certified[5])  # features certified top-5

# Theory bridge: predict flip rates from impossibility theorem formulas
tb = theory_bridge(pipe.result_)
print(tb.summary())       # SNR per pair, predicted flip rates, M recommendation

# Label each feature: robust / collinear / fragile / unimportant
flags = causal_flags(pipe.result_, X_ref=X_ref)
print(flags.summary())

# Structured audit report with warnings for stakeholders
report = audit_report(pipe.result_, X_ref=X_ref, causal=flags)
print(report.summary())

# Monitor explanation drift between model versions
monitor = DriftMonitor(pipe.result_, threshold=0.1)
alert = monitor.check(new_result, label="v2")
if alert.drifted:
    print(f"Drift: {alert.distance:.3f}, changed: {alert.changed_features}")

# Combine results from multiple sites without sharing data
fed = federated_consensus([result_site1, result_site2])
print(f"Cross-site agreement: {fed.cross_site_agreement:.3f}")

All 12 extensions: confidence_intervals, partial_order, feature_groups, stable_feature_selection, local_uncertainty, robust_certification, theory_bridge, causal_flags, audit_report, DriftMonitor, ParetoSelector, federated_consensus.

How It Works

DASH is a five-stage pipeline:

  1. Population — Train M independent models with random hyperparameters and restricted feature access, so each model explores different features
  2. Filtering — Keep models within ε of the best validation score
  3. Diversity Selection — Greedy MaxMin selection maximizing pairwise distance among importance vectors
  4. Consensus — Compute attributions for each selected model, then average
  5. Diagnostics — Feature Stability Index (FSI) and IS plots for auditing without ground truth

The key insight: model independence — not model size — is what cancels the arbitrary noise. See the paper for the full mechanism analysis.

Documentation

Resource Description
API Reference Complete parameter and method documentation
Extensions Guide All 12 extensions with worked examples, organized by use case
FAQ Usage, troubleshooting, parameter guidance
Diagnostics Guide IS plots, FSI thresholds, disagreement maps
Getting Started Concept-first introduction with worked examples
Research & Benchmarks Full results, method comparisons, reproduction guide
Tutorials Step-by-step notebooks from basic to advanced

Citation

@misc{caraker2026firstmover,
  title={First-Mover Bias in Gradient Boosting Explanations: Mechanism, Detection, and Resolution},
  author={Caraker, Drake and Arnold, Bryan and Rhoads, David},
  year={2026},
  eprint={2603.22346},
  archiveprefix={arXiv},
  primaryclass={cs.LG},
  doi={10.5281/zenodo.19060132},
  url={https://arxiv.org/abs/2603.22346}
}

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dash_shap-0.2.0.tar.gz (109.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dash_shap-0.2.0-py3-none-any.whl (108.2 kB view details)

Uploaded Python 3

File details

Details for the file dash_shap-0.2.0.tar.gz.

File metadata

  • Download URL: dash_shap-0.2.0.tar.gz
  • Upload date:
  • Size: 109.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for dash_shap-0.2.0.tar.gz
Algorithm Hash digest
SHA256 c2e6292cc15af04d99a73aeb7cf2372460b15357c8c363b3a474ead0ad0d24b9
MD5 37de0b31b49f4de3e836b0c99d74534a
BLAKE2b-256 336def8d0b772cf762d7ac4a5159caa81ca9c2164055a794ead9d9d984c76db2

See more details on using hashes here.

File details

Details for the file dash_shap-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: dash_shap-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 108.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for dash_shap-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d65b9c5cc7f10081f12f7311d4f84c5d2a1758e09a0e68f5211b9d58713af19c
MD5 112d4b67dabf490e1ac1eb15769d1a48
BLAKE2b-256 bb6e91c465474e247f38542a81bd1c5bf0b75a928f972bfbaac6f74d87cbdb81

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page