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
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ htmlcov/
# Documentation
docs/_build/

# Generated outputs and temporary files
outputs/
results/
examples/results
wandb/
experiments/results/
experiments/local_explanation/results/
wandb/
.codex/
113 changes: 113 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,124 @@ The high-level API is designed to return structured outputs so downstream tools

- `DPGExplainer.fit(X)`: builds the DPG structure
- `DPGExplainer.explain_global(X=None, communities=False, community_threshold=0.2)`: returns a `DPGExplanation`
- `DPGExplainer.explain_local(sample, sample_id=0, X=None, validate_graph=True)`: returns a `DPGLocalExplanation`
- `DPGExplainer.local_path_dataframe(local_explanation)`: flattens local paths into a tabular view
- `DPGExplainer.plot(...)`: renders the standard DPG
- `DPGExplainer.plot_communities(...)`: renders a community-colored DPG
- `DPGExplainer.plot_local_on_dpg(...)`: overlays one sample's local paths on the fitted DPG

`DPGExplanation` includes `dot`, `graph`, `nodes`, `node_metrics`, `edge_metrics`, `class_boundaries`, and optional `communities`.

### Local explanations

DPG also supports sample-level explanations on top of the fitted global graph.

#### Graph construction modes

You can control how the graph is built through `dpg.graph_construction.mode`:

```python
from dpg import DPGExplainer

explainer = DPGExplainer(
model=model,
feature_names=X.columns.tolist(),
target_names=class_names,
dpg_config={
"dpg": {
"default": {
"perc_var": 1e-9,
"decimal_threshold": 6,
"n_jobs": -1,
},
"graph_construction": {
"mode": "execution_trace", # or "aggregated_transitions"
},
}
},
)
```

- `"aggregated_transitions"`: current default behavior; filters path variants first, then discovers the DPG.
- `"execution_trace"`: builds directly from raw traces and filters edges instead of whole-path variants when `perc_var > 0`.

#### Minimal local workflow

```python
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
from dpg import DPGExplainer
import numpy as np

X, y = load_iris(return_X_y=True, as_frame=True)
model = RandomForestClassifier(n_estimators=5, random_state=42).fit(X, y)

explainer = DPGExplainer(
model=model,
feature_names=X.columns.tolist(),
target_names=np.unique(y).astype(str).tolist(),
)
explainer.fit(X.values)

local = explainer.explain_local(sample=X.iloc[0].values, sample_id=0)

print(local.majority_vote)
print(local.class_votes)
print(local.sample_confidence)

df_local = explainer.local_path_dataframe(local)
print(df_local.head())
```

`local.tree_paths[*].labels` stay in DPG label format such as `"sepal width (cm) <= 3.0"` and `"Class 0"`.
For easier aggregation, `local.class_votes` and `local.majority_vote` use normalized class names such as `"0"` instead of `"Class 0"`.

#### Local plotting

```python
explainer.plot_local_on_dpg(
"iris_local_sample0",
local_explanation=local,
true_class_label=str(y.iloc[0]),
save_dir="results/",
theme="dpg",
palette="olive",
layout_template="vertical",
show=False,
)
```

A runnable example is available at [examples/local_explanation_iris.py](examples/local_explanation_iris.py).

#### Faithfulness evaluation

You can also evaluate local explanations against the fitted black-box model:

```python
details = explainer.evaluate_faithfulness(
X_test,
y_true=y_test,
return_details=True,
)

print(details["faithfulness_score"])
print(details["output_fidelity"])
print(details["mean_trace_coverage_score"])
print(details["mean_recombination_rate"])
```

This reports:
- `output_fidelity`: agreement between the local explanation and the black-box model
- structural metrics such as trace coverage and recombination
- semantic metrics such as evidence margin
- a composite `faithfulness_score`

Important:
- the composite score is a heuristic summary, not a calibrated probability
- `output_fidelity` is model agreement, not ground-truth correctness
- `local_accuracy` is only reported when `y_true` is provided
- structural faithfulness here means recovering the executed decision traces used by the model

