API reference¶
Auto-generated from source-code docstrings via
mkdocstrings. Metric functions return a tidy
pandas.DataFrame indexed by the concept's /-joined path; plot functions return a
plotly.graph_objects.Figure.
ConceptGraph¶
The tree-shaped concept graph. Constructors from dict / YAML / NetworkX; deterministic DFS traversal.
ConceptGraph
¶
ConceptGraph(graph: DiGraph, root: str)
Tree of business concepts with feature leaves.
Internally backed by a networkx.DiGraph where edges point from parent to
child. Every node carries the attributes kind and metadata.
Invariants enforced at construction:
- Exactly one root (a concept node with no parent).
- Every leaf is a
featurenode; every internal node is aconcept. - Every feature node is a leaf.
- Node names are unique across the graph.
Source code in src/concept_graph_xai/graph.py
44 45 46 47 48 49 | |
graph
property
¶
graph: DiGraph
Return a snapshot copy of the underlying NetworkX DiGraph.
The copy preserves all node attributes (kind, metadata) and
edges, but mutations to the returned object never reach back into
the ConceptGraph — preventing accidental cache / order corruption.
nodes_in_order
¶
nodes_in_order() -> list[str]
Deterministic depth-first preorder list of node names.
Source code in src/concept_graph_xai/graph.py
75 76 77 78 | |
from_dict
classmethod
¶
from_dict(data: Mapping[str, Any] | Mapping[str, list[str] | Mapping[str, Any]], *, root: str | None = None) -> ConceptGraph
Build a ConceptGraph from a nested-dict representation.
data is a mapping with exactly one top-level key (the root concept)
whose value describes the tree:
- a list of strings: a concept whose children are all features;
- a mapping
name -> subtree: a concept whose children are concepts (recursive) or, when the leaf value is a list, features.
Source code in src/concept_graph_xai/graph.py
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | |
from_networkx
classmethod
¶
from_networkx(graph: DiGraph, root: str) -> ConceptGraph
Wrap an existing NetworkX DiGraph (must already have kind attrs).
Source code in src/concept_graph_xai/graph.py
172 173 174 175 176 | |
NodeView
dataclass
¶
NodeView(name: str, kind: NodeKind, parent: str | None, path: tuple[str, ...], metadata: Mapping[str, Any])
Read-only view of a single node in the graph.
IO¶
YAML load/dump for the nested-dict graph format — the plumbing behind
ConceptGraph.from_yaml / ConceptGraph.to_yaml.
load_yaml
¶
load_yaml(path: str | Path) -> dict[str, Any]
Load a nested-dict ConceptGraph definition from a YAML file.
Source code in src/concept_graph_xai/io/yaml.py
11 12 13 14 15 16 17 18 | |
dump_yaml
¶
dump_yaml(data: dict[str, Any], path: str | Path) -> None
Dump a nested-dict ConceptGraph definition to YAML.
Source code in src/concept_graph_xai/io/yaml.py
21 22 23 24 25 | |
Adapters¶
Convert SHAP, sklearn permutation results, and model.feature_importances_ into the
canonical (values, feature_names) tuple.
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
TYPE:
|
feature_names
|
Required only when
TYPE:
|
class_index
|
For multi-class explanations (3D
TYPE:
|
Source code in src/concept_graph_xai/adapters/shap.py
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | |
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
TYPE:
|
feature_names
|
Names matching the order of features used during the permutation run.
TYPE:
|
use
|
Which attribute on the Bunch to expose. Defaults to
TYPE:
|
Source code in src/concept_graph_xai/adapters/sklearn_perm.py
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | |
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
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
Counts¶
How many features live under each concept?
feature_counts
¶
feature_counts(graph: ConceptGraph) -> DataFrame
Return a tidy DataFrame with one row per node and a count column.
For a feature node, count = 1. For a concept node, count is the
number of feature descendants of that concept.
Source code in src/concept_graph_xai/metrics/counts.py
11 12 13 14 15 16 17 18 19 20 21 | |
Importance¶
How much importance does each concept aggregate?
importance_sum
¶
importance_sum(graph: ConceptGraph, feature_names: Sequence[str], importances: ndarray, *, signed: bool = False, agg: str = 'mean', on_unknown: str = 'warn') -> DataFrame
Sum per-feature importance under each concept.
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
ConceptGraph whose features are a subset of
TYPE:
|
feature_names
|
Names matching the columns of
TYPE:
|
importances
|
TYPE:
|
signed
|
Pass-through to :func:
TYPE:
|
agg
|
Pass-through to :func:
TYPE:
|
on_unknown
|
Behaviour when input features are missing from the graph:
TYPE:
|
Source code in src/concept_graph_xai/metrics/importance.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | |
Bootstrap¶
Percentile confidence intervals on per-concept importance — is the ranking statistically separable?
bootstrap_importance
¶
bootstrap_importance(graph: ConceptGraph, feature_names: Sequence[str], shap_values: ndarray, *, n_bootstrap: int = 200, ci: float = 0.95, random_state: int | None = None, agg: BootstrapAgg = 'mean_signed', on_unknown: str = 'warn') -> DataFrame
Bootstrap-resampled per-concept SHAP with percentile CI.
For each concept, the per-sample value is the sum of SHAP across the
concept's descendant features. The statistic is the mean of those
per-sample values across the held-out set. The bootstrap resamples row
indices with replacement n_bootstrap times and reports the mean
plus percentile confidence-interval bounds.
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
The ConceptGraph.
TYPE:
|
feature_names
|
Names matching the columns of
TYPE:
|
shap_values
|
Per-sample SHAP values of shape
TYPE:
|
n_bootstrap
|
Number of resamples (default 200).
TYPE:
|
ci
|
Confidence level in
TYPE:
|
random_state
|
Seed for the resampler.
TYPE:
|
agg
|
TYPE:
|
on_unknown
|
Behaviour when
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
DataFrame
|
Indexed by concept-path with columns |
Source code in src/concept_graph_xai/metrics/bootstrap.py
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | |
Utilization¶
Which concepts does the model actually use?
utilization
¶
utilization(graph: ConceptGraph, feature_names: Sequence[str], importances: ndarray, *, threshold: float = 0.0, signed: bool = False, agg: str = 'mean', on_unknown: str = 'warn') -> DataFrame
Mark each node is_used when its aggregated importance exceeds threshold.
A feature node is used iff abs(importance) > threshold (when
signed=False). A concept node is used iff any of its feature
descendants is used.
Returned DataFrame columns: name, kind, depth, parent,
importance_sum, feature_count, used_feature_count, is_used.
Source code in src/concept_graph_xai/metrics/utilization.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | |
Interaction¶
Concept × concept aggregation of the feature-level SHAP-interaction tensor.
concept_interaction_matrix
¶
concept_interaction_matrix(graph: ConceptGraph, feature_names: Sequence[str], shap_interaction_values: ndarray, *, only_concepts: bool = True, include_root: bool = False, agg: InteractionAgg = 'mean_abs', on_unknown: str = 'warn') -> DataFrame
Aggregate a per-sample feature × feature interaction tensor into concept × concept.
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
ConceptGraph.
TYPE:
|
feature_names
|
Names matching the second/third dimensions of
TYPE:
|
shap_interaction_values
|
Tensor of shape
TYPE:
|
only_concepts
|
If
TYPE:
|
include_root
|
If
TYPE:
|
agg
|
TYPE:
|
on_unknown
|
Behaviour when
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
DataFrame
|
Square DataFrame, rows and columns are concept names. |
Source code in src/concept_graph_xai/metrics/interaction.py
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | |
Ablation¶
How much performance is lost when a concept's data is missing? Three strategies.
auc_drop
¶
auc_drop(graph: ConceptGraph, model: Any, X: DataFrame | ndarray, y: ndarray | Series, feature_names: Sequence[str] | None = None, *, strategy: Strategy = 'permutation', metric: ScorerLike = 'roc_auc', n_repeats: int = 10, random_state: int | None = 42, train_fn: Callable[[DataFrame | ndarray, ndarray], Any] | None = None, X_train: DataFrame | ndarray | None = None, y_train: ndarray | Series | None = None, shap_values: ndarray | None = None, base_predictions: ndarray | None = None, skip_root: bool = True) -> DataFrame
Compute concept-level metric drop under ablation.
Source code in src/concept_graph_xai/metrics/ablation.py
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | |
Correlation¶
Are concepts internally coherent? Do they go missing together? Do features look substitutable to the model?
CorrelationResult
dataclass
¶
CorrelationResult(matrix: DataFrame, blocks: list[tuple[str, int, int]], block_stats: DataFrame, method: CorrelationMethod)
Output of every correlation metric in this module.
matrix
instance-attribute
¶
matrix: DataFrame
Square DataFrame indexed/columned by feature name in graph order.
blocks
instance-attribute
¶
blocks: list[tuple[str, int, int]]
[(concept_path, start_idx, end_idx_exclusive), ...] over rows/cols.
block_stats
instance-attribute
¶
block_stats: DataFrame
One row per block. Columns: concept_path, size, mean_abs,
median_abs, min, max.
feature_correlation
¶
feature_correlation(graph: ConceptGraph, X: DataFrame | ndarray, *, feature_names: Sequence[str] | None = None, method: CorrelationMethod = 'spearman') -> CorrelationResult
Block-structured correlation matrix on feature values (P14).
Diagonal blocks reveal within-concept coherence; off-diagonal blocks reveal boundary leakage (features in different concepts that turn out to be highly correlated).
Accepts either a pd.DataFrame (column names taken from
X.columns) or an np.ndarray of shape (N, F) (column names
must be supplied via feature_names).
Source code in src/concept_graph_xai/metrics/correlation.py
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | |
nullity_correlation
¶
nullity_correlation(graph: ConceptGraph, X: DataFrame, *, method: CorrelationMethod = 'spearman') -> CorrelationResult
Block-structured correlation matrix on feature missingness (P15a).
Built on X.isna(). A high diagonal-block value means the features in
that concept tend to go missing together — directly relevant to the AUC
drop "this branch is missing" scenario.
Source code in src/concept_graph_xai/metrics/correlation.py
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | |
shap_correlation
¶
shap_correlation(graph: ConceptGraph, feature_names: Sequence[str], shap_values: ndarray, *, method: CorrelationMethod = 'spearman') -> CorrelationResult
Block-structured correlation of SHAP values across samples (P17).
Two raw-uncorrelated features can still be SHAP-redundant: diagonal blocks near 1 indicate features inside a concept push the model in the same way; off-diagonal blocks near 1 indicate the model treats different concepts as substitutes.
Source code in src/concept_graph_xai/metrics/correlation.py
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | |
Missingness¶
How often does a feature / a whole concept go missing?
column_missing_rate
¶
column_missing_rate(graph: ConceptGraph, X: DataFrame) -> DataFrame
Mean per-feature missing rate, plus a concept-level any-missing mean.
For a concept node, any_missing_rate is mean(any feature under the
concept is NaN in row) — much weaker than :func:joint_missing_rate,
but useful as an upper bound.
Source code in src/concept_graph_xai/metrics/missingness.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | |
joint_missing_rate
¶
joint_missing_rate(graph: ConceptGraph, X: DataFrame) -> DataFrame
Per-concept joint-missing rate (P13/P15b).
For each concept (and each feature, trivially), the fraction of rows where every feature under that concept is NaN. This is the number that should drive the "is the AUC-drop scenario realistic?" judgement.
Returned columns: name, kind, depth, parent, feature_count,
joint_missing_rate.
Source code in src/concept_graph_xai/metrics/missingness.py
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | |
Coherence¶
Are concepts well-designed (coherent + important)?
coherence_importance
¶
coherence_importance(graph: ConceptGraph, X: DataFrame, feature_names: Sequence[str], importances: ndarray, *, method: CorrelationMethod = 'spearman', coherence_threshold: float | None = None, importance_threshold: float | None = None) -> DataFrame
Per-concept coherence × importance table.
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
ConceptGraph.
TYPE:
|
X
|
Feature matrix used to compute within-block correlation.
TYPE:
|
feature_names
|
Inputs to :func:
TYPE:
|
importances
|
Inputs to :func:
TYPE:
|
method
|
Correlation method passed to :func:
TYPE:
|
coherence_threshold
|
Quadrant boundary on the coherence axis. Defaults to the median across concepts.
TYPE:
|
importance_threshold
|
Quadrant boundary on the importance axis. Defaults to the median across concepts.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
DataFrame
|
One row per concept (root included). Columns include |
Source code in src/concept_graph_xai/metrics/coherence.py
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | |
Segments¶
Per-segment per-concept SHAP aggregation for cohort analysis.
segment_importance
¶
segment_importance(graph: ConceptGraph, feature_names: Sequence[str], shap_values: ndarray, segments: Series | str, *, X: DataFrame | None = None, agg: SegmentAgg = 'mean_abs', on_unknown: str = 'warn') -> DataFrame
Per-segment per-concept SHAP aggregate (long-form).
For each (concept, segment) pair, computes mean_n agg(s_c[n])
over the rows belonging to segment, where s_c[n] = sum_{f in
concept.descendants} SHAP[n, f].
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
The ConceptGraph.
TYPE:
|
feature_names
|
Names matching the columns of
TYPE:
|
shap_values
|
Per-sample SHAP, shape
TYPE:
|
segments
|
Either a
TYPE:
|
X
|
DataFrame whose row order matches
TYPE:
|
agg
|
TYPE:
|
on_unknown
|
Behaviour when
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
DataFrame
|
Long-form with columns |
Source code in src/concept_graph_xai/metrics/segment.py
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | |
Disparity¶
Per-concept SHAP gap of each protected group against a reference group.
concept_disparity
¶
concept_disparity(graph: ConceptGraph, feature_names: Sequence[str], shap_values: ndarray, protected: Series | str, *, reference: str, X: DataFrame | None = None, agg: DisparityAgg = 'mean_abs', on_unknown: str = 'warn') -> DataFrame
Per-concept additive SHAP gap vs a reference protected group.
For each (concept, group) pair, computes
mean_n agg(s_c[n]) over rows in group minus the same quantity for
reference. The reference group's row exists in the output with
value=0 for every concept.
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
The ConceptGraph.
TYPE:
|
feature_names
|
Names matching the columns of
TYPE:
|
shap_values
|
Per-sample SHAP, shape
TYPE:
|
protected
|
Either a
TYPE:
|
reference
|
Label of the baseline group. Must appear in the resolved protected-attribute values.
TYPE:
|
X
|
DataFrame whose row order matches
TYPE:
|
agg
|
TYPE:
|
on_unknown
|
Behaviour when
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
DataFrame
|
Long-form with columns |
Source code in src/concept_graph_xai/metrics/disparity.py
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | |
Drift¶
Per-period concept SHAP aggregation for drift monitoring: a long-form per-period table and a two-period delta table.
attribution_drift
¶
attribution_drift(graph: ConceptGraph, periods: Sequence[PeriodSpec], *, agg: DriftAgg = 'mean_abs', on_unknown: str = 'warn') -> DataFrame
Per-period per-concept SHAP aggregate (long-form).
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
The ConceptGraph.
TYPE:
|
periods
|
Ordered list of
TYPE:
|
agg
|
TYPE:
|
on_unknown
|
Behaviour when
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
DataFrame
|
Long-form with columns |
Source code in src/concept_graph_xai/metrics/drift.py
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | |
concept_drift_delta
¶
concept_drift_delta(graph: ConceptGraph, periods: Sequence[PeriodSpec], *, baseline: str | None = None, target: str | None = None, agg: DriftAgg = 'mean_abs', on_unknown: str = 'warn') -> DataFrame
Per-concept baseline / target / delta between two periods.
Convenience wrapper around :func:attribution_drift for the
two-period delta view consumed by :func:concept_drift_sunburst.
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
The ConceptGraph.
TYPE:
|
periods
|
Same as :func:
TYPE:
|
baseline
|
Period label to treat as the reference. Defaults to the first period.
TYPE:
|
target
|
Period label to compare against. Defaults to the last period.
TYPE:
|
agg
|
Aggregation passed through to :func:
TYPE:
|
on_unknown
|
Pass-through.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
DataFrame
|
Indexed by concept path, columns |
Source code in src/concept_graph_xai/metrics/drift.py
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | |
Plotting¶
All plots return plotly.graph_objects.Figure. Static PNG via the [png] extra
(kaleido).
sunburst
¶
sunburst(graph: ConceptGraph, df: DataFrame, *, value: str = 'count', title: str | None = None, colorscale: str | None = None, color_value: str | None = None, color_by: ColorBy = 'auto', branch_palette: Sequence[str] | None = None, hide_root: bool = True, branchvalues: str = 'total', extra_hover: list[str] | None = None, hover_fmt: dict[str, str] | None = None, layout_kwargs: dict[str, Any] | None = None) -> Figure
Render a sunburst from a ConceptGraph + a metric DataFrame.
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
The ConceptGraph to render.
TYPE:
|
df
|
Tidy DataFrame produced by one of the metric functions. Must be
indexed by
TYPE:
|
value
|
Column used for sector size. Defaults to
TYPE:
|
title
|
Figure title.
TYPE:
|
colorscale
|
Plotly colorscale name (e.g.
TYPE:
|
color_value
|
Column used for color intensity. Defaults to
TYPE:
|
color_by
|
How to colour sectors.
TYPE:
|
branch_palette
|
CSS color sequence used when colouring by branch. Defaults to the Plotly qualitative palette.
TYPE:
|
hide_root
|
When
TYPE:
|
branchvalues
|
Plotly sunburst branchvalues (
TYPE:
|
extra_hover
|
Additional columns to append to the hover tooltip.
TYPE:
|
hover_fmt
|
Per-column
TYPE:
|
layout_kwargs
|
Passed verbatim to
TYPE:
|
Source code in src/concept_graph_xai/plotting/sunburst.py
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | |
utilization_map
¶
utilization_map(graph: ConceptGraph, df: DataFrame, *, value: str = 'feature_count', used_color: str | None = None, unused_color: str = '#d3d3d3', branch_palette: Sequence[str] | None = None, hide_root: bool = True, title: str | None = None, layout_kwargs: dict[str, Any] | None = None) -> Figure
Render a sunburst where unused branches are grey.
The DataFrame must be the output of
:func:concept_graph_xai.metrics.utilization (it requires the is_used
column). By default sector area encodes feature_count and colour
encodes both branch identity (hue) and is-used status (grey when not used)
— the chart subsumes the standalone sunburst(..., feature_counts(...))
structural view.
| PARAMETER | DESCRIPTION |
|---|---|
used_color
|
If
TYPE:
|
branch_palette
|
Custom palette for branch base hues. Defaults to the Plotly qualitative palette.
TYPE:
|
hide_root
|
When
TYPE:
|
Source code in src/concept_graph_xai/plotting/utilization_map.py
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | |
signed_concept_bar
¶
signed_concept_bar(graph: ConceptGraph, df: DataFrame, *, only_concepts: bool = True, sort: bool = True, max_concepts: int | None = None, value: str | None = None, branch_palette: Sequence[str] | None = None, title: str | None = None, layout_kwargs: dict[str, Any] | None = None) -> Figure
Render a horizontal bar chart of per-concept signed SHAP with CI bars.
The DataFrame must come from :func:bootstrap_importance (it requires
ci_lo / ci_hi columns and one of mean_signed_shap /
mean_abs_shap).
| PARAMETER | DESCRIPTION |
|---|---|
only_concepts
|
If
TYPE:
|
sort
|
If
TYPE:
|
max_concepts
|
Optionally cap the number of bars (top-K by
TYPE:
|
value
|
Override the column carrying the bar value. Defaults to whichever of
TYPE:
|
branch_palette
|
Custom palette for branch base hues. Defaults to the Plotly qualitative palette.
TYPE:
|
title
|
Figure title.
TYPE:
|
layout_kwargs
|
Passed verbatim to
TYPE:
|
Source code in src/concept_graph_xai/plotting/signed_concept_bar.py
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | |
concept_interaction_heatmap
¶
concept_interaction_heatmap(matrix: DataFrame, *, title: str | None = None, show_diagonal_box: bool = True, annotate_top_k: int | None = 5, colorscale: str | None = None, layout_kwargs: dict[str, Any] | None = None) -> Figure
Render a concept × concept SHAP-interaction heatmap.
| PARAMETER | DESCRIPTION |
|---|---|
matrix
|
Square DataFrame returned by :func:
TYPE:
|
title
|
Figure title.
TYPE:
|
show_diagonal_box
|
If
TYPE:
|
annotate_top_k
|
Annotate the largest
TYPE:
|
colorscale
|
Override the colorscale. Defaults to
TYPE:
|
layout_kwargs
|
Passed verbatim to
TYPE:
|
Source code in src/concept_graph_xai/plotting/concept_interaction_heatmap.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | |
concept_sankey
¶
concept_sankey(graph: ConceptGraph, feature_names: Sequence[str], shap_values: ndarray, *, max_features_per_concept: int | None = None, branch_palette: Sequence[str] | None = None, positive_color: str = '#2ca02c', negative_color: str = '#d62728', title: str | None = None, layout_kwargs: dict[str, Any] | None = None) -> Figure
Render a SHAP-flow Sankey that walks the full concept hierarchy.
Tiers (left → right):
- Features — one node per included feature.
- Concept tiers — one node per concept on any included feature's
path (excluding the hidden root). For deep trees this produces
multiple intermediate tiers (e.g.
feature → sub-concept → top-level concept). - Outcome — two nodes (+, −).
Link weights:
feature → direct-parent:sum_n |SHAP[n, f]|— total magnitude carried by the feature.concept → its parent concept:sum_n |s_c[n]|wheres_c[n] = sum_{f in c.descendants} SHAP[n, f]. This is the signed sum's magnitude, so within-concept cancellation narrows the band as you move right.top-level concept → +:sum_n max(0, s_t[n]).top-level concept → −:sum_n max(0, -s_t[n]).
Conservation is intentionally relaxed: at each concept node, total incoming flow ≥ outgoing flow whenever descendants' SHAP cancel within the concept. The shrinkage from left to right is the diagnostic — it tells you which concepts wash out under aggregation.
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
The ConceptGraph.
TYPE:
|
feature_names
|
Names matching the columns of
TYPE:
|
shap_values
|
Per-sample SHAP, shape
TYPE:
|
max_features_per_concept
|
Optional cap: per top-level concept, keep only the top-K
descendant features by
TYPE:
|
branch_palette
|
Custom palette for branch base hues.
TYPE:
|
positive_color
|
Colours for the
TYPE:
|
negative_color
|
Colours for the
TYPE:
|
title
|
Figure title.
TYPE:
|
layout_kwargs
|
Passed verbatim to
TYPE:
|
Source code in src/concept_graph_xai/plotting/concept_sankey.py
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 | |
concept_violin
¶
concept_violin(graph: ConceptGraph, feature_names: Sequence[str], shap_values: ndarray, *, only_concepts: bool = True, sort_by_importance: bool = True, max_concepts: int | None = None, title: str | None = None, points: ViolinPoints = 'outliers', box_visible: bool = True, meanline_visible: bool = True, branch_palette: Sequence[str] | None = None, layout_kwargs: dict[str, Any] | None = None) -> Figure
Render a per-concept violin of summed signed SHAP across samples.
Each row is a concept (or feature, if only_concepts=False); the violin
shape is the KDE of the per-sample sum of SHAP across the concept's
descendant features. A central box-and-whiskers and a mean line can be
overlaid via box_visible and meanline_visible.
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
The ConceptGraph.
TYPE:
|
feature_names
|
Names of the features matching the columns of
TYPE:
|
shap_values
|
Per-sample SHAP values of shape
TYPE:
|
only_concepts
|
If True (default), drop feature leaves from the chart.
TYPE:
|
sort_by_importance
|
If True (default), order rows by mean(|summed SHAP|) descending.
TYPE:
|
max_concepts
|
Optionally cap the number of rows shown (top-K by importance).
TYPE:
|
title
|
Figure title.
TYPE:
|
points
|
Which raw points to overlay on the violin.
TYPE:
|
box_visible
|
Draw the box-and-whiskers inside each violin. Default
TYPE:
|
meanline_visible
|
Draw the mean as a dashed line inside each violin. Default
TYPE:
|
branch_palette
|
Custom palette for branch base hues (each violin is tinted by its top-level branch with hierarchical shading). Defaults to the Plotly qualitative palette.
TYPE:
|
layout_kwargs
|
Passed verbatim to
TYPE:
|
Source code in src/concept_graph_xai/plotting/concept_violin.py
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | |
auc_drop_map
¶
auc_drop_map(graph: ConceptGraph, df: DataFrame, *, value: str = 'auc_drop_mean', size: str = 'feature_count', colorscale: str = 'Reds', hide_root: bool = True, title: str | None = None, layout_kwargs: dict[str, Any] | None = None) -> Figure
Render a sunburst where each concept is colored by its AUC drop.
Sector area uses size (feature count by default), the colour intensity
uses value (mean AUC drop by default). Set hide_root=False to
keep the root sector visible.
Source code in src/concept_graph_xai/plotting/auc_drop_map.py
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | |
correlation_block
¶
correlation_block(result: CorrelationResult, *, title: str | None = None, show_block_labels: bool = True, annotate_mean_abs: bool = True, colorscale: str = 'RdBu', zmid: float = 0.0, layout_kwargs: dict[str, Any] | None = None) -> Figure
Render a correlation matrix with concept-block separators.
Works on the output of any of :func:feature_correlation,
:func:nullity_correlation, or :func:shap_correlation — they all return
a :class:CorrelationResult.
| PARAMETER | DESCRIPTION |
|---|---|
result
|
Output of one of the correlation metrics.
TYPE:
|
title
|
Figure title.
TYPE:
|
show_block_labels
|
Draw the concept name above each diagonal block.
TYPE:
|
annotate_mean_abs
|
Print
TYPE:
|
colorscale
|
Plotly colorscale name. Default
TYPE:
|
zmid
|
Mid value for the colorscale. Use
TYPE:
|
layout_kwargs
|
Passed verbatim to
TYPE:
|
Source code in src/concept_graph_xai/plotting/correlation_block.py
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | |
joint_missing_map
¶
joint_missing_map(graph: ConceptGraph, df: DataFrame, *, value: str = 'joint_missing_rate', size: str = 'feature_count', colorscale: str = 'Reds', hide_root: bool = True, title: str | None = None, layout_kwargs: dict[str, Any] | None = None) -> Figure
Render a sunburst where each concept is coloured by its joint-missing rate.
The DataFrame must come from :func:joint_missing_rate. Sector size uses
feature_count so the shape matches the existing sunburst plots; colour
intensity uses joint_missing_rate. Set hide_root=False to keep
the root sector visible.
Source code in src/concept_graph_xai/plotting/joint_missing_map.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | |
coherence_importance_scatter
¶
coherence_importance_scatter(df: DataFrame, *, only_concepts: bool = True, label_points: bool = True, title: str | None = None, layout_kwargs: dict[str, Any] | None = None) -> Figure
Render the coherence × importance quadrant scatter.
| PARAMETER | DESCRIPTION |
|---|---|
df
|
Output of :func:
TYPE:
|
only_concepts
|
Drop rows where
TYPE:
|
label_points
|
Annotate every point with the concept name.
TYPE:
|
Source code in src/concept_graph_xai/plotting/coherence_importance_scatter.py
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | |
regulatory_tag_overlay
¶
regulatory_tag_overlay(graph: ConceptGraph, df: DataFrame | None = None, *, tag_key: str = 'tag', palette: dict[str, str] | None = None, untagged_color: str = '#dddddd', value: str = 'count', hide_root: bool = True, title: str | None = None, layout_kwargs: dict[str, Any] | None = None) -> Figure
Render a sunburst whose sectors are coloured by a node-metadata tag.
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
ConceptGraph; tag is read from
TYPE:
|
df
|
Optional DataFrame providing the
TYPE:
|
tag_key
|
Metadata key carrying the categorical tag.
TYPE:
|
palette
|
Optional
TYPE:
|
untagged_color
|
Colour for nodes that carry no value under
TYPE:
|
hide_root
|
When
TYPE:
|
Source code in src/concept_graph_xai/plotting/regulatory_tag_overlay.py
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | |
segment_concept_heatmap
¶
segment_concept_heatmap(graph: ConceptGraph, df: DataFrame, *, only_concepts: bool = True, hide_root: bool = True, sort_by: str | None = 'max', max_concepts: int | None = None, title: str | None = None, colorscale: str | None = None, layout_kwargs: dict[str, Any] | None = None) -> Figure
Render a concept × segment SHAP heatmap.
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
The ConceptGraph (used for depth-aware ordering).
TYPE:
|
df
|
Long-form output of :func:
TYPE:
|
only_concepts
|
If
TYPE:
|
hide_root
|
If
TYPE:
|
sort_by
|
TYPE:
|
max_concepts
|
Optionally cap the number of rows shown (top-K by chosen ordering).
TYPE:
|
title
|
Figure title.
TYPE:
|
colorscale
|
Override the colorscale. Defaults to
TYPE:
|
layout_kwargs
|
Passed verbatim to
TYPE:
|
Source code in src/concept_graph_xai/plotting/segment_concept_heatmap.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | |
concept_pareto
¶
concept_pareto(graph: ConceptGraph, df: DataFrame, *, only_concepts: bool = True, hide_root: bool = True, segment_palette: Sequence[str] | None = None, show_equality_line: bool = True, title: str | None = None, layout_kwargs: dict[str, Any] | None = None) -> Figure
Render per-segment Lorenz / Pareto curves of concept importance.
For each cohort in the long-form DataFrame from
:func:segment_importance, concepts are sorted by value descending
and accumulated to produce a Lorenz curve:
- x =
(rank + 1) / n_concepts— cumulative share of concepts. - y =
cum_value / total_value— cumulative share of importance.
A curve hugging the dashed 45° equality line means the cohort's importance is spread evenly across concepts; a curve bulging up-left means a few concepts dominate that cohort's SHAP budget.
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
ConceptGraph (used to drop the root row).
TYPE:
|
df
|
Long-form DataFrame from :func:
TYPE:
|
only_concepts
|
If
TYPE:
|
hide_root
|
If
TYPE:
|
segment_palette
|
Custom palette for per-segment colours. Defaults to the Plotly qualitative palette.
TYPE:
|
show_equality_line
|
Overlay the dashed 45° reference line. Default
TYPE:
|
title
|
Figure title.
TYPE:
|
layout_kwargs
|
Passed verbatim to
TYPE:
|
Source code in src/concept_graph_xai/plotting/concept_pareto.py
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | |
concept_disparity_heatmap
¶
concept_disparity_heatmap(graph: ConceptGraph, df: DataFrame, *, only_concepts: bool = True, hide_root: bool = True, include_reference: bool = True, sort_by: SortBy | None = 'max_abs', max_concepts: int | None = None, title: str | None = None, colorscale: str = 'RdBu_r', layout_kwargs: dict[str, Any] | None = None) -> Figure
Render a concept × protected-group disparity heatmap.
Diverging palette centred at 0 — the reference column is exactly zero, other columns are signed gaps. Positive gap = the model relies on this concept more for that group than for the reference; negative = less.
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
The ConceptGraph (used for depth-aware ordering).
TYPE:
|
df
|
Long-form output of :func:
TYPE:
|
only_concepts
|
If
TYPE:
|
hide_root
|
If
TYPE:
|
include_reference
|
If
TYPE:
|
sort_by
|
TYPE:
|
max_concepts
|
Optionally cap the number of rows shown (top-K by chosen ordering).
TYPE:
|
title
|
Figure title. Defaults to
TYPE:
|
colorscale
|
Plotly diverging colorscale name. Default
TYPE:
|
layout_kwargs
|
Passed verbatim to
TYPE:
|
Source code in src/concept_graph_xai/plotting/concept_disparity_heatmap.py
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | |
concept_drift_lines
¶
concept_drift_lines(graph: ConceptGraph, df: DataFrame, *, only_concepts: bool = True, hide_root: bool = True, max_concepts: int | None = None, branch_palette: Sequence[str] | None = None, title: str | None = None, layout_kwargs: dict[str, Any] | None = None) -> Figure
Render one line per concept across periods.
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
The ConceptGraph (used for branch-hierarchical colouring).
TYPE:
|
df
|
Long-form DataFrame from :func:
TYPE:
|
only_concepts
|
If
TYPE:
|
hide_root
|
If
TYPE:
|
max_concepts
|
If set, keep only the K concepts with the highest
max-across-periods value to avoid spaghetti charts. Default
TYPE:
|
branch_palette
|
Custom palette for branch base hues. Defaults to the Plotly qualitative palette.
TYPE:
|
title
|
Figure title.
TYPE:
|
layout_kwargs
|
Passed verbatim to
TYPE:
|
Source code in src/concept_graph_xai/plotting/concept_drift_lines.py
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | |
concept_drift_sunburst
¶
concept_drift_sunburst(graph: ConceptGraph, df: DataFrame, *, value: str = 'feature_count', delta_col: str = 'delta', colorscale: str = 'RdBu_r', hide_root: bool = True, title: str | None = None, layout_kwargs: dict[str, Any] | None = None) -> Figure
Render a sunburst coloured by per-concept SHAP drift.
Sector area uses value (default feature_count — additive, safe
for branchvalues="total"). Sector colour uses delta_col with a
diverging palette centred at 0. With the default RdBu_r colorscale,
positive deltas (importance grew between baseline and target) render
red and negative deltas (importance shrank) render blue.
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
The ConceptGraph.
TYPE:
|
df
|
DataFrame from :func:
TYPE:
|
value
|
Column used for sector area. Default
TYPE:
|
delta_col
|
Column used for sector colour. Default
TYPE:
|
colorscale
|
Plotly diverging colorscale name. Default
TYPE:
|
hide_root
|
Drop the root concept by default (consistent with the other sunburst plots).
TYPE:
|
title
|
Figure title.
TYPE:
|
layout_kwargs
|
Passed verbatim to
TYPE:
|
Source code in src/concept_graph_xai/plotting/concept_drift_sunburst.py
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | |
Prediction explainer¶
Single-prediction explanations rolled up to concept level, headlined by the concept waterfall.
ConceptPredictionExplainer
¶
ConceptPredictionExplainer(graph: ConceptGraph, model: Any, X: DataFrame, shap_values: ndarray, base_value: float, *, feature_names: Sequence[str] | None = None)
Explain a single prediction using the concept tree.
| PARAMETER | DESCRIPTION |
|---|---|
graph
|
The ConceptGraph.
TYPE:
|
model
|
A fitted model. Used only to display the prediction alongside the waterfall; the SHAP values are the source of truth.
TYPE:
|
X
|
The feature matrix the SHAP values were computed on. Must be a DataFrame whose columns include every feature in the graph.
TYPE:
|
shap_values
|
Per-sample SHAP values of shape
TYPE:
|
base_value
|
The SHAP base value (typically
TYPE:
|
feature_names
|
Optional override for
TYPE:
|
Source code in src/concept_graph_xai/prediction_explainer.py
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | |
breakdown
¶
breakdown(row: int | str, *, depth: int = 1) -> DataFrame
Per-concept SHAP sum for a single prediction at the given depth.
| PARAMETER | DESCRIPTION |
|---|---|
row
|
Either a positional index (
TYPE:
|
depth
|
Depth of the concepts to roll up to.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
DataFrame
|
Sorted by |
Source code in src/concept_graph_xai/prediction_explainer.py
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | |
waterfall
¶
waterfall(row: int | str, *, depth: int = 1, title: str | None = None, layout_kwargs: dict[str, Any] | None = None) -> Figure
Render a per-prediction concept waterfall.
The chart starts at base_value, applies each concept's SHAP sum in
descending magnitude, and ends at the predicted logit
(base_value + sum(SHAP)). Bars are coloured red for negative
contributions and green for positive.
| PARAMETER | DESCRIPTION |
|---|---|
row
|
Row index or label.
TYPE:
|
depth
|
Tree depth to roll up to. See :meth:
TYPE:
|
title
|
Figure title.
TYPE:
|
layout_kwargs
|
Passed verbatim to
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Figure
|
|
Source code in src/concept_graph_xai/prediction_explainer.py
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | |
ConceptContribution
dataclass
¶
ConceptContribution(name: str, path: str, depth: int, feature_count: int, shap_sum: float)
One row of the per-concept breakdown for a single prediction.