Skip to content

Evaluation

evaluate_graph

evaluate_graph(
    predicted: TimeSeriesGraph, truth: TruthLike
) -> StructureRecoveryMetrics

Compute structure-recovery metrics for a fitted graph.

Parameters:

Name Type Description Default
predicted TimeSeriesGraph

The :class:TimeSeriesGraph returned by CDANs(...).fit(...) (specifically result.graph).

required
truth TruthLike

The ground-truth structure. Can be either a :class:TimeSeriesGraph (canonical) or a :class:SyntheticDataset (the convenience output of :func:generate_synthetic_cdans).

required

Returns:

Type Description
StructureRecoveryMetrics

Raises:

Type Description
ValueError

If predicted and truth have inconsistent dimensions.

Example

from cdans import CDANs from cdans.utils import generate_synthetic_cdans from cdans.evaluation import evaluate_graph dataset = generate_synthetic_cdans(n_vars=4, n_samples=400, tau_max=2) result = CDANs(tau_max=2).fit(dataset.data) metrics = evaluate_graph(result.graph, dataset) print(metrics.summary()) # doctest: +SKIP

shd

shd(predicted: TimeSeriesGraph, truth: TruthLike) -> int

Total Structural Hamming Distance (lagged + contemporaneous).

Convenience wrapper around the corresponding fields of :func:evaluate_graph.

GraphMetrics dataclass

GraphMetrics(tp: int, fp: int, fn: int)

Edge-level confusion-matrix counts plus derived rates.

Attributes:

Name Type Description
tp int

True positives — edges in both prediction and truth.

fp int

False positives — edges in prediction but not in truth.

fn int

False negatives — edges in truth but not in prediction.

n_truth int

Total number of true edges (tp + fn). Convenience.

n_pred int

Total number of predicted edges (tp + fp). Convenience.

precision property

precision: float

TP / (TP + FP). Returns 0.0 when no edges are predicted.

recall property

recall: float

TP / (TP + FN). Same as :attr:tpr. Returns 0.0 when no true edges exist (i.e. truth is empty).

tpr property

tpr: float

True positive rate; alias for :attr:recall.

fdr property

fdr: float

False discovery rate = FP / (TP + FP) = 1 - precision.

f1 property

f1: float

Harmonic mean of precision and recall. 0.0 when both are zero.

StructureRecoveryMetrics dataclass

StructureRecoveryMetrics(
    lagged: GraphMetrics,
    contemp_skeleton: GraphMetrics,
    contemp_directed: GraphMetrics,
    changing_modules: GraphMetrics,
    shd_lagged: int,
    shd_contemp: int,
)

All metrics for a single graph-vs-truth comparison.

Use :func:evaluate_graph to produce one of these.

Attributes:

Name Type Description
lagged GraphMetrics

:class:GraphMetrics for lagged edges (src, dst, lag).

contemp_skeleton GraphMetrics

:class:GraphMetrics for the contemporaneous skeleton (adjacency only — direction ignored).

contemp_directed GraphMetrics

:class:GraphMetrics for contemporaneous directed edges. An undirected predicted edge counts as neither TP nor FP for a directed truth edge; see also :attr:shd_contemp for a PDAG-aware single number.

changing_modules GraphMetrics

:class:GraphMetrics over the set of changing-module variable indices.

shd_lagged int

Structural Hamming Distance for lagged edges. Equal to the symmetric difference of the two edge sets.

shd_contemp int

PDAG-aware SHD for contemporaneous edges. For each unordered pair (i, j), the state is one of {no edge, i->j, j->i, undirected}; one SHD unit is added per state mismatch.

shd_total int

shd_lagged + shd_contemp. Changing-module disagreements are counted separately and not folded into total SHD.

Notes

Two convenience aggregates are also available as computed properties:

  • :attr:total — pools TP/FP/FN across :attr:lagged, :attr:contemp_directed, and :attr:changing_modules into a single :class:GraphMetrics. Use this when you want one overall TPR/FDR/F1 number per fit (the typical "full TPR/FDR" reported in benchmarks).
  • :attr:total_skeleton — same as total but uses :attr:contemp_skeleton instead of :attr:contemp_directed. More lenient: a contemp edge with the wrong direction still counts.

total property

total: GraphMetrics

Aggregate metrics across all categories at the directed-edge level.

Pools TP/FP/FN counts from :attr:lagged, :attr:contemp_directed, and :attr:changing_modules into a single :class:GraphMetrics. This yields the overall TPR, FDR, precision, recall, and F1 typically reported in causal-discovery papers as a single per-method number.

Use :attr:total_skeleton for the more lenient adjacency-only version that doesn't penalize direction errors.

total_skeleton property

total_skeleton: GraphMetrics

Aggregate metrics at the contemp-skeleton level (more lenient).

Same as :attr:total but uses :attr:contemp_skeleton instead of :attr:contemp_directed, so a contemp edge with the wrong direction (or left undirected) still counts as a true positive as long as the adjacency was found.

Useful for separating "did we find the right structure" from "did we orient it correctly".

summary

summary() -> str

Formatted multi-line summary.