neu_eval.voxel¶
Voxel-level agreement metrics. Every one is a pure function of a Contingency.
No arrays and no I/O, so computing several metrics is cheap; Plaza & Funke advise reading several together rather than trusting one.
Which half of VOI is “split” and which is “merge” depends on which side is the
reference, so nothing here returns a bare pair. With side a as the reference: if
b fuses two a bodies, a voxel’s b label no longer tells you its a body, so
H(a|b) grows, and that is voi_merge; if one a body is spread over several
b segments, H(b|a) grows, and that is voi_split. Plaza & Funke call these
under-segmentation H(G|S) and over-segmentation H(S|G).
Classes¶
Functions¶
|
Per-pair VOI contributions, parallel to |
|
Each label's contribution to the two halves of |
|
Adapted Rand precision, recall and F-score for the two sides of |
|
Every scalar in this module, plus what was scored, as one flat row (so many |
|
Variation of information between the two sides of |
Module Contents¶
- class neu_eval.voxel.Rand¶
Adapted Rand, as a precision/recall pair plus its F-score and the error.
precision: of the voxel pairsbputs in one segment, the fractionaalso puts together.recall: of the pairsaputs together, the fractionbkeeps together.error = 1 - f_scoreis the usual “adapted Rand error”.- as_dict() dict[str, float]¶
- property error: float¶
- property f_score: float¶
- precision: float¶
- recall: float¶
- class neu_eval.voxel.Voi¶
Variation of information, decomposed, in bits.
Named with side
aas the reference:merge = H(a|b)(bfusingabodies),split = H(b|a)(bfragmenting one).totalis their sum.- as_dict() dict[str, float]¶
- merge: float¶
- split: float¶
- property total: float¶
- neu_eval.voxel.pair_voi(c: neu_eval.overlap.Contingency) tuple[numpy.ndarray, numpy.ndarray]¶
Per-pair VOI contributions, parallel to
c’s arrays.(merge_term, split_term)for each(a_id, b_id)row, so a caller can rank pairs without re-deriving the entropy. Their sums arevoi()’s two fields.
- neu_eval.voxel.per_label_voi(c: neu_eval.overlap.Contingency) tuple[dict[int, float], dict[int, float]]¶
Each label’s contribution to the two halves of
voi().(merge_by_a, split_by_b): eachaid’s share ofH(a|b)and eachbid’s share ofH(b|a); each sums to the matching field ofvoi(). VOI contribution ranks errors better than voxel counts do: halving a large body and shaving a thousand voxels off it score the same in voxels.
- neu_eval.voxel.rand(c: neu_eval.overlap.Contingency) Rand¶
Adapted Rand precision, recall and F-score for the two sides of
c.Counts of pairs of voxels, computed from the sums of squares rather than by enumeration:
sum_ij n_ij^2for pairs the two sides agree on, againstsum_j n_j^2andsum_i n_i^2for the pairs each side claims.
- neu_eval.voxel.summary(c: neu_eval.overlap.Contingency) dict[str, float | int]¶
Every scalar in this module, plus what was scored, as one flat row (so many comparisons make a DataFrame).
frac_scoredis included because a VOI over 3% of a box is not comparable to one over all of it.
- neu_eval.voxel.voi(c: neu_eval.overlap.Contingency) Voi¶
Variation of information between the two sides of
c, in bits.Zero when the labelings agree up to renaming. An empty table also scores zero; check
frac_scored, which shows when nothing was scored.