case-explainer 0.1.1__tar.gz → 0.2.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 (47) hide show
  1. case_explainer-0.2.0/CHANGELOG.md +43 -0
  2. {case_explainer-0.1.1 → case_explainer-0.2.0}/MANIFEST.in +4 -0
  3. {case_explainer-0.1.1 → case_explainer-0.2.0}/PKG-INFO +158 -61
  4. {case_explainer-0.1.1 → case_explainer-0.2.0}/README.md +153 -51
  5. case_explainer-0.2.0/case_explainer/__init__.py +77 -0
  6. case_explainer-0.2.0/case_explainer/_compat.py +19 -0
  7. case_explainer-0.2.0/case_explainer/activations.py +789 -0
  8. case_explainer-0.2.0/case_explainer/explainer.py +948 -0
  9. {case_explainer-0.1.1 → case_explainer-0.2.0}/case_explainer/explanation.py +88 -62
  10. {case_explainer-0.1.1 → case_explainer-0.2.0}/case_explainer/indexing.py +25 -25
  11. {case_explainer-0.1.1 → case_explainer-0.2.0}/case_explainer/metrics.py +22 -22
  12. case_explainer-0.2.0/case_explainer/py.typed +0 -0
  13. {case_explainer-0.1.1 → case_explainer-0.2.0}/case_explainer.egg-info/SOURCES.txt +9 -1
  14. case_explainer-0.2.0/docs/api/explainer.rst +412 -0
  15. {case_explainer-0.1.1 → case_explainer-0.2.0}/docs/api/explanation.rst +0 -3
  16. {case_explainer-0.1.1 → case_explainer-0.2.0}/docs/conf.py +2 -5
  17. {case_explainer-0.1.1 → case_explainer-0.2.0}/docs/index.rst +1 -0
  18. case_explainer-0.2.0/docs/migration.rst +80 -0
  19. case_explainer-0.2.0/notebooks/02_breast_cancer_tutorial.ipynb +1487 -0
  20. {case_explainer-0.1.1 → case_explainer-0.2.0}/notebooks/03_fraud_detection_tutorial.ipynb +136 -0
  21. {case_explainer-0.1.1 → case_explainer-0.2.0}/notebooks/04_hardware_trojan_tutorial.ipynb +130 -0
  22. {case_explainer-0.1.1 → case_explainer-0.2.0}/pyproject.toml +27 -5
  23. case_explainer-0.2.0/setup.py +6 -0
  24. case_explainer-0.2.0/tests/test_activations.py +1290 -0
  25. case_explainer-0.2.0/tests/test_benchmark.py +98 -0
  26. {case_explainer-0.1.1 → case_explainer-0.2.0}/tests/test_explainer.py +54 -37
  27. {case_explainer-0.1.1 → case_explainer-0.2.0}/tests/test_explanation.py +20 -4
  28. {case_explainer-0.1.1 → case_explainer-0.2.0}/tests/test_indexing.py +26 -15
  29. {case_explainer-0.1.1 → case_explainer-0.2.0}/tests/test_metrics.py +26 -12
  30. case_explainer-0.2.0/tests/test_notebooks.py +25 -0
  31. case_explainer-0.1.1/case_explainer/__init__.py +0 -13
  32. case_explainer-0.1.1/case_explainer/explainer.py +0 -318
  33. case_explainer-0.1.1/docs/api/explainer.rst +0 -189
  34. case_explainer-0.1.1/notebooks/02_breast_cancer_tutorial.ipynb +0 -752
  35. case_explainer-0.1.1/setup.py +0 -50
  36. {case_explainer-0.1.1 → case_explainer-0.2.0}/LICENSE +0 -0
  37. {case_explainer-0.1.1 → case_explainer-0.2.0}/assets/README.md +0 -0
  38. {case_explainer-0.1.1 → case_explainer-0.2.0}/assets/data/hardware_trojan.csv +0 -0
  39. {case_explainer-0.1.1 → case_explainer-0.2.0}/docs/DEPLOYMENT.md +0 -0
  40. {case_explainer-0.1.1 → case_explainer-0.2.0}/docs/Makefile +0 -0
  41. {case_explainer-0.1.1 → case_explainer-0.2.0}/docs/README.md +0 -0
  42. {case_explainer-0.1.1 → case_explainer-0.2.0}/docs/api/metrics.rst +0 -0
  43. {case_explainer-0.1.1 → case_explainer-0.2.0}/docs/citation.rst +0 -0
  44. {case_explainer-0.1.1 → case_explainer-0.2.0}/docs/license.rst +0 -0
  45. {case_explainer-0.1.1 → case_explainer-0.2.0}/notebooks/01_iris_tutorial.ipynb +0 -0
  46. {case_explainer-0.1.1 → case_explainer-0.2.0}/notebooks/README.md +0 -0
  47. {case_explainer-0.1.1 → case_explainer-0.2.0}/setup.cfg +0 -0
