mixle.utils.hvis.topology module¶
The fuzzy nerve of the learned cover, and map-fidelity receipts (design review R3/R2, partial).
The fitted mixture is a parametrized cover of the data manifold: components are cover elements and
the posterior is a partition of unity subordinate to it. By the nerve theorem, the topology of the
data (for a good cover) is the homotopy type of the cover’s NERVE – the simplicial complex whose
k-simplices are (k+1)-wise overlapping components. fuzzy_nerve() computes its weighted 1- and
2-skeleton directly from the posteriors (this is soft Mapper with an EM-learned cover), and
nerve_report() turns it into receipts a 2-D map cannot give on its own:
holes – an unfilled cycle of strongly-overlapping components (e.g. a ring-shaped manifold) is a loop in the data’s topology. A plane embedding may render it faithfully or may distort it; either way the user should KNOW the loop exists rather than infer it from blob positions.
disconnection – a cover that splits into multiple connected pieces.
Cycle classification is deliberately conservative: a 3-cycle is “filled” exactly when its triple overlap is strong (the 2-simplex is present); longer cycles are reported as candidate holes without attempting a full triangulation check (exact filling is a combinatorial problem; the honest output is “here is a cycle no strong triple fills directly”).
embedding_health() is the RENDERING-fidelity receipt: trustworthiness/continuity of the map’s
neighborhoods against the model affinity that produced it. Note precisely what this does and does
not audit – it catches a layout that misrepresents the model (rendering failure), NOT a model that
misrepresents the data (model misfit, which remains the design review’s open R2 item).
- component_tree(nerve)[source]
Single-linkage merge tree over components by nerve edge weight – the hierarchy skeleton.
Merges are emitted strongest-overlap-first:
[{"a": frozenset, "b": frozenset, "weight": w, "merged": frozenset}, ...]. Cutting the tree at any weight gives coarse super-components (mixle.utils.hvis.front.Mapuses it for zoom groups); the merge order is itself a receipt – which regimes are almost one regime.
- embedding_health(coords, mix_model, data, *, affinity='auto', k=10, field_weights=None, evidence_cap=1.0, max_rows=400, seed=0)[source]
Rendering-fidelity receipt: do the map’s neighborhoods agree with the model affinity?
Standard trustworthiness (are map-neighbors genuinely close under the model?) and continuity (are model-neighbors kept close in the map?), computed on a row subsample. This audits the LAYOUT against the MODEL – a low score means the picture misrepresents the affinities that produced it (bad init, unconverged optimizer, non-embeddable topology). It does NOT audit the model against the raw data; that receipt is still open (design review R2).
- fuzzy_nerve(z, *, edge_threshold=0.02, triangle_threshold=0.02)[source]
Weighted 1- and 2-skeleton of the cover’s nerve, from the posteriors alone.
Edge weight
w(k,l) = sum_i z_ik z_il / min(mass_k, mass_l)– the co-claimed fraction of the smaller component’s mass (1 when one component’s points are entirely co-claimed by the other, 0 when they never co-claim). Triangle weight is the same with a triple product. Simplices at or above their threshold are “strong” and drivenerve_report(); all nonzero weights are returned so thresholds are inspectable choices, not hidden ones.
- model_fit_health(mix_model, data, *, holdout=None, field_weights=None, coverage_q=0.9, merged_sep_threshold=None, shattered_weight=0.5, min_component_points=20)[source]
The model<->data receipt (design review R2, second half): does the FITTED MODEL describe the data it is about to be a map of? Measured from the model’s own residual structure – no raw feature space is assumed, which is the whole point of HViS.
fiber calibration – per component, the squared Mahalanobis of its dominant points’ whitened fiber coordinates should look chi-squared: the fraction inside the
coverage_qball is compared againstcoverage_q. A large gap means the component’s shape claim is wrong (too wide, too narrow, or mis-shaped).merged-regime detector – a deterministic 2-means split (top-PC sign init) of each component’s dominant fiber coordinates; a separation ratio above the threshold with a non-trivial minority says one component is covering what the data treats as two regimes (K too small). The threshold has a derivation plus a measured finite-sample correction: for a UNIMODAL normal the population statistic is
2 E|x| / sqrt(1 - 2/pi) ~ 2.65regardless of scale, but at n=40 sample noise inflates it to ~3.4 (observed), so the default threshold is2.65 + 6/sqrt(n)– ~3.6 at n=40, tightening toward the population value as n grows. Two unit-variance regimes 4 sigma apart score ~4.0 either way. Pass an explicitmerged_sep_thresholdto pin it.shattered detector – nerve edges with weight >=
shattered_weightare near-duplicate components claiming largely the same points (K too large).held-out check – with
holdoutdata, a mean log-density drop > 1 nat vs training is flagged (memorization / drift).
- nerve_report(nerve)[source]
Topology receipts from a
fuzzy_nerve(): connected pieces, cycles, and candidate holes.A hole is an independent cycle of strong edges not directly filled by a strong 2-simplex (3-cycles are checked exactly; longer cycles are conservatively reported as candidates). The
diagnosisstrings are the user-facing half: a loop in the cover is real data topology that a 2-D layout may distort silently.