Usage
Usage Example 1: Single Algorithm on a Single Scenario
This example demonstrates how to run a causal discovery algorithm on a single scenario, covering the complete workflow of data generation, algorithm execution, and evaluation.
from causalcompass.datasets.measurement_error import simulate_var_with_measure_error
from causalcompass.algorithms import PCMCI
# Step 1: Generate VAR data with measurement error
p, T, lag, seed = 10, 500, 3, 0
gamma = 1.2 # measurement error scale factor
data, beta, true_adj = simulate_var_with_measure_error(
p=p, T=T, lag=lag, gamma=gamma, seed=seed
)
print(f"Data shape: {data.shape}") # (500, 10)
print(f"Ground truth shape: {true_adj.shape}") # (10, 10)
# Step 2: Initialize and run the algorithm
model = PCMCI(tau_max=3, pc_alpha=0.05, alpha=0.05)
predicted_adj = model.run(data)
# Step 3: Evaluate
all_metrics, no_diag_metrics = model.eval(
true_adj,
predicted_adj,
shd_thresholds=[0, 0.01, 0.05, 0.1, 0.3],
)
print(f"AUROC: {all_metrics['auroc']:.3f}")
print(f"AUPRC: {all_metrics['auprc']:.3f}")
print(f"NSHD: {all_metrics['shd']:.3f}") # shd stores normalized SHD (NSHD)
print(f"AUROC (no diag): {no_diag_metrics['auroc']:.3f}")
print(f"AUPRC (no diag): {no_diag_metrics['auprc']:.3f}")
print(f"NSHD (no diag): {no_diag_metrics['shd']:.3f}") # shd stores normalized SHD (NSHD)
Usage Example 2: All Algorithms on a Single Scenario
This example benchmarks all 11 TSCD algorithms under the measurement error scenario.
import torch
from causalcompass.datasets.measurement_error import simulate_var_with_measure_error
from causalcompass.algorithms import (
PCMCI, DyNotears, CMLP, CLSTM,
VARLiNGAM, CUTS, CUTSPlus, NTSNotears,
LGC, VAR, TSCI
)
# Generate measurement error data
p, T, lag, seed = 10, 500, 3, 0
gamma = 1.2
data, beta, true_adj = simulate_var_with_measure_error(
p=p, T=T, lag=lag, gamma=gamma, seed=seed
)
device = 'cuda' if torch.cuda.is_available() else 'cpu'
# Define all 11 algorithms with their parameters
algorithms = [
('PCMCI', PCMCI, {'tau_max': 3, 'pc_alpha': 0.05, 'alpha': 0.05}),
('VARLiNGAM', VARLiNGAM, {'tau_max': 3, 'varlingamalpha': 0.01}),
('DyNotears', DyNotears, {'tau_max': 3, 'wthre': 0.01, 'lambda_w': 0.1, 'lambda_a': 0.1}),
('NTSNotears', NTSNotears, {'tau_max': 3, 'wthre': 0.01, 'lambda_1': 0.001, 'lambda_2': 0.01, 'device': device}),
('TSCI', TSCI, {'theta': 0.5, 'fnn_tol': 0.01}),
('VAR', VAR, {'tau_max': 3, 'threshold': 0.01}),
('LGC', LGC, {'tau_max': 3, 'threshold': 0.01, 'lgc_alphas': [1e-4, 5e-3, 1e-2, 2e-2, 5e-2]}),
('cMLP', CMLP, {'lag': 3, 'hidden_dim': [100], 'lam': 0.005, 'lr': 0.01, 'max_iter': 50000, 'device': device}),
('cLSTM', CLSTM, {'context': 10, 'hidden_dim': 100, 'lam': 0.005, 'lr': 0.01, 'max_iter': 20000, 'device': device}),
('CUTS', CUTS, {'input_step': 10, 'batch_size': 32, 'weight_decay': 0.001, 'device': device}),
('CUTSPlus', CUTSPlus, {'input_step': 10, 'batch_size': 32, 'weight_decay': 0.001, 'device': device}),
]
# Run and evaluate each algorithm
for name, cls, params in algorithms:
model = cls(seed=seed, **params)
# CUTS and CUTSPlus require the true causal matrix in run()
if name in ['CUTS', 'CUTSPlus']:
predicted_adj = model.run(data, true_cm=true_adj)
else:
predicted_adj = model.run(data)
all_metrics, no_diag_metrics = model.eval(true_adj, predicted_adj)
print(f"[{name}] AUROC={all_metrics['auroc']:.3f}, AUPRC={all_metrics['auprc']:.3f}, NSHD={all_metrics['shd']:.3f} | "
f"No-Diag AUROC={no_diag_metrics['auroc']:.3f}, AUPRC={no_diag_metrics['auprc']:.3f}, NSHD={no_diag_metrics['shd']:.3f}") # shd stores normalized SHD (NSHD)