@@ -0,0 +1,43 @@
1
+ ---
2
+ title: Case Explainer Changelog
3
+ description: Release history and migration schedule for Case Explainer
4
+ ---
5
+
6
+ ## 0.2.0 (2026-09-02)
7
+
8
+ * Added the unified ``similarity=`` constructor parameter as the single knob
9
+ for retrieval mode, accepting a string shorthand (``"features"``,
10
+ ``"activations"``) or a strategy object
11
+ * Added intent-named similarity strategies: ``Features``, ``HiddenActivations``,
12
+ ``CustomActivations``, ``TreeLeaf``, ``ForestProximity``, and ``Blend``
13
+ * Added predicted-class activation weighting for multiclass classifiers
14
+ * Added support for arbitrary hashable classifier labels
15
+ * Added a PEP 561 ``py.typed`` marker so downstream users receive the package's
16
+ type hints
17
+ * Deprecated the ``retrieval=`` parameter and the ``*Retrieval`` configuration
18
+ classes in favor of ``similarity=`` and the strategy classes above
19
+ * Deprecated the legacy `activation_extractor`, `activation_layer`,
20
+ `blend_alpha`, and `use_output_weights` constructor parameters
21
+
22
+ The deprecated parameters and classes remain functional throughout the `0.2.x`
23
+ series. Use `similarity=` with the strategy classes for new integrations.
24
+
25
+ ### Removal checklist for 0.3.0
26
+
27
+ * Remove the deprecated constructor parameters (`activation_extractor`,
28
+ `activation_layer`, `blend_alpha`, `use_output_weights`) and the
29
+ ``retrieval=`` parameter along with the ``*Retrieval`` classes
30
+ * Remove tests that assert legacy and strategy-based equivalence
31
+ * Retain a clear `TypeError` for removed parameter usage when practical
32
+ * Update examples and API reference pages to show only ``similarity=``
33
+ * Add a migration note with before-and-after constructor examples
34
+ * Verify the package version, runtime version, and Sphinx release stay aligned
35
+
36
+ The runtime warning contract is centralized in ``case_explainer._compat`` and
37
+ the migration examples are maintained in ``docs/migration.rst``. Complete the
38
+ checklist only when preparing the 0.3.0 release; version 0.2.x must continue to
39
+ accept the deprecated parameters.
40
+
41
+ ## 0.1.1
42
+
43
+ * Published the initial general-purpose feature-space case explainer
@@ -1,8 +1,12 @@
1
1
  # Include essential top-level files
2
2
  include README.md
3
3
  include LICENSE
4
+ include CHANGELOG.md
4
5
  include pyproject.toml
5
6
 
7
+ # Include the PEP 561 typing marker
8
+ include case_explainer/py.typed
9
+
6
10
  # Include notebooks
7
11
  recursive-include notebooks *.ipynb *.md
8
12
 
@@ -1,9 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: case-explainer
3
- Version: 0.1.1
3
+ Version: 0.2.0
4
4
  Summary: General-purpose case-based explainability for machine learning
