explainiverse 0.3.0__tar.gz → 0.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. explainiverse-0.5.0/PKG-INFO +617 -0
  2. explainiverse-0.5.0/README.md +585 -0
  3. {explainiverse-0.3.0 → explainiverse-0.5.0}/pyproject.toml +1 -1
  4. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/__init__.py +1 -1
  5. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/core/registry.py +40 -0
  6. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/explainers/__init__.py +8 -0
  7. explainiverse-0.5.0/src/explainiverse/explainers/example_based/__init__.py +18 -0
  8. explainiverse-0.5.0/src/explainiverse/explainers/example_based/protodash.py +826 -0
  9. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/explainers/gradient/__init__.py +2 -0
  10. explainiverse-0.5.0/src/explainiverse/explainers/gradient/smoothgrad.py +424 -0
  11. explainiverse-0.3.0/PKG-INFO +0 -391
  12. explainiverse-0.3.0/README.md +0 -359
  13. {explainiverse-0.3.0 → explainiverse-0.5.0}/LICENSE +0 -0
  14. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/adapters/__init__.py +0 -0
  15. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/adapters/base_adapter.py +0 -0
  16. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/adapters/pytorch_adapter.py +0 -0
  17. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/adapters/sklearn_adapter.py +0 -0
  18. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/core/__init__.py +0 -0
  19. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/core/explainer.py +0 -0
  20. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/core/explanation.py +0 -0
  21. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/engine/__init__.py +0 -0
  22. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/engine/suite.py +0 -0
  23. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/evaluation/__init__.py +0 -0
  24. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/evaluation/_utils.py +0 -0
  25. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/evaluation/faithfulness.py +0 -0
  26. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/evaluation/metrics.py +0 -0
  27. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/evaluation/stability.py +0 -0
  28. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/explainers/attribution/__init__.py +0 -0
  29. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/explainers/attribution/lime_wrapper.py +0 -0
  30. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/explainers/attribution/shap_wrapper.py +0 -0
  31. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/explainers/attribution/treeshap_wrapper.py +0 -0
  32. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/explainers/counterfactual/__init__.py +0 -0
  33. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/explainers/counterfactual/dice_wrapper.py +0 -0
  34. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/explainers/global_explainers/__init__.py +0 -0
  35. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/explainers/global_explainers/ale.py +0 -0
  36. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/explainers/global_explainers/partial_dependence.py +0 -0
  37. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/explainers/global_explainers/permutation_importance.py +0 -0
  38. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/explainers/global_explainers/sage.py +0 -0
  39. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/explainers/gradient/deeplift.py +0 -0
  40. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/explainers/gradient/gradcam.py +0 -0
  41. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/explainers/gradient/integrated_gradients.py +0 -0
  42. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/explainers/rule_based/__init__.py +0 -0
  43. {explainiverse-0.3.0 → explainiverse-0.5.0}/src/explainiverse/explainers/rule_based/anchors_wrapper.py +0 -0
