> ## Documentation Index
> Fetch the complete documentation index at: https://fpde-80-mintlify-8d7c1d86.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Examples

> FPDE usage examples for single-sample explanations, batch explanations, lambda selection, Bayesian-FPDE posteriors, and grid search.

Use `FPDEEngine` for most workflows.
It stores prototypes, anchors, the baseline vector, and label lookup state so you can reuse them across explanations.

## Explain one sample

```python theme={null}
from fpde import FPDEEngine

engine = FPDEEngine.fit(X_train, y_train, model=model)
attributions, details = engine.explain_one(X_test[0], lambda_hyb=0.5)

print(details["target_label"])
print(details["rival_label"])
print(details["evidence"])
```

`details["target_label"]` is the model's highest-probability class.
`details["rival_label"]` is the second-highest-probability class.

## Explain a batch

Use `explain_batch` when you need both attribution rows and per-sample metadata.

```python theme={null}
attribution_matrix, details = engine.explain_batch(
    X_test[:10],
    lambda_hyb=0.5,
    normalize="l1",
)

print(attribution_matrix.shape)
print(details[0]["exactness_residual"])
```

Use `explain_matrix` when you only need the attribution matrix.

```python theme={null}
attribution_matrix = engine.explain_matrix(X_test[:10], lambda_hyb=0.5)
```

## Select `lambda_hyb`

Use held-out validation data to select a fixed Hyb-FPDE mixture.
The selection score combines deletion and insertion perturbation curves.

```python theme={null}
selection = engine.select_lambda(
    X_val,
    lambda_hyb_grid=(0.0, 0.25, 0.5, 0.75, 1.0),
    fractions=(0.0, 0.1, 0.3, 0.5, 0.7, 1.0),
)

best_lambda = selection.best_lambda
attributions, details = engine.explain_batch(X_test, lambda_hyb=best_lambda)
```

Save `selection.rows` with your experiment results so you can inspect the score for each candidate later.

## Build a Bayesian-FPDE posterior over `lambda_hyb`

Use `select_bayesian_lambda` when you want a posterior over the Hyb-FPDE mixture weight instead of a single selected value.
The posterior is built on the same held-out deletion and insertion score as `select_lambda`, with a `Beta(alpha, beta)` prior and a likelihood temperature.

```python theme={null}
selection = engine.select_bayesian_lambda(
    X_val,
    lambda_hyb_grid=(0.0, 0.25, 0.5, 0.75, 1.0),
    alpha=1.0,
    beta=1.0,
    temperature=1.0,
    credible_mass=0.95,
)

print(selection.posterior_mean_lambda)
print(selection.map_lambda)
print(selection.credible_interval)
```

Then explain samples with the posterior-mean `lambda_hyb`:

```python theme={null}
attributions, details = engine.explain_one_bayesian(X_test[0], selection)

print(details["posterior_mean_lambda"])
print(details["credible_interval"])
print(details["posterior_entropy"])
```

Use `explain_batch_bayesian` or `explain_matrix_bayesian` for many samples.
Inspect `selection.sorted_rows()` to see candidates from highest to lowest posterior mass.

## Run grid search

Use `grid_search` to compare Diff-FPDE, Cos-FPDE, and Hyb-FPDE candidate settings.

```python theme={null}
result = engine.grid_search(
    X_eval,
    lambda_hyb_grid=(0.0, 0.5, 1.0),
    normalize_grid=("l1", "none"),
    objective="blackbox_agreement",
)

print(result.best_config)
print(result.best_score)
```

## Direct prototype functions

Use lower-level functions when you want direct control over prototypes and labels.

```python theme={null}
from fpde import class_mean_prototypes, explain_with_selected_prototypes

prototypes, labels = class_mean_prototypes(X_train, y_train)
explanation = explain_with_selected_prototypes(
    X_test[0],
    prototypes,
    labels,
    positive_label=target_label,
    negative_label=rival_label,
    mode="diff",
)

print(explanation.attributions)
print(explanation.evidence)
```

For repeated work, prefer `FPDEEngine`.