5
- Home-page: https://github.com/paulwhitten/case-explainer
6
- Author: Paul Whitten
7
5
  Author-email: Paul Whitten <pcw@case.edu>
8
6
  License: MIT
9
7
  Project-URL: Homepage, https://github.com/paulwhitten/case-explainer
@@ -11,7 +9,7 @@ Project-URL: Documentation, https://paulwhitten.github.io/case-explainer/
11
9
  Project-URL: Repository, https://github.com/paulwhitten/case-explainer
12
10
  Project-URL: Bug Tracker, https://github.com/paulwhitten/case-explainer/issues
13
11
  Keywords: explainability,interpretability,machine-learning,case-based-reasoning,nearest-neighbors
14
- Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Development Status :: 4 - Beta
15
13
  Classifier: Intended Audience :: Science/Research
16
14
  Classifier: Intended Audience :: Developers
17
15
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
@@ -32,15 +30,12 @@ Requires-Dist: pandas>=1.3.0
32
30
  Provides-Extra: dev
33
31
  Requires-Dist: pytest>=7.0.0; extra == "dev"
34
32
  Requires-Dist: pytest-cov>=3.0.0; extra == "dev"
35
- Requires-Dist: black>=22.0.0; extra == "dev"
36
- Requires-Dist: flake8>=4.0.0; extra == "dev"
37
- Requires-Dist: mypy>=0.950; extra == "dev"
33
+ Requires-Dist: black==24.8.0; extra == "dev"
34
+ Requires-Dist: ruff==0.16.5; extra == "dev"
35
+ Requires-Dist: mypy==1.11.2; extra == "dev"
38
36
  Requires-Dist: build>=0.10.0; extra == "dev"
39
37
  Requires-Dist: twine>=4.0.0; extra == "dev"
40
- Dynamic: author
41
- Dynamic: home-page
42
38
  Dynamic: license-file
43
- Dynamic: requires-python
44
39
 
45
40
  # Case-Explainer: General-Purpose Case-Based Explainability
46
41
 
@@ -70,6 +65,7 @@ You get: *"This sample is classified as X because it resembles these 5 training
70
65
  - **Metadata tracking**: Attach provenance data to training samples
71
66
  - **Sklearn-compatible API**: Familiar interface for ML practitioners
72
67
  - **Batch explanations**: Explain multiple predictions efficiently
68
+ - **Model-informed similarity**: Retrieve cases from a neural network's learned representation or a decision tree's matching leaf
73
69
 
74
70
  ## Installation
75
71
 
@@ -120,11 +116,44 @@ print(explanation.summary())
120
116
 
121
117
  ## Core Concepts
122
118
 
119
+ ### Traditional Feature-Space Precedent
120
+
121
+ By default, Case-Explainer retrieves training cases that are nearest to the
122
+ query in the original feature space. Numeric features are standardized by
123
+ default so a feature with a large numerical range does not dominate Euclidean
124
+ distance. Set `scale_data=False` only when the inputs are already on a
125
+ meaningful common scale or when custom scaling has been applied.
126
+
127
+ ```python
128
+ feature_explainer = CaseExplainer(
129
+ X_train,
130
+ y_train,
131
+ feature_names=feature_names,
132
+ scale_data=True,
133
+ )
134
+
135
+ explanation = feature_explainer.explain_instance(
136
+ X_test[0],
137
+ model=classifier,
138
+ )
139
+ ```
140
+
141
+ This model-agnostic explanation answers: "Which observed training samples have
142
+ the most similar measured attributes?" It is useful when input features have a
143
+ domain meaning that a reviewer can inspect directly. Feature-space proximity
144
+ does not imply that the model used those features in the same way, and it can
145
+ be misleading when irrelevant, redundant, or high-dimensional inputs dominate
146
+ the distance.
147
+
148
+ The returned neighbors retain their original feature values, labels, indexes,
149
+ and optional metadata. Correspondence then measures how strongly their labels
150
+ agree with the model prediction; it does not measure feature importance.
151
+
123
152
  ### Correspondence Metric
