position_accuracy¶
Bar-position accuracy, decomposed by how a track’s predicted bar grid is misaligned with the reference rather than just how often it is.
musicality.metrics.confusion.confusion_half_cycle_rate() says a
prediction is half a bar out; it can’t say whether the model got the phase
wrong for the whole track (a consistent offset — an acoustic/model failure)
or kept flipping between phases within the track (an unstable decode — a
postprocessing failure). Those two have opposite fixes, so this separates
them.
The offset histogram is the mechanism; the headline numbers are
position_acc and position_acc_best_offset, whose difference —
anchor_error — is the cost of a bar grid that is right in every respect
except where it starts counting.
Functions
|
Bar-position accuracy at every reference beat, plus its offset profile. |
- position_accuracy(ref_times, ref_positions, pred_events, tolerance=0.07, group_size=4)[source]¶
Bar-position accuracy at every reference beat, plus its offset profile.
For every reference beat, finds the nearest predicted event within
toleranceseconds and recordsoffset = (predicted_position - true_position) mod group_size. Unlikeconfusion_half_cycle_rate(), all positions are eligible, not just 1 and the half-cycle opposite — an off-by-one error is exactly what this is meant to be able to see, and unlikedownbeat_f_measures()it scores positions2..group_size-1too.The two headline numbers:
position_acc— the fraction labelled correctly, as annotated.position_acc_best_offset— the fraction the model would get right if allowed to rotate its bar numbering by one constant per track. Near1.0means the track has one consistent phase (right or wrong) from start to finish; well below means the predicted phase changes partway through.
Their difference,
anchor_error, is therefore the share of the error attributable to choosing the wrong global anchor rather than to an inconsistent grid. Measured onmerge_v4, 0.090 of a total 0.419 position error; seeplans/06_metric_calibration_and_eval_consolidation.mdsection 1.2.Reading them with
modal_offset:high
position_acc_best_offset,modal_offset != 0→ the model committed to a single wrong phase for the whole track. A better decoder can’t help; the per-beat evidence itself is wrong.low
position_acc_best_offset→ the predicted phase flips mid-track. The evidence may well be fine on average and the decoder is losing it (seemusicality.postprocess.label_bar_position()’s resync behaviour).
- Parameters:
ref_times (ndarray) – Reference beat times, in seconds, shape
(n_beats,).ref_positions (ndarray) – Reference group position (1-
group_size) per beat, same shape asref_times.pred_events (list[dict]) – Predicted beat list, as returned by
musicality.postprocess.readout().tolerance (float) – Matching window, in seconds.
group_size (int) – Beats per group —
4for bar position (default),8for phrase position.
- Returns:
Noneif no reference beat found a matching, resolved prediction (nothing to score), else a dict with:n_matched(int) — reference beats that matched a resolved label.histogram(list[int], lengthgroup_size) — count per offset.modal_offset(int) — most common offset, in0..group_size-1.0is correct;group_size // 2is the half-cycle swap; anything else is an off-by-one-style error.position_acc(float) — fraction of matched beats at offset 0.position_acc_best_offset(float) — fraction atmodal_offset.anchor_error(float) —position_acc_best_offset - position_acc, always>= 0since offset 0 is one of the candidates the maximum is taken over. Zero exactly when the dominant offset is the correct one.
- Return type:
dict | None