#### CLI scripts
The library contains two different scripts to apply DPG:
- `run_dpg_standard.py`: with this script it is possible to test DPG on a standard classification dataset provided by `sklearn` such as `iris`, `digits`, `wine`, `breast cancer`, and `diabetes`.
Expand Down
88 changes: 88 additions & 0 deletions docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,94 @@ explainer = DPGExplainer(
)
```

You can also configure how the graph is constructed:

```python
explainer = DPGExplainer(
model,
feature_names=X.columns.tolist(),
dpg_config={
"dpg": {
"default": {
"perc_var": 1e-9,
"decimal_threshold": 6,
"n_jobs": -1,
},
"graph_construction": {
"mode": "execution_trace", # or "aggregated_transitions"
},
}
},
)
```

- `aggregated_transitions`: default global DPG behavior.
- `execution_trace`: trace-first construction, useful for local path inspection.

## Local explanations

After fitting the explainer, you can inspect one sample at a time:

```python
local = explainer.explain_local(sample=X.iloc[0].values, sample_id=0)

print(local.majority_vote)
print(local.class_votes)
print(local.sample_confidence)

local_df = explainer.local_path_dataframe(local)
print(local_df.head())
```

Path labels remain in DPG format such as `Class 0`, while `local.class_votes`
and `local.majority_vote` use normalized class names such as `0`.

To render the local paths on top of the fitted DPG:

```python
explainer.plot_local_on_dpg(
"iris_local_sample0",
local_explanation=local,
true_class_label=str(y.iloc[0]),
save_dir="results/",
theme="dpg",
palette="olive",
show=False,
)
```

See [examples/local_explanation_iris.py](../examples/local_explanation_iris.py)
for a minimal runnable script.

## Faithfulness evaluation

DPG can evaluate local explanations against the fitted black-box model:

```python
details = explainer.evaluate_faithfulness(
X_test,
y_true=y_test,
return_details=True,
)

print(details["faithfulness_score"])
print(details["output_fidelity"])
print(details["mean_trace_coverage_score"])
print(details["mean_recombination_rate"])
```

This API reports:
- `output_fidelity`: agreement between the local explanation and the model
- structural metrics such as trace coverage and recombination
- semantic metrics such as evidence margin
- a composite `faithfulness_score`

Notes:
- the composite score is a heuristic summary, not a calibrated probability
- `output_fidelity` measures agreement with the black-box model
- `local_accuracy` is only available when `y_true` is supplied
- structural faithfulness here is about recovering executed decision traces

## Visualisation options

For a complete gallery of available graph and chart outputs, see
Expand Down
11 changes: 10 additions & 1 deletion dpg/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# dpg/__init__.py
from .core import DecisionPredicateGraph
from .explainer import DPGExplainer, DPGExplanation
from .explainer import (
DPGExplainer,
DPGExplanation,
DPGLocalExplanation,
DPGTreePathExplanation,
)
from .themes import DPG_CLASS_PALETTE, DPG_COLORS, DPG_OLIVE_CLASS_PALETTE, resolve_theme_context
from .visualizer import (
class_feature_predicate_counts,
Expand All @@ -10,6 +15,7 @@
plot_dpg,
plot_dpg_class_bounds_vs_dataset_feature_ranges,
plot_dpg_constraints_overview,
plot_dpg_local_paths_aggregate,
plot_dpg_reg,
plot_lec_vs_rf_importance,
plot_lrc_vs_rf_importance,
Expand All @@ -22,11 +28,14 @@
"DecisionPredicateGraph",
"DPGExplainer",
"DPGExplanation",
"DPGLocalExplanation",
"DPGTreePathExplanation",
"DPG_COLORS",
"DPG_CLASS_PALETTE",
"DPG_OLIVE_CLASS_PALETTE",
"resolve_theme_context",
"plot_dpg",
"plot_dpg_local_paths_aggregate",
"plot_dpg_reg",
"plot_dpg_constraints_overview",
"plot_lrc_vs_rf_importance",
Expand Down
Loading
Loading