124
153
 
125
154
  Quantifies agreement between prediction and retrieved neighbors using inverse-cubed distance weighting:
126
155
 
127
- ```
156
+ ```text
128
157
  w(c) = sum[ 1 / (distance + 1)^3 ] for neighbors with class c
129
158
  Correspondence = w(predicted_class) / sum( w(all_classes) )
130
159
  ```
@@ -132,6 +161,7 @@ Correspondence = w(predicted_class) / sum( w(all_classes) )
132
161
  The `+1` offset in the denominator prevents division by zero when a test sample is identical to a training sample (distance = 0). In that case the weight is simply `1 / 1 = 1`.
133
162
 
134
163
  **Example Interpretation Thresholds** (domain-dependent, not universal standards):
164
+
135
165
  - **High (≥85%)**: Strong agreement with training precedent
136
166
  - **Medium (70-85%)**: Moderate agreement
137
167
  - **Low (<70%)**: Weak agreement, prediction may be uncertain
@@ -144,6 +174,91 @@ The `+1` offset in the denominator prevents division by zero when a test sample
144
174
  - **`ball_tree`**: Better for high-dimensional data
145
175
  - **`brute`**: Exact search for small datasets (<10k samples)
146
176
 
177
+ ### Activation-Based Similarity (Neural Networks)
178
+
179
+ For sklearn `MLPClassifier` models, you can retrieve neighbors by hidden-layer
180
+ activations instead of raw input features. The resulting cases show consequences
181
+ of the model's learned representation. They do not expose the model's complete
182
+ internal reasoning.
183
+
184
+ ```python
185
+ from sklearn.neural_network import MLPClassifier
186
+ from case_explainer import CaseExplainer, HiddenActivations, Blend
187
+
188
+ mlp = MLPClassifier(hidden_layer_sizes=(64, 32, 16), random_state=42)
189
+ mlp.fit(X_train, y_train)
190
+
191
+ # Last hidden layer, based on Caruana et al. (1999)
192
+ explainer = CaseExplainer(
193
+ X_train, y_train,
194
+ similarity=HiddenActivations(model=mlp),
195
+ )
196
+
197
+ # All hidden layers with position weighting, a library extension
198
+ explainer_deep = CaseExplainer(
199
+ X_train, y_train,
200
+ similarity=HiddenActivations(model=mlp, layer="all_hidden"),
201
+ )
202
+
203
+ # Hybrid: blend features (30%) and activations (70%)
204
+ explainer_hybrid = CaseExplainer(
205
+ X_train, y_train,
206
+ similarity=Blend(HiddenActivations(model=mlp), features=0.3),
207
+ )
208
+
209
+ # Multiclass: weight units using the predicted class's output connections
210
+ explainer_class_weighted = CaseExplainer(
211
+ X_train, y_train,
212
+ similarity=HiddenActivations(
213
+ model=mlp,
214
+ output_weighting="predicted_class",
215
+ ),
216
+ )
217
+
218
+ # The construction model is reused for prediction.
219
+ explanation = explainer.explain_instance(X_test[0])
220
+ ```
221
+
222
+ If the MLP was trained on transformed inputs, pass its fitted transformer as
223
+ `input_transform`. The explainer applies it both when extracting activations
224
+ and when asking the model for a prediction.
225
+
226
+ The legacy `activation_extractor`, `activation_layer`, `use_output_weights`,
227
+ and `blend_alpha` constructor path, along with the `retrieval=` parameter,
228
+ remains supported but emits `DeprecationWarning`. Prefer `similarity=` with the
229
+ strategy classes (`HiddenActivations`, `CustomActivations`, `TreeLeaf`,
230
+ `ForestProximity`, `Blend`).
231
+
232
+ For sklearn random forests, use shared-leaf proximity rather than treating
233
+ leaf identifiers as numeric coordinates:
234
+
235
+ ```python
236
+ from case_explainer import ForestProximity
237
+
238
+ forest_explainer = CaseExplainer(
239
+ X_train, y_train,
240
+ similarity=ForestProximity(model=forest),
241
+ )
242
+ ```
243
+
244
+ See [notebooks/02_breast_cancer_tutorial.ipynb](notebooks/02_breast_cancer_tutorial.ipynb) for a full worked comparison.
245
+
246
+ ### Choosing a Retrieval Space
247
+
248
+ | Retrieval space | Meaning of a similar case | Best suited to | Main limitation |
249
+ | --- | --- | --- | --- |
250
+ | Features (default) | Nearby observed input attributes | Model-agnostic review and domain-readable measurements | May not reflect the model's learned notion of similarity |
251
+ | Hidden activations | Nearby learned neural-network representations | Inspecting precedents that the MLP represents similarly | Model-specific and less directly interpretable |
252
+ | Feature/activation hybrid | Nearby under a weighted combination of both spaces | Balancing domain similarity with model representation | The blend weight is an analyst choice that requires validation |
253
+ | Decision-tree leaf | Cases following the same tree path to a leaf | Exact precedent within a fitted decision tree | A leaf may contain fewer than `k` retained cases |
254
+ | Random-forest proximity | Cases sharing leaves across many trees | Model-informed precedent for fitted random forests | Requires comparison with the retained case base at query time |
255
+
256
+ All modes retrieve actual training cases. The retrieval space changes what
257
+ "like samples" means; the explanation and correspondence interfaces remain the
258
+ same. Use feature retrieval when observed attributes define the comparison you
259
+ want to defend. Use model-informed retrieval when the model's internal
260
+ partitioning or representation is the relevant basis for precedent.
261
+
147
262
  ## Examples
148
263
 
149
264
  See `quickstart.py` for a complete working example:
@@ -172,6 +287,7 @@ python benchmark.py --help # See all options
172
287
  ```
