Friedman 2000 - Closed Form for a Known Ordering
Summary
Given a total ordering , the parent sets of different nodes can be chosen independently, so at cost about . Edge posteriors given the ordering are ratios of restricted sums (Prop. 3.1); Markov-blanket posteriors follow by independence (Prop. 3.2).
Overview
This is the core trick. Without an ordering, choosing as a parent of forbids as a parent of , coupling families through acyclicity; the ordering removes that coupling. The decomposition was first noted by Buntine and was used for averaging by the present paper.
Main Content
Marginal likelihood given an ordering (eq. 5-6)
Let (all members of precede ). Then
Number of allowed families per node is at most , so the cost is at most score evaluations.
Proof sketch. Under , each graph is an independent choice of for every ; by Theorem 2.1 and structure modularity the weight of is , so the sum over the product set factorises.
Feature posteriors given an ordering (Prop. 3.1, eq. 7-8)
Edge: (the other nodes’ terms cancel). Parent set: .
Proposition 3.2 (Markov blanket)
For , , where and (families restricted to contain both); all events are independent given the ordering.
Features like “there is a directed path ” have no closed form; instead sample whole networks given the ordering by drawing each family from eq. 8 and evaluate on the samples.
Examples
Numerical verification of eq. 6 on four variables
Random local scores with , ordering : the product of per-node sums (closed form) equals the brute-force sum over all consistent graphs, 37.5456 both; .
import itertools, numpy as np
rng = np.random.default_rng(0); n, k = 4, 2
score = {i: {frozenset(U): np.exp(rng.normal()) for r in range(k+1)
for U in itertools.combinations([j for j in range(n) if j != i], r)} for i in range(n)}
order = [2, 0, 3, 1]; pos = {v: t for t, v in enumerate(order)}
fam = lambda i: [U for U in score[i] if all(pos[u] < pos[i] for u in U)]
closed = np.prod([sum(score[i][U] for U in fam(i)) for i in range(n)])
brute = sum(np.prod([score[i][U] for i, U in enumerate(G)]) for G in itertools.product(*[fam(i) for i in range(n)]))
print(closed, brute)PyMC connection: E20’s “exact BGe + dynamic programming over all orders” replaces the order-MCMC with exact summation over orderings (feasible for about 10-15 nodes via subset dynamic programming); the per-family scores are the same score terms.
Connections
Friedman 2000 - MCMC over Orderings and Computational Tricks samples orderings; Bayesian Causal Discovery - BGe Score, Interventions and Sachs Data gives Gaussian scores.
See Also
Friedman 2000 - Being Bayesian about Network Structure - Overview