Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -207,3 +207,4 @@ marimo/_lsp/
__marimo__/
.DS_Store
.vscode/settings.json
.DS_Store
28 changes: 20 additions & 8 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
# Changelog

## [0.0.1] - 2026-02-12
## [0.0.2] - 2026-02-17
### Added
- Shared diagnostics now emit qualitative labels (GOOD/MODERATE/POOR) with unified `[FDFI][DIAG]` logging for OT/EOT/Flow explainers.
- Utility functions `compute_latent_independence` and `compute_mmd` are promoted and documented in the public API.
- Notebook investigations now include SE calibration checks (formula vs bootstrap) and reconstruction-fidelity checks for FlowExplainer.

### Changed
- `conf_int()` now defaults to mixture-based variance floor and mixture-based margin for all explainers.
- Diagnostics implementation is generalized in the base explainer API (`diagnose` / `diagnostics`) for OT/EOT/Flow, and Flow-specific legacy diagnostics are removed.
- Flow diagnostics reconstruction now uses high-precision ODE tolerances to measure model fidelity instead of solver drift.
- Flow solver tolerances are configurable (`flow_solver_rtol/atol`, `diagnostics_solver_rtol/atol`) and flow training can be seeded via `flow_training_seed`.
- `compute_latent_independence` and `compute_mmd` are optimized for better computational efficiency.
- Package version is synchronized to `0.0.2` across package metadata, docs configuration, and tutorial notebook outputs.

## [0.0.1] - 2026-01-31
### Added
- **OTExplainer**: Gaussian optimal-transport DFI for feature importance computation
- **EOTExplainer**: Entropic optimal-transport DFI with adaptive epsilon, stochastic transport sampling, and Gaussian/empirical targets
Expand All @@ -18,10 +31,9 @@
- GitHub Actions workflows for CI/CD and PyPI publishing

### Changed
- Package renamed from `dfi` to `fdfi` for PyPI availability
- DFIExplainer renamed to OTExplainer (DFIExplainer remains as alias)
- Removed legacy `setup.py` and `requirements*.txt` in favor of `pyproject.toml` extras

### Dependencies
- Core: numpy, scipy, scikit-learn, matplotlib, seaborn
- Optional `[flow]`: torch, torchdiffeq (for FlowExplainer)
- EOT/OT explainers now cache results for post-hoc CI computation via `conf_int`.
- Exp3 example now uses `conf_int` for CI bands and supports `FDFI_USE_EOT` toggle.
- `environment.yml` now includes plotting + sklearn deps for running examples.
- Removed legacy `setup.py` and `requirements*.txt` in favor of `pyproject.toml` extras.
- DFIExplainer is renamed to OTExplainer (DFIExplainer remains as an alias).
- Explainer can skip flow training via `fit_flow=False`.
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

A Python library for computing feature importance using disentangled methods, inspired by SHAP.

Current release: `0.0.2`

## Overview

FDFI (Flow-Disentangled Feature Importance) is a Python module that provides interpretable machine learning explanations through disentangled feature importance methods. This package implements both DFI (Disentangled Feature Importance) and FDFI (Flow-DFI) methods. Similar to SHAP, FDFI helps you understand which features are driving your model's predictions.
Expand Down Expand Up @@ -63,6 +65,16 @@ results = explainer(X_test)
ci = explainer.conf_int(alpha=0.05, target="X", alternative="two-sided")
```

### CI Defaults in v0.0.2

By default, `conf_int()` now uses:

- `var_floor_method="mixture"`
- `margin_method="mixture"`

This improves stability for weak effects and avoids ad hoc thresholding in many use cases.
You can still override both methods explicitly if needed.

## EOT Options (Entropic OT)

`EOTExplainer` supports adaptive epsilon, stochastic transport sampling, and
Expand Down Expand Up @@ -111,6 +123,29 @@ results = explainer(X_test)
ci = explainer.conf_int(alpha=0.05, target="Z", alternative="two-sided")
```

### Explainer diagnostics (new in v0.0.2)

Disentangled explainers (`OTExplainer`, `EOTExplainer`, and `FlowExplainer`) report two diagnostics with qualitative labels (GOOD / MODERATE / POOR) using consistent `[FDFI][DIAG]` logging:

- **Latent independence (median dCor)** — lower is better (thresholds: <0.10 good, <0.25 moderate).
- **Distribution fidelity (MMD)** — lower is better (thresholds: <0.05 good, <0.15 moderate).

Example log:

```
[FDFI][DIAG] Flow Model Diagnostics
[FDFI][DIAG] Latent independence (median dCor): 0.0421 [GOOD] → lower is better
[FDFI][DIAG] Distribution fidelity (MMD): 0.0187 [GOOD] → lower is better
```

Access diagnostics directly:

```python
diag = explainer.diagnostics
print(diag["latent_independence_median"], diag["latent_independence_label"])
print(diag["distribution_fidelity_mmd"], diag["distribution_fidelity_label"])
```

For advanced users, flow models can be trained separately:

```python
Expand Down
10 changes: 10 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ orphan: true
# DFI Documentation

This is the documentation source for DFI (Disentangled Feature Importance).
Current documented release: `0.0.2`.

For the full documentation, see the main README in the project root or build the docs:

Expand All @@ -25,3 +26,12 @@ open _build/html/index.html
- [Concepts](user_guide/concepts.rst): Theory behind DFI and Flow-DFI
- [Choosing an Explainer](user_guide/choosing_explainer.rst): Which explainer to use
- [Tutorials](tutorials/index.rst): Hands-on notebooks

## Diagnostics

All disentangled explainers (`OTExplainer`, `EOTExplainer`, and `FlowExplainer`)
expose a shared `diagnostics` dictionary with latent independence (dCor) and
distribution fidelity (MMD) metrics plus qualitative labels.

Confidence intervals (`conf_int`) use mixture defaults in v0.0.2 for both
variance floor and practical margin.
22 changes: 22 additions & 0 deletions docs/api/explainers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,28 @@ and empirical transport targets.
)
results = explainer(X_test)

Shared Disentanglement Diagnostics
----------------------------------

``OTExplainer``, ``EOTExplainer``, and ``FlowExplainer`` expose a shared
diagnostics interface via:

- ``explainer.diagnostics`` (computed at setup by default)
- ``explainer.diagnose(...)`` (recompute manually)

The diagnostics dictionary contains:

- ``latent_independence_dcor`` (pairwise dCor matrix)
- ``latent_independence_median`` and ``latent_independence_label``
- ``distribution_fidelity_mmd`` and ``distribution_fidelity_label``

.. code-block:: python

diag = explainer.diagnostics
# or: diag = explainer.diagnose()
print(diag["latent_independence_median"], diag["latent_independence_label"])
print(diag["distribution_fidelity_mmd"], diag["distribution_fidelity_label"])

Flow-Based DFI (FlowExplainer)
------------------------------

Expand Down
7 changes: 7 additions & 0 deletions docs/api/utils.rst
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ Computes the Gower distance matrix for mixed-type data (continuous, binary,
and categorical features). Used by ``EOTExplainer`` when ``cost_metric="gower"``
or ``cost_metric="auto"``.

Diagnostics Utilities
---------------------

.. autofunction:: fdfi.utils.compute_latent_independence

.. autofunction:: fdfi.utils.compute_mmd

Statistical Utilities
---------------------

Expand Down
9 changes: 5 additions & 4 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
sys.path.insert(0, os.path.abspath(".."))

# -- Project information -----------------------------------------------------
project = "DFI"
copyright = "2024, DFI Team"
author = "DFI Team"
release = "0.0.1"
project = "FDFI"
copyright = "2025, FDFI Team"
author = "FDFI Team"
release = "0.0.2"

# -- General configuration ---------------------------------------------------
extensions = [
Expand Down Expand Up @@ -91,6 +91,7 @@
# -- Options for HTML output -------------------------------------------------
html_theme = "sphinx_rtd_theme"
html_static_path = ["_static"]
html_title = "FDFI Documentation"

html_theme_options = {
"logo_only": False,
Expand Down
33 changes: 29 additions & 4 deletions docs/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,23 @@ results = explainer(X_test)

### EOTExplainer (Entropic OT)

Entropic OT DFI using a learned transport kernel:
Entropic OT DFI using a learned transport kernel (useful for non-Gaussian and mixed-type tabular data):

```python
import numpy as np
from fdfi.explainers import EOTExplainer

explainer = EOTExplainer(model.predict, X_background, epsilon=0.1, nsamples=50)
feature_types = np.array(["continuous", "binary", "categorical", "continuous"])

explainer = EOTExplainer(
model.predict,
X_background,
nsamples=50,
cost_metric="gower",
feature_types=feature_types,
auto_epsilon=True,
target="empirical",
)
results = explainer(X_test)
```

Expand All @@ -116,15 +127,29 @@ explainer = EOTExplainer(
)
```

### Confidence Intervals
### Attribution Inference (Confidence Intervals)

All explainers support post-hoc CIs via `conf_int`:
All explainers support post-hoc attribution inference via `conf_int`:

```python
results = explainer(X_test)
ci = explainer.conf_int(alpha=0.05, target="X", alternative="two-sided")
```

In v0.0.2, `conf_int` defaults to mixture-based methods for both variance floor
and practical margin. You can still pass explicit methods/quantiles to override.

### Disentanglement Diagnostics

`OTExplainer`, `EOTExplainer`, and `FlowExplainer` expose a shared
`diagnostics` dictionary:

```python
diag = explainer.diagnostics
print(diag["latent_independence_median"], diag["latent_independence_label"])
print(diag["distribution_fidelity_mmd"], diag["distribution_fidelity_label"])
```

## Next Steps

- See `examples/` directory for complete examples
Expand Down
9 changes: 5 additions & 4 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
DFI Documentation
=================
FDFI Documentation
==================

.. image:: https://img.shields.io/badge/License-MIT-yellow.svg
:target: https://opensource.org/licenses/MIT
Expand All @@ -9,15 +9,16 @@ DFI Documentation
:target: https://www.python.org/downloads/
:alt: Python 3.8+

**DFI** (Disentangled Feature Importance) is a Python library for computing
**FDFI** (Flow-Disentangled Feature Importance) is a Python library for computing
feature importance using disentangled methods, inspired by SHAP. This package
implements both DFI and FDFI (Flow-DFI) methods.
implements both OT-based DFI and flow-based FDFI methods.

Key Features
------------

- 🎯 **Multiple Explainer Types**: Tree, Linear, Kernel, and Optimal Transport explainers
- 🧭 **OT-Based DFI**: Gaussian OT (OTExplainer) and Entropic OT (EOTExplainer)
- 🔍 **Shared Diagnostics**: Latent independence and fidelity checks for OT/EOT/Flow
- 📊 **Statistical Inference**: Confidence intervals and hypothesis testing
- 🔧 **Easy to Use**: Simple API similar to SHAP
- 🚀 **Extensible**: Built with modularity for future enhancements
Expand Down
Loading