173
288
 
174
289
  Results (single run on reference hardware):
290
+
175
291
  - **Speed**: 14-37 ms per explanation depending on dataset size
176
292
  - **Memory**: <1 MB to 131 MB (scales with data size and dimensionality)
177
293
  - **Correspondence**: 87-100% neighbor agreement across validated domains
@@ -196,6 +312,7 @@ python3 -m http.server 8000 --directory docs/_build/html
196
312
  ```
197
313
 
198
314
  The documentation includes:
315
+
199
316
  - Complete API reference for all classes and functions
200
317
  - Usage examples and code snippets
201
318
  - Theory and mathematical foundations
@@ -211,13 +328,14 @@ The documentation includes:
211
328
  - **Personal data:** User behavior, preferences, demographics
212
329
 
213
330
  **Before using in production with sensitive data:**
331
+
214
332
  1. Implement feature masking for sensitive columns
215
333
  2. Consider differential privacy mechanisms
216
334
  3. Apply anonymization to metadata
217
335
  4. Set up access control and audit logging
218
336
  5. Review legal/regulatory requirements (GDPR, HIPAA, etc.)
219
337
 
220
- **Privacy protection features are planned for Phase 2.** For now, use only with non-sensitive data or in controlled research environments.
338
+ Privacy-preserving features are not yet available. Use only with non-sensitive data or in controlled research environments.
221
339
 
222
340
  Unlike LIME/SHAP which only show feature importance, case-explainer exposes training sample features. Evaluate whether this trade-off is acceptable for your use case.
223
341
 
@@ -229,13 +347,15 @@ Unlike LIME/SHAP which only show feature importance, case-explainer exposes trai
229
347
 
230
348
  ```python