@@ -0,0 +1,617 @@
1
+ Metadata-Version: 2.1
2
+ Name: explainiverse
3
+ Version: 0.5.0
4
+ Summary: Unified, extensible explainability framework supporting LIME, SHAP, Anchors, Counterfactuals, PDP, ALE, SAGE, and more
5
+ Home-page: https://github.com/jemsbhai/explainiverse
6
+ License: MIT
7
+ Keywords: xai,explainability,interpretability,machine-learning,lime,shap,anchors
8
+ Author: Muntaser Syed
9
+ Author-email: jemsbhai@gmail.com
10
+ Requires-Python: >=3.10,<3.13
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
20
+ Provides-Extra: torch
21
+ Requires-Dist: lime (>=0.2.0.1,<0.3.0.0)
22
+ Requires-Dist: numpy (>=1.24,<2.0)
23
+ Requires-Dist: pandas (>=1.5,<3.0)
24
+ Requires-Dist: scikit-learn (>=1.1,<1.6)
25
+ Requires-Dist: scipy (>=1.10,<2.0)
26
+ Requires-Dist: shap (>=0.48.0,<0.49.0)
27
+ Requires-Dist: torch (>=2.0) ; extra == "torch"
28
+ Requires-Dist: xgboost (>=1.7,<3.0)
29
+ Project-URL: Repository, https://github.com/jemsbhai/explainiverse
30
+ Description-Content-Type: text/markdown
31
+
32
+ # Explainiverse
33
+
34
+ [![PyPI version](https://badge.fury.io/py/explainiverse.svg)](https://badge.fury.io/py/explainiverse)
35
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
36
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
37
+
38
+ **Explainiverse** is a unified, extensible Python framework for Explainable AI (XAI). It provides a standardized interface for **15 state-of-the-art explanation methods** across local, global, gradient-based, and example-based paradigms, along with **comprehensive evaluation metrics** for assessing explanation quality.
39
+
40
+ ---
41
+
42
+ ## Key Features
43
+
44
+ | Feature | Description |
45
+ |---------|-------------|
46
+ | **15 Explainers** | LIME, KernelSHAP, TreeSHAP, Integrated Gradients, DeepLIFT, DeepSHAP, SmoothGrad, GradCAM/GradCAM++, Anchors, Counterfactual, Permutation Importance, PDP, ALE, SAGE, ProtoDash |
47
+ | **8 Evaluation Metrics** | Faithfulness (PGI, PGU, Comprehensiveness, Sufficiency, Correlation) and Stability (RIS, ROS, Lipschitz) |
48
+ | **Unified API** | Consistent `BaseExplainer` interface with standardized `Explanation` output |
49
+ | **Plugin Registry** | Filter explainers by scope, model type, data type; automatic recommendations |
50
+ | **Framework Support** | Adapters for scikit-learn and PyTorch (with gradient computation) |
51
+
52
+ ---
53
+
54
+ ## Explainer Coverage
55
+
56
+ ### Local Explainers (Instance-Level)
57
+
58
+ | Method | Type | Reference |
59
+ |--------|------|-----------|
60
+ | **LIME** | Perturbation | [Ribeiro et al., 2016](https://arxiv.org/abs/1602.04938) |
61
+ | **KernelSHAP** | Perturbation | [Lundberg & Lee, 2017](https://arxiv.org/abs/1705.07874) |
62
+ | **TreeSHAP** | Exact (Trees) | [Lundberg et al., 2018](https://arxiv.org/abs/1802.03888) |
63
+ | **Integrated Gradients** | Gradient | [Sundararajan et al., 2017](https://arxiv.org/abs/1703.01365) |
64
+ | **DeepLIFT** | Gradient | [Shrikumar et al., 2017](https://arxiv.org/abs/1704.02685) |
65
+ | **DeepSHAP** | Gradient + Shapley | [Lundberg & Lee, 2017](https://arxiv.org/abs/1705.07874) |
66
+ | **SmoothGrad** | Gradient | [Smilkov et al., 2017](https://arxiv.org/abs/1706.03825) |
67
+ | **GradCAM / GradCAM++** | Gradient (CNN) | [Selvaraju et al., 2017](https://arxiv.org/abs/1610.02391) |
68
+ | **Anchors** | Rule-Based | [Ribeiro et al., 2018](https://ojs.aaai.org/index.php/AAAI/article/view/11491) |
69
+ | **Counterfactual** | Contrastive | [Mothilal et al., 2020](https://arxiv.org/abs/1905.07697) |
70
+ | **ProtoDash** | Example-Based | [Gurumoorthy et al., 2019](https://arxiv.org/abs/1707.01212) |
71
+
72
+ ### Global Explainers (Model-Level)
73
+
74
+ | Method | Type | Reference |
75
+ |--------|------|-----------|
76
+ | **Permutation Importance** | Feature Importance | [Breiman, 2001](https://link.springer.com/article/10.1023/A:1010933404324) |
77
+ | **Partial Dependence (PDP)** | Feature Effect | [Friedman, 2001](https://projecteuclid.org/euclid.aos/1013203451) |
78
+ | **ALE** | Feature Effect | [Apley & Zhu, 2020](https://academic.oup.com/jrsssb/article/82/4/1059/7056085) |
79
+ | **SAGE** | Shapley Importance | [Covert et al., 2020](https://arxiv.org/abs/2004.00668) |
80
+
81
+ ---
82
+
83
+ ## Evaluation Metrics
84
+
85
+ Explainiverse includes a comprehensive suite of evaluation metrics based on the XAI literature:
86
+
87
+ ### Faithfulness Metrics
88
+
89
+ | Metric | Description | Reference |
90
+ |--------|-------------|-----------|
91
+ | **PGI** | Prediction Gap on Important features | [Petsiuk et al., 2018](https://arxiv.org/abs/1806.07421) |
92
+ | **PGU** | Prediction Gap on Unimportant features | [Petsiuk et al., 2018](https://arxiv.org/abs/1806.07421) |
93
+ | **Comprehensiveness** | Drop when removing top-k features | [DeYoung et al., 2020](https://arxiv.org/abs/1911.03429) |
94
+ | **Sufficiency** | Prediction using only top-k features | [DeYoung et al., 2020](https://arxiv.org/abs/1911.03429) |
95
+ | **Faithfulness Correlation** | Correlation between attribution and impact | [Bhatt et al., 2020](https://arxiv.org/abs/2005.00631) |
96
+
97
+ ### Stability Metrics
98
+
99
+ | Metric | Description | Reference |
100
+ |--------|-------------|-----------|
101
+ | **RIS** | Relative Input Stability | [Agarwal et al., 2022](https://arxiv.org/abs/2203.06877) |
102
+ | **ROS** | Relative Output Stability | [Agarwal et al., 2022](https://arxiv.org/abs/2203.06877) |
103
+ | **Lipschitz Estimate** | Local Lipschitz continuity | [Alvarez-Melis & Jaakkola, 2018](https://arxiv.org/abs/1806.08049) |
104
+
105
+ ---
106
+
107
+ ## Installation
108
+
109
+ ```bash
110
+ # From PyPI
111
+ pip install explainiverse
112
+
113
+ # With PyTorch support (for gradient-based methods)
114
+ pip install explainiverse[torch]
115
+
116
+ # For development
117
+ git clone https://github.com/jemsbhai/explainiverse.git
118
+ cd explainiverse
119
+ poetry install
120
+ ```
121
+
122
+ ---
123
+
124
+ ## Quick Start
125
+
126
+ ### Basic Usage with Registry
127
+
128
+ ```python
129
+ from explainiverse import default_registry, SklearnAdapter
130
+ from sklearn.ensemble import RandomForestClassifier
131
+ from sklearn.datasets import load_iris
132
+
133
+ # Train a model
134
+ iris = load_iris()
135
+ model = RandomForestClassifier(n_estimators=100, random_state=42)
136
+ model.fit(iris.data, iris.target)
137
+
138
+ # Wrap with adapter
139
+ adapter = SklearnAdapter(model, class_names=iris.target_names.tolist())
140
+
141
+ # List all available explainers
142
+ print(default_registry.list_explainers())
143
+ # ['lime', 'shap', 'treeshap', 'integrated_gradients', 'deeplift', 'deepshap',
144
+ # 'smoothgrad', 'gradcam', 'anchors', 'counterfactual', 'protodash',
145
+ # 'permutation_importance', 'partial_dependence', 'ale', 'sage']
146
+
147
+ # Create an explainer via registry
148
+ explainer = default_registry.create(
149
+ "lime",
150
+ model=adapter,
151
+ training_data=iris.data,
152
+ feature_names=iris.feature_names.tolist(),
153
+ class_names=iris.target_names.tolist()
154
+ )
155
+
156
+ # Generate explanation
157
+ explanation = explainer.explain(iris.data[0])
158
+ print(explanation.explanation_data["feature_attributions"])
159
+ ```
160
+
161
+ ### Filter and Recommend Explainers
162
+
163
+ ```python
164
+ # Filter by criteria
165
+ local_explainers = default_registry.filter(scope="local", data_type="tabular")
166
+ neural_explainers = default_registry.filter(model_type="neural")
167
+ image_explainers = default_registry.filter(data_type="image")
168
+
169
+ # Get recommendations
170
+ recommendations = default_registry.recommend(
171
+ model_type="neural",
172
+ data_type="tabular",
173
+ scope_preference="local",
174
+ max_results=5
175
+ )
176
+ ```
177
+
178
+ ---
179
+
180
+ ## Gradient-Based Explainers (PyTorch)
181
+
182
+ ### Integrated Gradients
183
+
184
+ ```python
185
+ from explainiverse import PyTorchAdapter
186
+ from explainiverse.explainers.gradient import IntegratedGradientsExplainer
187
+ import torch.nn as nn
188
+
189
+ # Define and wrap model
190
+ model = nn.Sequential(
191
+ nn.Linear(10, 64), nn.ReLU(),
192
+ nn.Linear(64, 32), nn.ReLU(),
193
+ nn.Linear(32, 3)
194
+ )
195
+ adapter = PyTorchAdapter(model, task="classification", class_names=["A", "B", "C"])
196
+
197
+ # Create explainer
198
+ explainer = IntegratedGradientsExplainer(
199
+ model=adapter,
200
+ feature_names=[f"feature_{i}" for i in range(10)],
201
+ class_names=["A", "B", "C"],
202
+ n_steps=50,
203
+ method="riemann_trapezoid"
204
+ )
205
+
206
+ # Explain with convergence check
207
+ explanation = explainer.explain(X[0], return_convergence_delta=True)
208
+ print(f"Attributions: {explanation.explanation_data['feature_attributions']}")
209
+ print(f"Convergence δ: {explanation.explanation_data['convergence_delta']:.6f}")
210
+ ```
211
+
212
+ ### DeepLIFT and DeepSHAP
213
+
214
+ ```python
215
+ from explainiverse.explainers.gradient import DeepLIFTExplainer, DeepLIFTShapExplainer
216
+
217
+ # DeepLIFT - Fast reference-based attributions
218
+ deeplift = DeepLIFTExplainer(
219
+ model=adapter,
220
+ feature_names=feature_names,
221
+ class_names=class_names,
222
+ baseline=None # Uses zero baseline by default
223
+ )
224
+ explanation = deeplift.explain(X[0])
225
+
226
+ # DeepSHAP - DeepLIFT averaged over background samples
227
+ deepshap = DeepLIFTShapExplainer(
228
+ model=adapter,
229
+ feature_names=feature_names,
230
+ class_names=class_names,
231
+ background_data=X_train[:100]
232
+ )
233
+ explanation = deepshap.explain(X[0])
234
+ ```
235
+
236
+ ### SmoothGrad
237
+
238
+ ```python
239
+ from explainiverse.explainers.gradient import SmoothGradExplainer
240
+
241
+ # SmoothGrad - Noise-averaged gradients for smoother saliency
242
+ explainer = SmoothGradExplainer(
243
+ model=adapter,
244
+ feature_names=feature_names,
245
+ class_names=class_names,
246
+ n_samples=50,
247
+ noise_scale=0.15,
248
+ noise_type="gaussian" # or "uniform"
249
+ )
250
+
251
+ # Standard SmoothGrad
252
+ explanation = explainer.explain(X[0], method="smoothgrad")
253
+
254
+ # SmoothGrad-Squared (sharper attributions)
255
+ explanation = explainer.explain(X[0], method="smoothgrad_squared")
256
+
257
+ # VarGrad (variance of gradients)
258
+ explanation = explainer.explain(X[0], method="vargrad")
259
+
260
+ # With absolute values
261
+ explanation = explainer.explain(X[0], absolute_value=True)
262
+ ```
263
+
264
+ ### GradCAM for CNNs
265
+
266
+ ```python
267
+ from explainiverse.explainers.gradient import GradCAMExplainer
268
+
269
+ # For CNN models
270
+ adapter = PyTorchAdapter(cnn_model, task="classification", class_names=class_names)
271
+
272
+ explainer = GradCAMExplainer(
273
+ model=adapter,
274
+ target_layer="layer4", # Last conv layer
275
+ class_names=class_names,
276
+ method="gradcam++" # or "gradcam"
277
+ )
278
+
279
+ explanation = explainer.explain(image)
280
+ heatmap = explanation.explanation_data["heatmap"]
281
+ overlay = explainer.get_overlay(original_image, heatmap, alpha=0.5)
282
+ ```
283
+
284
+ ---
285
+
286
+ ## Example-Based Explanations
287
+
288
+ ### ProtoDash
289
+
290
+ ```python
291
+ from explainiverse.explainers.example_based import ProtoDashExplainer
292
+
293
+ explainer = ProtoDashExplainer(
294
+ model=adapter,
295
+ training_data=X_train,
296
+ feature_names=feature_names,
297
+ n_prototypes=5,
298
+ kernel="rbf",
299
+ gamma=0.1
300
+ )
301
+
302
+ explanation = explainer.explain(X_test[0])
303
+ print(explanation.explanation_data["prototype_indices"])
304
+ print(explanation.explanation_data["prototype_weights"])
305
+ ```
306
+
307
+ ---
308
+
309
+ ## Evaluation Metrics
310
+
311
+ ### Faithfulness Evaluation
312
+
313
+ ```python
314
+ from explainiverse.evaluation import (
315
+ compute_pgi, compute_pgu,
316
+ compute_comprehensiveness, compute_sufficiency,
317
+ compute_faithfulness_correlation
318
+ )
319
+
320
+ # PGI - Higher is better (important features affect predictions)
321
+ pgi = compute_pgi(
322
+ model=adapter,
323
+ instance=X[0],
324
+ attributions=attributions,
325
+ feature_names=feature_names,
326
+ top_k=3
327
+ )
328
+
329
+ # PGU - Lower is better (unimportant features don't affect predictions)
330
+ pgu = compute_pgu(
331
+ model=adapter,
332
+ instance=X[0],
333
+ attributions=attributions,
334
+ feature_names=feature_names,
335
+ top_k=3
336
+ )
337
+
338
+ # Comprehensiveness - Higher is better
339
+ comp = compute_comprehensiveness(
340
+ model=adapter,
341
+ instance=X[0],
342
+ attributions=attributions,
343
+ feature_names=feature_names,
344
+ top_k_values=[1, 2, 3, 5]
345
+ )
346
+
347
+ # Sufficiency - Lower is better
348
+ suff = compute_sufficiency(
349
+ model=adapter,
350
+ instance=X[0],
351
+ attributions=attributions,
352
+ feature_names=feature_names,
353
+ top_k_values=[1, 2, 3, 5]
354
+ )
355
+
356
+ # Faithfulness Correlation
357
+ corr = compute_faithfulness_correlation(
358
+ model=adapter,
359
+ instance=X[0],
360
+ attributions=attributions,
361
+ feature_names=feature_names
362
+ )
363
+ ```
364
+
365
+ ### Stability Evaluation
366
+
367
+ ```python
368
+ from explainiverse.evaluation import (
369
+ compute_ris, compute_ros, compute_lipschitz_estimate
370
+ )
371
+
372
+ # RIS - Relative Input Stability (lower is better)
373
+ ris = compute_ris(
374
+ explainer=explainer,
375
+ instance=X[0],
376
+ n_perturbations=10,
377
+ perturbation_scale=0.1
378
+ )
379
+
380
+ # ROS - Relative Output Stability (lower is better)
381
+ ros = compute_ros(
382
+ model=adapter,
383
+ explainer=explainer,
384
+ instance=X[0],
385
+ n_perturbations=10,
386
+ perturbation_scale=0.1
387
+ )
388
+
389
+ # Lipschitz Estimate (lower is better)
390
+ lipschitz = compute_lipschitz_estimate(
391
+ explainer=explainer,
392
+ instance=X[0],
393
+ n_perturbations=20,
394
+ perturbation_scale=0.1
395
+ )
396
+ ```
397
+
398
+ ---
399
+
400
+ ## Global Explainers
401
+
402
+ ```python
403
+ from explainiverse.explainers import (
404
+ PermutationImportanceExplainer,
405
+ PartialDependenceExplainer,
406
+ ALEExplainer,
407
+ SAGEExplainer
408
+ )
409
+
410
+ # Permutation Importance
411
+ perm_imp = PermutationImportanceExplainer(
412
+ model=adapter,
413
+ X=X_test,
414
+ y=y_test,
415
+ feature_names=feature_names,
416
+ n_repeats=10
417
+ )
418
+ explanation = perm_imp.explain()
419
+
420
+ # Partial Dependence Plot
421
+ pdp = PartialDependenceExplainer(
422
+ model=adapter,
423
+ X=X_train,
424
+ feature_names=feature_names
425
+ )
426
+ explanation = pdp.explain(feature="feature_0", grid_resolution=50)
427
+
428
+ # ALE (handles correlated features)
429
+ ale = ALEExplainer(
430
+ model=adapter,
431
+ X=X_train,
432
+ feature_names=feature_names
433
+ )
434
+ explanation = ale.explain(feature="feature_0", n_bins=20)
435
+
436
+ # SAGE (global Shapley importance)
437
+ sage = SAGEExplainer(
438
+ model=adapter,
439
+ X=X_train,
440
+ y=y_train,
441
+ feature_names=feature_names,
442
+ n_permutations=512
443
+ )
444
+ explanation = sage.explain()
445
+ ```
446
+
447
+ ---
448
+
449
+ ## Multi-Explainer Comparison
450
+
451
+ ```python
452
+ from explainiverse import ExplanationSuite
453
+
454
+ suite = ExplanationSuite(
455
+ model=adapter,
456
+ explainer_configs=[
457
+ ("lime", {"training_data": X_train, "feature_names": feature_names, "class_names": class_names}),
458
+ ("shap", {"background_data": X_train[:50], "feature_names": feature_names, "class_names": class_names}),
459
+ ("treeshap", {"feature_names": feature_names, "class_names": class_names}),
460
+ ]
461
+ )
462
+
463
+ results = suite.run(X_test[0])
464
+ suite.compare()
465
+ ```
466
+
467
+ ---
468
+
469
+ ## Custom Explainer Registration
470
+
471
+ ```python
472
+ from explainiverse import default_registry, ExplainerMeta, BaseExplainer, Explanation
473
+
474
+ @default_registry.register_decorator(
475
+ name="my_explainer",
476
+ meta=ExplainerMeta(
477
+ scope="local",
478
+ model_types=["any"],
479
+ data_types=["tabular"],
480
+ task_types=["classification", "regression"],
481
+ description="My custom explainer",
482
+ paper_reference="Author et al., 2024",
483
+ complexity="O(n)",
484
+ requires_training_data=False,
485
+ supports_batching=True
486
+ )
487
+ )
488
+ class MyExplainer(BaseExplainer):
489
+ def __init__(self, model, feature_names, **kwargs):
490
+ super().__init__(model)
491
+ self.feature_names = feature_names
492
+
493
+ def explain(self, instance, **kwargs):
494
+ # Your implementation
495
+ attributions = self._compute_attributions(instance)
496
+ return Explanation(
497
+ explainer_name="MyExplainer",
498
+ target_class="output",
499
+ explanation_data={"feature_attributions": attributions}
500
+ )
501
+ ```
502
+
503
+ ---
504
+
505
+ ## Architecture
506
+
507
+ ```
508
+ explainiverse/
509
+ ├── core/
510
+ │ ├── explainer.py # BaseExplainer abstract class
511
+ │ ├── explanation.py # Unified Explanation container
512
+ │ └── registry.py # ExplainerRegistry with metadata
513
+ ├── adapters/
514
+ │ ├── sklearn_adapter.py
515
+ │ └── pytorch_adapter.py # With gradient support
516
+ ├── explainers/
517
+ │ ├── attribution/ # LIME, SHAP, TreeSHAP
518
+ │ ├── gradient/ # IG, DeepLIFT, DeepSHAP, SmoothGrad, GradCAM
519
+ │ ├── rule_based/ # Anchors
520
+ │ ├── counterfactual/ # DiCE-style
521
+ │ ├── global_explainers/ # Permutation, PDP, ALE, SAGE
522
+ │ └── example_based/ # ProtoDash
523
+ ├── evaluation/
524
+ │ ├── faithfulness.py # PGI, PGU, Comprehensiveness, Sufficiency
525
+ │ └── stability.py # RIS, ROS, Lipschitz
526
+ └── engine/
527
+ └── suite.py # Multi-explainer comparison
528
+ ```
529
+
530
+ ---
531
+
532
+ ## Running Tests
533
+
534
+ ```bash
535
+ # Run all tests
536
+ poetry run pytest
537
+
538
+ # Run with coverage
539
+ poetry run pytest --cov=explainiverse --cov-report=html
540
+
541
+ # Run specific test file
542
+ poetry run pytest tests/test_smoothgrad.py -v
543
+
544
+ # Run specific test class
545
+ poetry run pytest tests/test_smoothgrad.py::TestSmoothGradBasic -v
546
+ ```
547
+
548
+ ---
549
+
550
+ ## Roadmap
551
+
552
+ ### Completed ✅
553
+ - [x] Core framework (BaseExplainer, Explanation, Registry)
554
+ - [x] Perturbation methods: LIME, KernelSHAP, TreeSHAP
555
+ - [x] Gradient methods: Integrated Gradients, DeepLIFT, DeepSHAP, SmoothGrad, GradCAM/GradCAM++
556
+ - [x] Rule-based: Anchors
557
+ - [x] Counterfactual: DiCE-style
558
+ - [x] Global: Permutation Importance, PDP, ALE, SAGE
559
+ - [x] Example-based: ProtoDash
560
+ - [x] Evaluation: Faithfulness metrics (PGI, PGU, Comprehensiveness, Sufficiency, Correlation)
561
+ - [x] Evaluation: Stability metrics (RIS, ROS, Lipschitz)
562
+ - [x] PyTorch adapter with gradient support
563
+
564
+ ### In Progress 🚧
565
+ - [ ] Saliency Maps (vanilla gradients)
566
+ - [ ] TCAV (Testing with Concept Activation Vectors)
567
+ - [ ] Layer-wise Relevance Propagation (LRP)
568
+
569
+ ### Planned 📋
570
+ - [ ] Attention-based explanations (for Transformers)
571
+ - [ ] TensorFlow/Keras adapter
572
+ - [ ] Interactive visualization dashboard
573
+ - [ ] Explanation caching and serialization
574
+ - [ ] Distributed computation support
575
+
576
+ ---
577
+
578
+ ## Citation
579
+
580
+ If you use Explainiverse in your research, please cite:
581
+
582
+ ```bibtex
583
+ @software{explainiverse2025,
584
+ title = {Explainiverse: A Unified Framework for Explainable AI},
585
+ author = {Syed, Muntaser},
586
+ year = {2025},
587
+ url = {https://github.com/jemsbhai/explainiverse},
588
+ version = {0.5.0}
589
+ }
590
+ ```
591
+
592
+ ---
593
+
594
+ ## Contributing
595
+
596
+ Contributions are welcome! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
597
+
598
+ 1. Fork the repository
599
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
600
+ 3. Write tests for your changes
601
+ 4. Ensure all tests pass (`poetry run pytest`)
602
+ 5. Commit your changes (`git commit -m 'Add amazing feature'`)
603
+ 6. Push to the branch (`git push origin feature/amazing-feature`)
604
+ 7. Open a Pull Request
605
+
606
+ ---
607
+
608
+ ## License
609
+
610
+ MIT License - see [LICENSE](LICENSE) for details.
611
+
612
+ ---
613
+
614
+ ## Acknowledgments
615
+
616
+ Explainiverse builds upon the foundational work of many researchers in the XAI community. We thank the authors of LIME, SHAP, Integrated Gradients, DeepLIFT, GradCAM, Anchors, DiCE, ALE, SAGE, and ProtoDash for their contributions to interpretable machine learning.
617
+