Skip to content

ConceptGraph

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 feature node; every internal node is a concept.
  • Every feature node is a leaf.
  • Node names are unique across the graph.
Source code in src/concept_graph_xai/graph.py
def __init__(self, graph: nx.DiGraph, root: str) -> None:
    self._graph = graph
    self._root = root
    self._validate()
    self._order: list[str] = list(nx.dfs_preorder_nodes(self._graph, source=self._root))
    self._path_cache: dict[str, tuple[str, ...]] = {}

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
def nodes_in_order(self) -> list[str]:
    """Deterministic depth-first preorder list of node names."""

    return list(self._order)

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
@classmethod
def from_dict(
    cls,
    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.
    """

    if root is not None:
        payload = data
    else:
        if len(data) != 1:
            raise ValueError(
                "from_dict requires either a single top-level key or an explicit root="
            )
        root = next(iter(data))
        payload = {root: data[root]}

    graph = nx.DiGraph()
    graph.add_node(root, kind="concept", metadata={})
    cls._build_subtree(graph, root, payload[root])
    return cls(graph, root)

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
@classmethod
def from_networkx(cls, graph: nx.DiGraph, root: str) -> ConceptGraph:
    """Wrap an existing NetworkX DiGraph (must already have ``kind`` attrs)."""

    return cls(graph.copy(), root)

NodeView

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.