231
349
  explainer = CaseExplainer(
232
- X_train, # Training features
233
- y_train, # Training labels
234
- feature_names=None, # Optional feature names
235
- class_names=None, # Optional class names {0: 'cat', 1: 'dog'}
236
- algorithm='kd_tree', # Indexing strategy
237
- scale_data=True, # Standardize features
238
- metadata=None # Optional provenance data
350
+ X_train, # Training features
351
+ y_train, # Training labels
352
+ feature_names=None, # Optional feature names
353
+ class_names=None, # Optional class names {0: 'cat', 1: 'dog'}
354
+ algorithm='kd_tree', # Indexing strategy
355
+ scale_data=True, # Standardize features
356
+ metadata=None, # Optional provenance data
357
+ # Explicit strategy object for hidden activations, tree leaves, or forests
358
+ retrieval=None,
239
359
  )
240
360
  ```
241
361
 
@@ -278,21 +398,25 @@ explanation.plot() # Visualize (bar plot)
278
398
  ## Validated Domains
279
399
 
280
400
  **Hardware Trojan Detection** (56,959 samples, 5 features)
401
+
281
402
  - 99.3% average correspondence across indexing methods
282
403
  - High neighbor agreement on imbalanced security data
283
404
  - 25.7 ms/sample explanation time (single run, reference hardware)
284
405
 
285
406
  **Credit Card Fraud Detection** (284,807 samples, 30 features)
407
+
286
408
  - 100% average correspondence (complete agreement with retrieved neighbors)
287
409
  - Highly imbalanced dataset (268:1 normal:fraud ratio)
288
410
  - 36.4 ms/sample explanation time (single run, reference hardware)
289
411
 
290
412
  **Medical Diagnosis - Breast Cancer** (569 samples, 30 features)
413
+
291
414
  - 93.3% average correspondence
292
415
  - Correct predictions: 96.2% correspondence vs 47.3% for incorrect predictions
293
416
  - 25.9 ms/sample explanation time (single run, reference hardware)
294
417
 
295
418
  **Also Validated On:**
419
+
296
420
  - Iris (92.7%), Wine (91.8%), Digits (94.9%), MNIST (87.5%)
297
421
  - See `benchmark.py` for full results across 7 datasets
298
422
 
@@ -301,6 +425,7 @@ explanation.plot() # Visualize (bar plot)
301
425
  ## When to Use Case-Based Explainability
302
426
 
303
427
  **Case-Explainer is well-suited for scenarios where:**
428
+
304
429
  - Domain experts need to verify predictions against known training cases
305
430
  - Precedent-based reasoning is valued (medical diagnosis, legal decisions, security analysis)
306
431
  - Concrete examples are more intuitive than feature importance scores
@@ -308,6 +433,7 @@ explanation.plot() # Visualize (bar plot)
308
433
  - Fast explanation generation is needed for real-time or interactive systems
309
434
 
310
435
  **Alternative approaches (LIME, SHAP) may be preferable when:**
436
+
311
437
  - Feature contributions are more relevant than training precedents
312
438
  - Training data cannot be exposed due to privacy/security constraints
313
439
  - Model debugging requires understanding feature-level behavior
@@ -315,7 +441,7 @@ explanation.plot() # Visualize (bar plot)
315
441
  ### Comparison with LIME and SHAP
316
442
 
317
443
  | Aspect | Case-Explainer | LIME | SHAP |
318
- |--------|---------------|------|------|
444
+ | -------- | --------------- | ------ | ------ |
319
445
  | Explanation type | Training precedents (similar cases) | Local surrogate model (feature importance) | Shapley values (feature importance) |
320
446
  | Output | k nearest neighbors + correspondence score | Per-feature importance for one prediction | Per-feature importance (local and global) |
321
447
  | Privacy risk | High -- exposes actual training samples | Low -- uses synthetic perturbations | Low -- no sample exposure |
@@ -327,65 +453,35 @@ explanation.plot() # Visualize (bar plot)
327
453
 
328
454
  ## Limitations
329
455
 
330
- **Privacy and Security**
456
+ ### Privacy and Security
457
+
331
458
  - Exposes actual training samples, which may contain sensitive information
332
459
  - Not suitable for sensitive data without additional privacy protection mechanisms
333
460
  - Privacy-preserving features are planned for future releases
334
461
 
335
- **Correspondence Metric**
462
+ ### Correspondence Metric Limitations
463
+
336
464
  - Measures neighbor agreement, not prediction correctness or quality
337
465
  - High correspondence can occur with incorrect predictions if training data contains systematic errors
338
466
  - Thresholds for "high/medium/low" must be validated per domain
339
467
 
340
- **Performance Benchmarks**
468
+ ### Performance Benchmark Limitations
469
+
341
470
  - Timing and memory results are from single runs on reference hardware
342
471
  - No statistical error bars or confidence intervals provided
343
472
  - Results may vary significantly on different hardware and with different parameters
344
473
 
345
- **Scalability**
474
+ ### Scalability Limitations
475
+
346
476
  - Memory usage scales linearly with training set size
347
477
  - Very large datasets (>1M samples) may require approximate nearest neighbor methods (not yet implemented)
348
478
 
349
- **Interpretability**
479
+ ### Interpretability Limitations
480
+
350
481
  - Assumes users can meaningfully interpret feature values of retrieved neighbors
351
482
  - Multi-feature patterns may be difficult to assess without domain expertise
352
483
  - High-dimensional data may require dimensionality reduction for effective interpretation
353
484
 
354
- ## Development Status
355
-
356
- ### Core Functionality MVP
357
- - [x] CaseExplainer class with sklearn-compatible API
358
- - [x] Correspondence metric with distance weighting
359
- - [x] Multiple indexing strategies (K-D tree, Ball tree, brute force)
360
- - [x] Explanation object with summary and visualization
361
- - [x] Metadata/provenance tracking
362
- - [x] Batch explanation support
363
-
364
- ### Phase 1: Multi-Domain Validation
365
- - [x] Hardware trojan detection (validated in JETTA paper)
366
- - [x] Medical diagnosis (UCI Breast Cancer)
367
- - [x] Fraud detection (Credit Card Fraud)
368
- - [x] Benchmarking (time, memory, correspondence)
369
-
370
- ### Phase 2: Documentation - IN PROGRESS
371
- - [x] API reference
372
- - [x] Tutorial notebooks (4 domains)
373
- - [x] Comparison guide (vs LIME/SHAP)
374
- - [x] Code coverage >90%
375
-
376
- ### Phase 3: Testing & Quality
377
- - [x] Unit test suite (pytest, >90% coverage)
378
- - [x] Multi-Python version compatibility (3.8–3.12)
379
- - [x] Integration tests across validated domains
380
- - [ ] Privacy-preserving features (feature masking, differential privacy)
381
- - [ ] Approximate nearest neighbors (Annoy, FAISS) for large-scale data
382
-
383
- ### Phase 4: Release & Distribution
384
- - [x] PyPI package (`pip install case-explainer`)
385
- - [x] GitHub Pages documentation (https://paulwhitten.github.io/case-explainer/)
386
- - [x] CI/CD pipeline (GitHub Actions: test matrix, publish to PyPI)
387
- - [ ] Zenodo DOI
388
-
389
485
  ## Citation
390
486
 
391
487
  If you use this module in academic work, please cite:
@@ -408,6 +504,7 @@ MIT License - see LICENSE file for details.
408
504
  Contributions welcome! Core functionality and release infrastructure are complete.
409
505
 
410
506
  **Priority areas:**
507
+
411
508
  - Additional distance metrics (Manhattan, Cosine)
412
509
  - Approximate nearest neighbors (Annoy, FAISS) for large-scale data
413
510
  - Radar and parallel coordinate visualizations
@@ -415,7 +512,7 @@ Contributions welcome! Core functionality and release infrastructure are complet
415
512
 
416
513
  ## Contact
417
514
 
418
- Questions? Issues? Open a GitHub issue or contact pcw@case.edu.
515
+ Questions? Issues? Open a GitHub issue or contact <pcw@case.edu>.
419
516
 
420
517
  ## Acknowledgments
421
518