Skip to content

Adapters

from_shap_explanation

from_shap_explanation(explanation: Any, *, feature_names: Sequence[str] | None = None, class_index: int | None = None) -> tuple[ndarray, list[str]]

Convert a SHAP Explanation (or compatible object) to (values, names).

PARAMETER DESCRIPTION
explanation

Either a shap.Explanation instance or any object with .values and .feature_names attributes. A raw numpy.ndarray is also accepted when feature_names is provided.

TYPE: Any

feature_names

Required only when explanation does not carry feature_names of its own.

TYPE: Sequence[str] | None DEFAULT: None

class_index

For multi-class explanations (3D values of shape (N, F, C)), select one class. Defaults to the last class.

TYPE: int | None DEFAULT: None

Source code in src/concept_graph_xai/adapters/shap.py
def from_shap_explanation(
    explanation: Any,
    *,
    feature_names: Sequence[str] | None = None,
    class_index: int | None = None,
) -> tuple[np.ndarray, list[str]]:
    """Convert a SHAP ``Explanation`` (or compatible object) to ``(values, names)``.

    Parameters
    ----------
    explanation:
        Either a ``shap.Explanation`` instance or any object with ``.values`` and
        ``.feature_names`` attributes. A raw ``numpy.ndarray`` is also accepted
        when ``feature_names`` is provided.
    feature_names:
        Required only when ``explanation`` does not carry ``feature_names`` of
        its own.
    class_index:
        For multi-class explanations (3D ``values`` of shape ``(N, F, C)``),
        select one class. Defaults to the last class.
    """

    values = getattr(explanation, "values", explanation)
    arr = np.asarray(values, dtype=float)

    names: list[str]
    explanation_names = getattr(explanation, "feature_names", None)
    if feature_names is not None:
        names = list(feature_names)
    elif explanation_names is not None:
        names = list(explanation_names)
    else:
        raise ValueError("feature_names must be provided when the explanation has none")

    if arr.ndim == 3:
        idx = class_index if class_index is not None else arr.shape[2] - 1
        arr = arr[:, :, idx]

    if arr.ndim not in (1, 2):
        raise ValueError(f"unexpected SHAP values rank: {arr.ndim}")
    if arr.shape[-1] != len(names):
        raise ValueError(
            f"shape mismatch: values has {arr.shape[-1]} features, names has {len(names)}"
        )

    return arr, names

from_permutation_importance

from_permutation_importance(result: Any, feature_names: Sequence[str], *, use: str = 'importances_mean') -> tuple[ndarray, list[str]]

Convert a sklearn Bunch (from permutation_importance) to arrays.

PARAMETER DESCRIPTION
result

The Bunch returned by sklearn.inspection.permutation_importance, with attributes importances_mean and importances_std.

TYPE: Any

feature_names

Names matching the order of features used during the permutation run.

TYPE: Sequence[str]

use

Which attribute on the Bunch to expose. Defaults to importances_mean.

TYPE: str DEFAULT: 'importances_mean'

Source code in src/concept_graph_xai/adapters/sklearn_perm.py
def from_permutation_importance(
    result: Any,
    feature_names: Sequence[str],
    *,
    use: str = "importances_mean",
) -> tuple[np.ndarray, list[str]]:
    """Convert a sklearn ``Bunch`` (from ``permutation_importance``) to arrays.

    Parameters
    ----------
    result:
        The Bunch returned by ``sklearn.inspection.permutation_importance``,
        with attributes ``importances_mean`` and ``importances_std``.
    feature_names:
        Names matching the order of features used during the permutation run.
    use:
        Which attribute on the Bunch to expose. Defaults to ``importances_mean``.
    """

    if not hasattr(result, use):
        raise AttributeError(f"permutation_importance result has no attribute {use!r}")
    values = np.asarray(getattr(result, use), dtype=float)
    if values.ndim != 1:
        raise ValueError(f"expected 1D array, got shape {values.shape}")
    names = list(feature_names)
    if values.shape[0] != len(names):
        raise ValueError(
            f"shape mismatch: values has {values.shape[0]} entries, names has {len(names)}"
        )
    return values, names

from_feature_importances_

from_feature_importances_(model: Any, feature_names: Sequence[str]) -> tuple[ndarray, list[str]]

Pull model.feature_importances_ into the canonical (values, names).

Source code in src/concept_graph_xai/adapters/tree_native.py
def from_feature_importances_(
    model: Any,
    feature_names: Sequence[str],
) -> tuple[np.ndarray, list[str]]:
    """Pull ``model.feature_importances_`` into the canonical ``(values, names)``."""

    if not hasattr(model, "feature_importances_"):
        raise AttributeError(f"{type(model).__name__} has no feature_importances_")
    values = np.asarray(model.feature_importances_, dtype=float)
    if values.ndim != 1:
        raise ValueError(f"expected 1D array, got shape {values.shape}")
    names = list(feature_names)
    if values.shape[0] != len(names):
        raise ValueError(
            f"shape mismatch: values has {values.shape[0]} entries, names has {len(names)}"
        )
    return values, names