mixle.stats.graphs.hyperedge_replacement_grammar module¶
Hyperedge-replacement graph grammar (HRG) – a distribution over networks you can score, fit, and sample.
The second main kind of graph grammar (the other is vertex replacement; see
vertex_replacement_grammar). A production A -> R rewrites a nonterminal HYPEREDGE labelled A
with a ranked tuple of attachment nodes (its tentacles) by a right-hand-side hypergraph R carrying
an ordered tuple of rank(A) external nodes; the rewrite fuses R’s external nodes with the
hyperedge’s tentacles (so the gluing is intrinsic – no embedding relation, unlike NLC). HRGs are
context-free and confluent, with cleaner parsing theory.
Observations are GRAPHS (networkx graphs, all-terminal); the start symbol has rank 0 by default, so a
derivation generates a graph with no boundary. The distribution mirrors vertex_replacement_grammar:
log_density(graph)is the MARGINAL likelihood – the graph is parsed (reduced back to the start symbol by un-applying productions) and scored as the log-sum over all derivations (the inside / sum-product recursion). Exact when the parse forest is fully explored, a lower bound if the budget truncates it,-infif the grammar cannot derive the graph.best_derivationgives the Viterbi parse.sample()runs a real hyperedge-replacement derivation.the estimator learns rule FREQUENCIES by Viterbi parse-counting (structure given; induction is out of scope).
- class Hypergraph(graph=None, hyperedges=())[source]
Bases:
objectA hypergraph: a networkx graph of terminal (rank-2) edges plus a list of nonterminal hyperedges.
graphholds the nodes and terminal edges (withlabel/node_color/weight/edge_colorattributes, as for vertex replacement).hyperedgesis a list of(label, tuple_of_attachment_nodes)– the nonterminal hyperedges still to be rewritten.- copy()[source]
Return a structural copy of the terminal graph and nonterminal hyperedges.
- class HyperedgeReplacementRule(lhs, rhs, external, frequency=1.0)[source]
Bases:
objectA production
lhs -> rhs: replace a rank-k nonterminal hyperedge byrhs, fusing externals.externalis the ordered tuple ofrhsnodes (length = rank oflhs) fused, in order, with the rewritten hyperedge’s tentacles.frequencyweights the production within its left-hand side.- property rank: int
Return the arity of the left-hand-side nonterminal hyperedge.
- class HyperedgeReplacementGrammar(name='')[source]
Bases:
objectA container of HyperedgeReplacementRule objects keyed by left-hand-side symbol.
- add_rule(rule)[source]
Add a production rule and refresh the flattened rule list.
- Parameters:
rule (HyperedgeReplacementRule)
- Return type:
None
- refresh_rules()[source]
Rebuild the flattened rule list and cached rule count.
- Return type:
None
- generate_graph(grammar, start_symbol, target_n=100, rng=None, start_rank=0)[source]
Generate a graph by a hyperedge-replacement derivation.
Begins with a single nonterminal hyperedge
start_symbolonstart_rankfresh boundary nodes (default 0 -> no boundary). Repeatedly rewrites a nonterminal hyperedge by one of its symbol’s rules (probability proportional to frequency), fusing the rule’s external nodes onto the hyperedge’s tentacles.target_nis a soft node budget: once reached the derivation prefers terminal-only rules, and any hyperedges left after the step cap are dropped. Returns a networkx graph.
- best_derivation(graph, grammar, start_symbol, budget=_PARSE_BUDGET)[source]
Best (Viterbi) hyperedge-replacement derivation of a graph: (log_prob, [rules]) or (-inf, None).
- marginal_log_prob(graph, grammar, start_symbol, budget=_PARSE_BUDGET, with_status=False)[source]
Marginal log-likelihood: log-sum over ALL hyperedge-replacement derivations that yield the graph.
Exact when the parse forest is fully explored; a variational lower bound (ELBO) if the budget/depth cap truncates it.
with_statusreturns(value, exact)withexactFalse iff a cap was hit.
- class HyperedgeReplacementGrammarDistribution(grammar, start_symbol=None, orig_n=100, name=None)[source]
Bases:
SequenceEncodableProbabilityDistributionA distribution over GRAPHS parameterised by a hyperedge-replacement grammar.
log_density(graph)is the marginal likelihood (sum over derivations, by parsing);sample()emits graphs by derivation; the estimator learns rule frequencies by Viterbi parse-counting.- density_semantics()[source]
Return that graph densities are lower bounds when parsing is budget-truncated.
- density(x)[source]
Return the marginal probability of a graph under the grammar.
- log_density(x, with_status=False)[source]
Marginal log-likelihood of graph
x(seemarginal_log_prob).with_status-> (value, exact).
- seq_encode(x)[source]
Return graph observations unchanged for sequence scoring.
- seq_log_density(x, with_status=False)[source]
Return vectorized graph log-likelihoods, optionally with exactness flags.
- sampler(seed=None)[source]
Return a derivation sampler for this grammar distribution.
- estimator(pseudo_count=None)[source]
Return a Viterbi parse-count estimator for this grammar’s rule frequencies.
- dist_to_encoder()[source]
Return the identity graph encoder used by vectorized methods.
- class HyperedgeReplacementGrammarSampler(grammar, start_symbol=None, orig_n=100, seed=None)[source]
Bases:
DistributionSamplerSample graphs from a hyperedge-replacement grammar by derivation.
- sample(size=None, *, batched=True)[source]
Draw one graph or a list of graphs by HRG derivation.
- class HyperedgeReplacementGrammarAccumulator(grammar=None, start_symbol=None, keys=None)[source]
Bases:
SequenceEncodableStatisticAccumulatorAccumulate Viterbi rule-firing counts: parse each graph and tally how often each rule fires.
- update(x, weight, estimate)[source]
Update Viterbi rule counts from one observed graph.
- initialize(x, weight, rng)[source]
Initialize rule counts from one observed graph.
- seq_initialize(x, weights, rng)[source]
Initialize rule counts from a batch of observed graphs.
- seq_update(x, weights, estimate)[source]
Update Viterbi rule counts from a batch of observed graphs.
- combine(suff_stat)[source]
Merge rule-frequency counts from another grammar accumulator value.
- value()[source]
Return the grammar-shaped rule-count accumulator.
- from_value(x)[source]
Restore grammar-shaped rule counts from
valueoutput.
- key_merge(stats_dict)[source]
Merge this accumulator into
stats_dictunder its configured key.
- key_replace(stats_dict)[source]
Replace this accumulator’s state from keyed statistics when present.
- acc_to_encoder()[source]
Return the graph encoder compatible with this accumulator.
- class HyperedgeReplacementGrammarAccumulatorFactory(grammar=None, start_symbol=None, keys=None)[source]
Bases:
StatisticAccumulatorFactoryCreates accumulators carrying the rule structure whose frequencies are estimated.
- make()[source]
Create an empty HRG rule-count accumulator.
- class HyperedgeReplacementGrammarEstimator(grammar=None, start_symbol=None, pseudo_count=None, name=None, keys=None)[source]
Bases:
ParameterEstimatorEstimate rule FREQUENCIES from graphs by Viterbi parse-counting (the structure is given).
- accumulator_factory()[source]
Return a factory for HRG Viterbi rule-count accumulators.
- estimate(nobs, suff_stat)[source]
Estimate rule frequencies from accumulated Viterbi parse counts.