API Reference
- class graph_explain.AttentionExplainer(head_aggregate: str = 'mean', layer_aggregate: str = 'mean', node_aggregate: str = 'sum')[source]
Bases:
ExplanationAlgorithmExplanation based on the attention weights of GAT models.
Captures the attention coefficients (pre-softmax) of each GATConv during a single forward pass and normalizes them with a per-neighbor softmax. Edge importance is the mean of the coefficients across attention heads and GAT layers; node importance aggregates the attention of the incident edges.
- class graph_explain.Counterfactual(mode: str = 'edge', flip_to: int | None = None, max_steps: int = 10, hops: int = 2, eps: float = 0.0, seed: int = 0)[source]
Bases:
ExplanationAlgorithmCounterfactual explanation: minimal perturbation that changes the prediction.
Finds the minimal set of edges (mode=’edge’) or feature coordinates (mode=’feature’) whose removal/re-scaling makes the node’s prediction change class (or reach flip_to). The search is greedy and deterministic: at each step it removes the candidate element that most reduces P(original class); if the class does not change within max_steps steps it returns the current state (prediction unchanged).
The returned importance marks the modified elements (edges 0/1, nodes from their incidence on removed edges, changed features 0/1), with prediction_explanation = logits after the perturbation.
- class graph_explain.DGLAdapter(feat_key: str | None = None, label_key: str | None = None, edge_weight_key: str | None = None)[source]
Bases:
BackendAdapter for dgl.DGLGraph graphs and DGL models.
Data convention: node features live in ndata[‘feat’], labels in ndata[‘label’] and edge weights in edata[‘w’] (‘x’/’weight’ are also accepted). The DGL model must read g.ndata[‘feat’] and g.edata[‘w’] in its forward(graph, feat).
- class graph_explain.DeepLift(eps: float = 1e-07, normalize: bool = False, node_mask_type: str | None = 'attributes')[source]
Bases:
ExplanationAlgorithmDeepLIFT (rescale rule) for GCNs + ReLU + Linear.
It is an additive rule: each input feature receives a contribution (delta) proportional to how much the target-class output changes when moving from a baseline (zero, by default) to the actual instance. The multiplier is propagated backwards layer by layer: exact for linear layers and GCN messages, and with the rescale rule (delta_out / delta_in) for elementwise nonlinearities.
Returns node_importance (absolute contribution per node), edge_importance (contributions through the message passing of each GCNConv, per directed edge) and feature_importance (contribution per feature).
- class graph_explain.Explanation(node_importance: 'Any | None' = None, edge_importance: 'Any | None' = None, feature_importance: 'Any | None' = None, subgraph: 'Any | None' = None, prediction_original: 'Any | None' = None, prediction_explanation: 'Any | None' = None, node_idx: 'int | None' = None, target_class: 'int | None' = None, mask_threshold: 'float' = 0.5, metadata: 'dict' = <factory>)[source]
Bases:
object
- class graph_explain.GNNExplainer(epochs: int = 200, lr: float = 0.01, edge_entropy: float = 0.001, node_entropy: float = 0.001, node_mask_type: str | None = 'attributes', edge_mask_type: str | None = 'object', prints: int = 20, **kwargs)[source]
Bases:
ExplanationAlgorithm
- class graph_explain.GNNGatedLRP(eps: float = 1e-06, normalize: bool = False, node_mask_type: str | None = None)[source]
Bases:
ExplanationAlgorithmGNN-LRP (Layer-wise Relevance Propagation for GNNs).
Propagates the relevance from the target-class logit backwards, layer by layer, redistributing it according to the positive contributions of each neuron (LRP-0 / z+ rules). For each GCNConv the relevance is split into two steps: (a) the linear transform W over the aggregated features and (b) the convolution, attributing relevance to the neighboring nodes/edges in proportion to their contribution to the message-passing step (GCN norm included). Supports GCN architectures (GCNConv + ReLU + Linear).
The resulting relevance is non-negative (positive rules) and is returned as node_importance (sum per node) and edge_importance (per directed edge, aligned with the edge_index indices).
- class graph_explain.GradXInput(baseline: str = 'zero', edge_grads: bool = True, node_mask_type: str | None = 'attributes', **kwargs)[source]
Bases:
ExplanationAlgorithmGradient x Input: attribution as gradient scaled by the activation.
The importance of each feature (and of each edge, if the backend supports edge weights) is the gradient of the target-class logit multiplied by the input-baseline difference (zero baseline by default). Node importance is the sum of abs(grad * Δx) over features.
- class graph_explain.GraphLIME(hops: int = 2, lambda_: float = 1.0, sigma: float | None = None, normalize: bool = True, **kwargs)[source]
Bases:
ExplanationAlgorithmGraphLIME: feature attribution via weighted local regression.
Fits a linear regression (ridge, closed form) over the k-hop neighbors’ features, weighting each neighbor by its similarity to the target node’s feature (Gaussian kernel). The coefficients explain the probability (softmax) of the target class; node importance matches the kernel similarity.
- class graph_explain.GuidedBackprop(fallback_to_gradient: bool = True, **kwargs)[source]
Bases:
ExplanationAlgorithmGuided Backpropagation: gradients guided by the ReLU mask.
During backpropagation the gradient is filtered: it only propagates where the ReLU activation was positive (negative gradients are discarded), highlighting the features that positively contribute to the class. Temporary hooks are registered on the nn.ReLU modules; if the model has none, it falls back to standard gradients (metadata guided=False).
- class graph_explain.IntegratedGradients(steps: int = 50, method: str = 'riemann', edge_grads: bool = True, **kwargs)[source]
Bases:
ExplanationAlgorithm
- class graph_explain.Narrator(llm: Callable[[str], str] | None = None, top_k: int = 5, lang: str = 'es')[source]
Bases:
objectReusable narrator; lets you inject the LLM just once.
- class graph_explain.NodeMask(epochs: int = 200, lr: float = 0.05, hops: int = 3, suppress_ratio: float = 0.8, entropy: float = 0.05, **kwargs)[source]
Bases:
ExplanationAlgorithmNodeMask: node mask learned by optimization.
Optimizes a (sigmoid) mask over the nodes of the target node’s k-hop subgraph so the model keeps its prediction, with an entropy regularizer to force sparsity. The resulting node importance is re-projected onto the full graph (0 outside the neighborhood).
- class graph_explain.PGExplainer(epochs: int = 100, lr: float = 0.01, hidden: int = 64, temp: float = 1.0, loss_coeff: float = 0.5, entropy_coeff: float = 0.005, batch_nodes: int = 32, **kwargs)[source]
Bases:
ExplanationAlgorithm
- class graph_explain.RandomBaseline(seed: int | None = 0, **kwargs)[source]
Bases:
ExplanationAlgorithmRandom: seed-able uniform random importance baseline.
Assigns random importances in [0, 1] to nodes, edges and features with no link to the model; useful as a null-scenario reference in comparative benchmarks.
- class graph_explain.Saliency(absolute: bool = True, aggregate: str = 'sum', node_mask_type: str | None = None)[source]
Bases:
ExplanationAlgorithm
- class graph_explain.SubgraphX(num_hops: int = 3, rollout: int = 30, high_cpu: bool = False, reward_method: str = 'mi', lambda_connect: float = 0.5, lambda_size: float = 0.05, max_nodes: int = 20, prune: bool = True, seed: int = 0, **kwargs)[source]
Bases:
ExplanationAlgorithm
- graph_explain.compare(data, model, node: int | None = None, target_class: int | None = None, backend: str = 'pyg', methods: list[str] | None = None, top_k: int = 5, num_perturbations: int = 5, noise_std: float = 0.05, epochs: int = 200, lr: float = 0.01, seed: int = 0, mask_threshold: float = 0.5, stability: bool = True) dict[source]
Runs several explanation methods and compares their metrics.
Uses node for node-level (required) or node=None for graph-level (node-only methods are marked skipped). Returns a dictionary with one entry per method: class, predictions, metrics (fidelity±, GEA, sparsity, stability) and the structured summarize summary. Non-applicable methods or failing metrics are marked as skipped/None without aborting the rest.
- graph_explain.describe(explanation, data: Any | None = None, top_k: int = 5, lang: str = 'es') str[source]
Deterministic template-based narration of an explanation.
- Parameters:
lang – Template language,
"es"(default) or"en".
- graph_explain.evaluate_fidelity_minus(model, explanation, top_k: int | None = None, keep_ratio: float = 0.1, kind: str = 'edge') float[source]
Sufficiency: P(c) preserved when keeping ONLY the top-k elements.
- graph_explain.evaluate_fidelity_plus(model, explanation, top_k: int | None = None, keep_ratio: float = 0.1, kind: str = 'edge') float[source]
Necessity: drop in P(c) when removing the top-k important elements.
- graph_explain.evaluate_gea(explanation, data=None, top_k: int | None = None) float[source]
Graph Explanation Accuracy: overlap between the top-k elements of the explanation and the benchmark’s relevant ground-truth subgraph.
- graph_explain.evaluate_gea_graph(explanation, data=None, gt_edge_ids: list[int] | None = None, top_k: int | None = None) float[source]
Graph Explanation Accuracy (graph-level): overlap of the explanation’s top-k edges with the dataset’s known motif edges (gt_edge_mask) of the explained graph.
- graph_explain.evaluate_stability(get_explanation, data, num_perturbations: int = 10, perturbation: str = 'feature', noise_std: float = 0.05, num_edges: int | None = None, top_k: int | None = None, seed: int = 0) float[source]
Stability: mean similarity between explanations under small graph perturbations. get_explanation receives a Data and returns an Explanation.
- graph_explain.narrate(explanation, llm: Callable[[str], str] | None = None, data: Any | None = None, top_k: int = 5, lang: str = 'es') str[source]
Narrates an explanation. With llm (a prompt -> text callable) it uses the generative model’s output; otherwise it falls back to deterministic template-based narration.
- graph_explain.report_html(results: dict, output_path: str) None[source]
Builds a self-contained HTML report (comparative table).
- graph_explain.summarize(explanation, data: Any | None = None, top_k: int = 5) dict[str, Any][source]
Structured summary of an explanation (for narration or JSON).
Core
- class graph_explain.core.explainer.Explainer(algorithm: ExplanationAlgorithm, backend: Backend | str = 'pyg', node_mask_type: str | None = 'attributes', edge_mask_type: str | None = 'object', mask_threshold: float = 0.5, explanation_type: str = 'model', **kwargs)[source]
Bases:
object- explain(data: Any, model: Any, index: int | list[int] | Tensor | None = None, target_class: int | None = None, **kwargs) Explanation[source]
- class graph_explain.core.explanation.Explanation(node_importance: 'Any | None' = None, edge_importance: 'Any | None' = None, feature_importance: 'Any | None' = None, subgraph: 'Any | None' = None, prediction_original: 'Any | None' = None, prediction_explanation: 'Any | None' = None, node_idx: 'int | None' = None, target_class: 'int | None' = None, mask_threshold: 'float' = 0.5, metadata: 'dict' = <factory>)[source]
Bases:
object
Metrics
- graph_explain.core.evaluation.evaluate_fidelity_plus(model, explanation, top_k: int | None = None, keep_ratio: float = 0.1, kind: str = 'edge') float[source]
Necessity: drop in P(c) when removing the top-k important elements.
- graph_explain.core.evaluation.evaluate_fidelity_minus(model, explanation, top_k: int | None = None, keep_ratio: float = 0.1, kind: str = 'edge') float[source]
Sufficiency: P(c) preserved when keeping ONLY the top-k elements.
- graph_explain.core.evaluation.evaluate_stability(get_explanation, data, num_perturbations: int = 10, perturbation: str = 'feature', noise_std: float = 0.05, num_edges: int | None = None, top_k: int | None = None, seed: int = 0) float[source]
Stability: mean similarity between explanations under small graph perturbations. get_explanation receives a Data and returns an Explanation.
- graph_explain.core.evaluation.evaluate_gea(explanation, data=None, top_k: int | None = None) float[source]
Graph Explanation Accuracy: overlap between the top-k elements of the explanation and the benchmark’s relevant ground-truth subgraph.
- graph_explain.core.evaluation.evaluate_fidelity(explanation, keep_ratio: float = 0.2) float[source]
- graph_explain.core.evaluation.evaluate_sparsity(explanation, local: bool = False, local_hops: int = 3) float[source]
- graph_explain.core.evaluation.evaluate_gea_graph(explanation, data=None, gt_edge_ids: list[int] | None = None, top_k: int | None = None) float[source]
Graph Explanation Accuracy (graph-level): overlap of the explanation’s top-k edges with the dataset’s known motif edges (gt_edge_mask) of the explained graph.
Comparative benchmark
- graph_explain.core.benchmark.compare(data, model, node: int | None = None, target_class: int | None = None, backend: str = 'pyg', methods: list[str] | None = None, top_k: int = 5, num_perturbations: int = 5, noise_std: float = 0.05, epochs: int = 200, lr: float = 0.01, seed: int = 0, mask_threshold: float = 0.5, stability: bool = True) dict[source]
Runs several explanation methods and compares their metrics.
Uses node for node-level (required) or node=None for graph-level (node-only methods are marked skipped). Returns a dictionary with one entry per method: class, predictions, metrics (fidelity±, GEA, sparsity, stability) and the structured summarize summary. Non-applicable methods or failing metrics are marked as skipped/None without aborting the rest.
Backends
Methods
- class graph_explain.methods.perturbation.gnn_explainer.GNNExplainer(epochs: int = 200, lr: float = 0.01, edge_entropy: float = 0.001, node_entropy: float = 0.001, node_mask_type: str | None = 'attributes', edge_mask_type: str | None = 'object', prints: int = 20, **kwargs)[source]
Bases:
ExplanationAlgorithm
- class graph_explain.methods.perturbation.pg_explainer.PGExplainer(epochs: int = 100, lr: float = 0.01, hidden: int = 64, temp: float = 1.0, loss_coeff: float = 0.5, entropy_coeff: float = 0.005, batch_nodes: int = 32, **kwargs)[source]
Bases:
ExplanationAlgorithm
- class graph_explain.methods.perturbation.subgraphx.SubgraphX(num_hops: int = 3, rollout: int = 30, high_cpu: bool = False, reward_method: str = 'mi', lambda_connect: float = 0.5, lambda_size: float = 0.05, max_nodes: int = 20, prune: bool = True, seed: int = 0, **kwargs)[source]
Bases:
ExplanationAlgorithm
- class graph_explain.methods.perturbation.node_mask.NodeMask(epochs: int = 200, lr: float = 0.05, hops: int = 3, suppress_ratio: float = 0.8, entropy: float = 0.05, **kwargs)[source]
Bases:
ExplanationAlgorithmNodeMask: node mask learned by optimization.
Optimizes a (sigmoid) mask over the nodes of the target node’s k-hop subgraph so the model keeps its prediction, with an entropy regularizer to force sparsity. The resulting node importance is re-projected onto the full graph (0 outside the neighborhood).
- class graph_explain.methods.gradient.saliency.Saliency(absolute: bool = True, aggregate: str = 'sum', node_mask_type: str | None = None)[source]
Bases:
ExplanationAlgorithm
- class graph_explain.methods.gradient.integrated_gradients.IntegratedGradients(steps: int = 50, method: str = 'riemann', edge_grads: bool = True, **kwargs)[source]
Bases:
ExplanationAlgorithm
- class graph_explain.methods.gradient.grad_x_input.GradXInput(baseline: str = 'zero', edge_grads: bool = True, node_mask_type: str | None = 'attributes', **kwargs)[source]
Bases:
ExplanationAlgorithmGradient x Input: attribution as gradient scaled by the activation.
The importance of each feature (and of each edge, if the backend supports edge weights) is the gradient of the target-class logit multiplied by the input-baseline difference (zero baseline by default). Node importance is the sum of abs(grad * Δx) over features.
- class graph_explain.methods.gradient.guided_backprop.GuidedBackprop(fallback_to_gradient: bool = True, **kwargs)[source]
Bases:
ExplanationAlgorithmGuided Backpropagation: gradients guided by the ReLU mask.
During backpropagation the gradient is filtered: it only propagates where the ReLU activation was positive (negative gradients are discarded), highlighting the features that positively contribute to the class. Temporary hooks are registered on the nn.ReLU modules; if the model has none, it falls back to standard gradients (metadata guided=False).
- class graph_explain.methods.relevance.gnn_lrp.GNNGatedLRP(eps: float = 1e-06, normalize: bool = False, node_mask_type: str | None = None)[source]
Bases:
ExplanationAlgorithmGNN-LRP (Layer-wise Relevance Propagation for GNNs).
Propagates the relevance from the target-class logit backwards, layer by layer, redistributing it according to the positive contributions of each neuron (LRP-0 / z+ rules). For each GCNConv the relevance is split into two steps: (a) the linear transform W over the aggregated features and (b) the convolution, attributing relevance to the neighboring nodes/edges in proportion to their contribution to the message-passing step (GCN norm included). Supports GCN architectures (GCNConv + ReLU + Linear).
The resulting relevance is non-negative (positive rules) and is returned as node_importance (sum per node) and edge_importance (per directed edge, aligned with the edge_index indices).
- class graph_explain.methods.relevance.deeplift.DeepLift(eps: float = 1e-07, normalize: bool = False, node_mask_type: str | None = 'attributes')[source]
Bases:
ExplanationAlgorithmDeepLIFT (rescale rule) for GCNs + ReLU + Linear.
It is an additive rule: each input feature receives a contribution (delta) proportional to how much the target-class output changes when moving from a baseline (zero, by default) to the actual instance. The multiplier is propagated backwards layer by layer: exact for linear layers and GCN messages, and with the rescale rule (delta_out / delta_in) for elementwise nonlinearities.
Returns node_importance (absolute contribution per node), edge_importance (contributions through the message passing of each GCNConv, per directed edge) and feature_importance (contribution per feature).
- class graph_explain.methods.attention.attention.AttentionExplainer(head_aggregate: str = 'mean', layer_aggregate: str = 'mean', node_aggregate: str = 'sum')[source]
Bases:
ExplanationAlgorithmExplanation based on the attention weights of GAT models.
Captures the attention coefficients (pre-softmax) of each GATConv during a single forward pass and normalizes them with a per-neighbor softmax. Edge importance is the mean of the coefficients across attention heads and GAT layers; node importance aggregates the attention of the incident edges.
- class graph_explain.methods.feature.graph_lime.GraphLIME(hops: int = 2, lambda_: float = 1.0, sigma: float | None = None, normalize: bool = True, **kwargs)[source]
Bases:
ExplanationAlgorithmGraphLIME: feature attribution via weighted local regression.
Fits a linear regression (ridge, closed form) over the k-hop neighbors’ features, weighting each neighbor by its similarity to the target node’s feature (Gaussian kernel). The coefficients explain the probability (softmax) of the target class; node importance matches the kernel similarity.
- class graph_explain.methods.baseline.random_baseline.RandomBaseline(seed: int | None = 0, **kwargs)[source]
Bases:
ExplanationAlgorithmRandom: seed-able uniform random importance baseline.
Assigns random importances in [0, 1] to nodes, edges and features with no link to the model; useful as a null-scenario reference in comparative benchmarks.
Synthetic benchmarks
- graph_explain.benchmarks.synthetic.ba_shapes(base_nodes: int = 300, num_houses: int = 80, m: int = 5, seed: int = 0, num_features: int = 10, feature_style: str = 'degree') tuple[Tensor, Tensor, Tensor, Tensor, Tensor, Tensor][source]
- graph_explain.benchmarks.synthetic.build_data(base_nodes: int = 300, num_houses: int = 80, m: int = 5, seed: int = 0, num_features: int = 10, feature_style: str = 'degree')[source]
- graph_explain.benchmarks.synthetic.build_graph_classification(num_pos: int = 20, num_neg: int = 20, base_nodes_range: tuple[int, int] = (15, 30), m: int = 2, seed: int = 0, num_features: int = 8, feature_style: str = 'random')[source]
Graph classification dataset with a known ‘house’ motif.
Returns a list of graph-level Data with a binary label y (1 if the graph contains the house motif). Each graph carries gt_edge_mask (bool over the directed edges, both directions included) and gt_nodes with the motif nodes (+ hub).
Narration
- class graph_explain.narration.Narrator(llm: Callable[[str], str] | None = None, top_k: int = 5, lang: str = 'es')[source]
Bases:
objectReusable narrator; lets you inject the LLM just once.
- graph_explain.narration.describe(explanation, data: Any | None = None, top_k: int = 5, lang: str = 'es') str[source]
Deterministic template-based narration of an explanation.
- Parameters:
lang – Template language,
"es"(default) or"en".
- graph_explain.narration.narrate(explanation, llm: Callable[[str], str] | None = None, data: Any | None = None, top_k: int = 5, lang: str = 'es') str[source]
Narrates an explanation. With llm (a prompt -> text callable) it uses the generative model’s output; otherwise it falls back to deterministic template-based narration.
Visualization
- graph_explain.visualization.show(explanation: Explanation, **kwargs) None[source]
CLI
- graph_explain.cli.build_parser() ArgumentParser[source]