mir_eval.chord

Chord estimation algorithms produce a list of intervals and labels which denote the chord being played over each timespan. They are evaluated by comparing the estimated chord labels to some reference, usually using a mapping to a chord subalphabet (e.g. minor and major chords only, all triads, etc.). There is no single ‘right’ way to compare two sequences of chord labels. Embracing this reality, every conventional comparison rule is provided. Comparisons are made over the different components of each chord (e.g. G:maj(6)/5): the root (G), the root-invariant active semitones as determined by the quality shorthand (maj) and scale degrees (6), and the bass interval (5). This submodule provides functions both for comparing a sequences of chord labels according to some chord subalphabet mapping and for using these comparisons to score a sequence of estimated chords against a reference.

Conventions

A sequence of chord labels is represented as a list of strings, where each label is the chord name based on the syntax of [1]. Reference and estimated chord label sequences should be of the same length for comparison functions. When converting the chord string into its constituent parts,

  • Pitch class counting starts at C, e.g. C:0, D:2, E:4, F:5, etc.

  • Scale degree is represented as a string of the diatonic interval, relative to the root note, e.g. ‘b6’, ‘#5’, or ‘7’

  • Bass intervals are represented as strings

  • Chord bitmaps are positional binary vectors indicating active pitch classes and may be absolute or relative depending on context in the code.

If no chord is present at a given point in time, it should have the label ‘N’, which is defined in the variable mir_eval.chord.NO_CHORD.

Metrics

  • mir_eval.chord.root(): Only compares the root of the chords.

  • mir_eval.chord.majmin(): Only compares major, minor, and “no chord” labels.

  • mir_eval.chord.majmin_inv(): Compares major/minor chords, with inversions. The bass note must exist in the triad.

  • mir_eval.chord.mirex(): A estimated chord is considered correct if it shares at least three pitch classes in common.

  • mir_eval.chord.thirds(): Chords are compared at the level of major or minor thirds (root and third), For example, both (‘A:7’, ‘A:maj’) and (‘A:min’, ‘A:dim’) are equivalent, as the third is major and minor in quality, respectively.

  • mir_eval.chord.thirds_inv(): Same as above, with inversions (bass relationships).

  • mir_eval.chord.triads(): Chords are considered at the level of triads (major, minor, augmented, diminished, suspended), meaning that, in addition to the root, the quality is only considered through #5th scale degree (for augmented chords). For example, (‘A:7’, ‘A:maj’) are equivalent, while (‘A:min’, ‘A:dim’) and (‘A:aug’, ‘A:maj’) are not.

  • mir_eval.chord.triads_inv(): Same as above, with inversions (bass relationships).

  • mir_eval.chord.tetrads(): Chords are considered at the level of the entire quality in closed voicing, i.e. spanning only a single octave; extended chords (9’s, 11’s and 13’s) are rolled into a single octave with any upper voices included as extensions. For example, (‘A:7’, ‘A:9’) are equivalent but (‘A:7’, ‘A:maj7’) are not.

  • mir_eval.chord.tetrads_inv(): Same as above, with inversions (bass relationships).

  • mir_eval.chord.sevenths(): Compares according to MIREX “sevenths” rules; that is, only major, major seventh, seventh, minor, minor seventh and no chord labels are compared.

  • mir_eval.chord.sevenths_inv(): Same as above, with inversions (bass relationships).

  • mir_eval.chord.overseg(): Computes the level of over-segmentation between estimated and reference intervals.

  • mir_eval.chord.underseg(): Computes the level of under-segmentation between estimated and reference intervals.

  • mir_eval.chord.seg(): Computes the minimum of over- and under-segmentation between estimated and reference intervals.

References

exception mir_eval.chord.InvalidChordException(message='', chord_label=None)

Bases: Exception

Exception class for suspect / invalid chord labels

mir_eval.chord.pitch_class_to_semitone(pitch_class)

Convert a pitch class to semitone.

Parameters:
pitch_classstr

Spelling of a given pitch class, e.g. ‘C#’, ‘Gbb’

Returns:
semitoneint

Semitone value of the pitch class.

mir_eval.chord.scale_degree_to_semitone(scale_degree)

Convert a scale degree to semitone.

Parameters:
scale_degreestr

Spelling of a relative scale degree, e.g. ‘b3’, ‘7’, ‘#5’

Returns:
semitoneint

Relative semitone of the scale degree, wrapped to a single octave

Raises:
InvalidChordException if scale_degree is invalid.
mir_eval.chord.scale_degree_to_bitmap(scale_degree, modulo=False, length=12)

Create a bitmap representation of a scale degree.

Note that values in the bitmap may be negative, indicating that the semitone is to be removed.

Parameters:
scale_degreestr

Spelling of a relative scale degree, e.g. ‘b3’, ‘7’, ‘#5’

modulobool, default=True

If a scale degree exceeds the length of the bit-vector, modulo the scale degree back into the bit-vector; otherwise it is discarded.

lengthint, default=12

Length of the bit-vector to produce

Returns:
bitmapnp.ndarray, in [-1, 0, 1], len=`length`

Bitmap representation of this scale degree.

mir_eval.chord.quality_to_bitmap(quality)

Return the bitmap for a given quality.

Parameters:
qualitystr

Chord quality name.

Returns:
bitmapnp.ndarray

Bitmap representation of this quality (12-dim).

mir_eval.chord.reduce_extended_quality(quality)

Map an extended chord quality to a simpler one, moving upper voices to a set of scale degree extensions.

Parameters:
qualitystr

Extended chord quality to reduce.

Returns:
base_qualitystr

New chord quality.

extensionsset

Scale degrees extensions for the quality.

mir_eval.chord.validate_chord_label(chord_label)

Test for well-formedness of a chord label.

Parameters:
chord_labelstr

Chord label to validate.

mir_eval.chord.split(chord_label, reduce_extended_chords=False)
Parse a chord label into its four constituent parts:
  • root

  • quality shorthand

  • scale degrees

  • bass

Note: Chords lacking quality AND interval information are major.
  • If a quality is specified, it is returned.

  • If an interval is specified WITHOUT a quality, the quality field is empty.

Some examples:

'C' -> ['C', 'maj', {}, '1']
'G#:min(*b3,*5)/5' -> ['G#', 'min', {'*b3', '*5'}, '5']
'A:(3)/6' -> ['A', '', {'3'}, '6']
Parameters:
chord_labelstr

A chord label.

reduce_extended_chordsbool

Whether to map the upper voicings of extended chords (9’s, 11’s, 13’s) to semitone extensions. (Default value = False)

Returns:
chord_partslist

Split version of the chord label.

mir_eval.chord.join(chord_root, quality='', extensions=None, bass='')

Join the parts of a chord into a complete chord label.

Parameters:
chord_rootstr

Root pitch class of the chord, e.g. ‘C’, ‘Eb’

qualitystr

Quality of the chord, e.g. ‘maj’, ‘hdim7’ (Default value = ‘’)

extensionslist

Any added or absent scaled degrees for this chord, e.g. [‘4’, ‘*3’] (Default value = None)

bassstr

Scale degree of the bass note, e.g. ‘5’. (Default value = ‘’)

Returns:
chord_labelstr

A complete chord label.

mir_eval.chord.encode(chord_label, reduce_extended_chords=False, strict_bass_intervals=False)

Translate a chord label to numerical representations for evaluation.

Parameters:
chord_labelstr

Chord label to encode.

reduce_extended_chordsbool

Whether to map the upper voicings of extended chords (9’s, 11’s, 13’s) to semitone extensions. (Default value = False)

strict_bass_intervalsbool

Whether to require that the bass scale degree is present in the chord. (Default value = False)

Returns:
root_numberint

Absolute semitone of the chord’s root.

semitone_bitmapnp.ndarray, dtype=int

12-dim vector of relative semitones in the chord spelling.

bass_numberint

Relative semitone of the chord’s bass note, e.g. 0=root, 7=fifth, etc.

mir_eval.chord.encode_many(chord_labels, reduce_extended_chords=False)

Translate a set of chord labels to numerical representations for sane evaluation.

Parameters:
chord_labelslist

Set of chord labels to encode.

reduce_extended_chordsbool

Whether to map the upper voicings of extended chords (9’s, 11’s, 13’s) to semitone extensions. (Default value = False)

Returns:
root_numbernp.ndarray, dtype=int

Absolute semitone of the chord’s root.

interval_bitmapnp.ndarray, dtype=int

12-dim vector of relative semitones in the given chord quality.

bass_numbernp.ndarray, dtype=int

Relative semitones of the chord’s bass notes.

mir_eval.chord.rotate_bitmap_to_root(bitmap, chord_root)

Circularly shift a relative bitmap to its absolute pitch classes.

For clarity, the best explanation is an example. Given ‘G:Maj’, the root and quality map are as follows:

root=5
quality=[1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0]  # Relative chord shape

After rotating to the root, the resulting bitmap becomes:

abs_quality = [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1]  # G, B, and D
Parameters:
bitmapnp.ndarray, shape=(12,)

Bitmap of active notes, relative to the given root.

chord_rootint

Absolute pitch class number.

Returns:
bitmapnp.ndarray, shape=(12,)

Absolute bitmap of active pitch classes.

mir_eval.chord.rotate_bitmaps_to_roots(bitmaps, roots)

Circularly shift a relative bitmaps to absolute pitch classes.

See rotate_bitmap_to_root() for more information.

Parameters:
bitmapsnp.ndarray, shape=(N, 12)

Bitmap of active notes, relative to the given root.

rootsnp.ndarray, shape=(N,)

Absolute pitch class number.

Returns:
bitmapnp.ndarray, shape=(N, 12)

Absolute bitmaps of active pitch classes.

mir_eval.chord.validate(reference_labels, estimated_labels)

Check that the input annotations to a comparison function look like valid chord labels.

Parameters:
reference_labelslist, len=n

Reference chord labels to score against.

estimated_labelslist, len=n

Estimated chord labels to score against.

mir_eval.chord.weighted_accuracy(comparisons, weights)

Compute the weighted accuracy of a list of chord comparisons.

Parameters:
comparisonsnp.ndarray

List of chord comparison scores, in [0, 1] or -1

weightsnp.ndarray

Weights (not necessarily normalized) for each comparison. This can be a list of interval durations

Returns:
scorefloat

Weighted accuracy

Examples

>>> (ref_intervals,
...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
>>> (est_intervals,
...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
>>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
...     est_intervals, est_labels, ref_intervals.min(),
...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
...     mir_eval.chord.NO_CHORD)
>>> (intervals,
...  ref_labels,
...  est_labels) = mir_eval.util.merge_labeled_intervals(
...      ref_intervals, ref_labels, est_intervals, est_labels)
>>> durations = mir_eval.util.intervals_to_durations(intervals)
>>> # Here, we're using the "thirds" function to compare labels
>>> # but any of the comparison functions would work.
>>> comparisons = mir_eval.chord.thirds(ref_labels, est_labels)
>>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)
mir_eval.chord.thirds(reference_labels, estimated_labels)

Compare chords along root & third relationships.

Parameters:
reference_labelslist, len=n

Reference chord labels to score against.

estimated_labelslist, len=n

Estimated chord labels to score against.

Returns:
comparison_scoresnp.ndarray, shape=(n,), dtype=float

Comparison scores, in [0.0, 1.0]

Examples

>>> (ref_intervals,
...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
>>> (est_intervals,
...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
>>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
...     est_intervals, est_labels, ref_intervals.min(),
...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
...     mir_eval.chord.NO_CHORD)
>>> (intervals,
...  ref_labels,
...  est_labels) = mir_eval.util.merge_labeled_intervals(
...      ref_intervals, ref_labels, est_intervals, est_labels)
>>> durations = mir_eval.util.intervals_to_durations(intervals)
>>> comparisons = mir_eval.chord.thirds(ref_labels, est_labels)
>>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)
mir_eval.chord.thirds_inv(reference_labels, estimated_labels)

Score chords along root, third, & bass relationships.

Parameters:
reference_labelslist, len=n

Reference chord labels to score against.

estimated_labelslist, len=n

Estimated chord labels to score against.

Returns:
scoresnp.ndarray, shape=(n,), dtype=float

Comparison scores, in [0.0, 1.0]

Examples

>>> (ref_intervals,
...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
>>> (est_intervals,
...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
>>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
...     est_intervals, est_labels, ref_intervals.min(),
...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
...     mir_eval.chord.NO_CHORD)
>>> (intervals,
...  ref_labels,
...  est_labels) = mir_eval.util.merge_labeled_intervals(
...      ref_intervals, ref_labels, est_intervals, est_labels)
>>> durations = mir_eval.util.intervals_to_durations(intervals)
>>> comparisons = mir_eval.chord.thirds_inv(ref_labels, est_labels)
>>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)
mir_eval.chord.triads(reference_labels, estimated_labels)

Compare chords along triad (root & quality to #5) relationships.

Parameters:
reference_labelslist, len=n

Reference chord labels to score against.

estimated_labelslist, len=n

Estimated chord labels to score against.

Returns:
comparison_scoresnp.ndarray, shape=(n,), dtype=float

Comparison scores, in [0.0, 1.0]

Examples

>>> (ref_intervals,
...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
>>> (est_intervals,
...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
>>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
...     est_intervals, est_labels, ref_intervals.min(),
...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
...     mir_eval.chord.NO_CHORD)
>>> (intervals,
...  ref_labels,
...  est_labels) = mir_eval.util.merge_labeled_intervals(
...      ref_intervals, ref_labels, est_intervals, est_labels)
>>> durations = mir_eval.util.intervals_to_durations(intervals)
>>> comparisons = mir_eval.chord.triads(ref_labels, est_labels)
>>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)
mir_eval.chord.triads_inv(reference_labels, estimated_labels)

Score chords along triad (root, quality to #5, & bass) relationships.

Parameters:
reference_labelslist, len=n

Reference chord labels to score against.

estimated_labelslist, len=n

Estimated chord labels to score against.

Returns:
scoresnp.ndarray, shape=(n,), dtype=float

Comparison scores, in [0.0, 1.0]

Examples

>>> (ref_intervals,
...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
>>> (est_intervals,
...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
>>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
...     est_intervals, est_labels, ref_intervals.min(),
...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
...     mir_eval.chord.NO_CHORD)
>>> (intervals,
...  ref_labels,
...  est_labels) = mir_eval.util.merge_labeled_intervals(
...      ref_intervals, ref_labels, est_intervals, est_labels)
>>> durations = mir_eval.util.intervals_to_durations(intervals)
>>> comparisons = mir_eval.chord.triads_inv(ref_labels, est_labels)
>>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)
mir_eval.chord.tetrads(reference_labels, estimated_labels)

Compare chords along tetrad (root & full quality) relationships.

Parameters:
reference_labelslist, len=n

Reference chord labels to score against.

estimated_labelslist, len=n

Estimated chord labels to score against.

Returns:
comparison_scoresnp.ndarray, shape=(n,), dtype=float

Comparison scores, in [0.0, 1.0]

Examples

>>> (ref_intervals,
...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
>>> (est_intervals,
...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
>>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
...     est_intervals, est_labels, ref_intervals.min(),
...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
...     mir_eval.chord.NO_CHORD)
>>> (intervals,
...  ref_labels,
...  est_labels) = mir_eval.util.merge_labeled_intervals(
...      ref_intervals, ref_labels, est_intervals, est_labels)
>>> durations = mir_eval.util.intervals_to_durations(intervals)
>>> comparisons = mir_eval.chord.tetrads(ref_labels, est_labels)
>>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)
mir_eval.chord.tetrads_inv(reference_labels, estimated_labels)

Compare chords along tetrad (root, full quality, & bass) relationships.

Parameters:
reference_labelslist, len=n

Reference chord labels to score against.

estimated_labelslist, len=n

Estimated chord labels to score against.

Returns:
comparison_scoresnp.ndarray, shape=(n,), dtype=float

Comparison scores, in [0.0, 1.0]

Examples

>>> (ref_intervals,
...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
>>> (est_intervals,
...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
>>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
...     est_intervals, est_labels, ref_intervals.min(),
...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
...     mir_eval.chord.NO_CHORD)
>>> (intervals,
...  ref_labels,
...  est_labels) = mir_eval.util.merge_labeled_intervals(
...      ref_intervals, ref_labels, est_intervals, est_labels)
>>> durations = mir_eval.util.intervals_to_durations(intervals)
>>> comparisons = mir_eval.chord.tetrads_inv(ref_labels, est_labels)
>>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)
mir_eval.chord.root(reference_labels, estimated_labels)

Compare chords according to roots.

Parameters:
reference_labelslist, len=n

Reference chord labels to score against.

estimated_labelslist, len=n

Estimated chord labels to score against.

Returns:
comparison_scoresnp.ndarray, shape=(n,), dtype=float

Comparison scores, in [0.0, 1.0], or -1 if the comparison is out of gamut.

Examples

>>> (ref_intervals,
...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
>>> (est_intervals,
...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
>>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
...     est_intervals, est_labels, ref_intervals.min(),
...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
...     mir_eval.chord.NO_CHORD)
>>> (intervals,
...  ref_labels,
...  est_labels) = mir_eval.util.merge_labeled_intervals(
...      ref_intervals, ref_labels, est_intervals, est_labels)
>>> durations = mir_eval.util.intervals_to_durations(intervals)
>>> comparisons = mir_eval.chord.root(ref_labels, est_labels)
>>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)
mir_eval.chord.mirex(reference_labels, estimated_labels)

Compare chords along MIREX rules.

Parameters:
reference_labelslist, len=n

Reference chord labels to score against.

estimated_labelslist, len=n

Estimated chord labels to score against.

Returns:
comparison_scoresnp.ndarray, shape=(n,), dtype=float

Comparison scores, in [0.0, 1.0]

Examples

>>> (ref_intervals,
...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
>>> (est_intervals,
...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
>>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
...     est_intervals, est_labels, ref_intervals.min(),
...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
...     mir_eval.chord.NO_CHORD)
>>> (intervals,
...  ref_labels,
...  est_labels) = mir_eval.util.merge_labeled_intervals(
...      ref_intervals, ref_labels, est_intervals, est_labels)
>>> durations = mir_eval.util.intervals_to_durations(intervals)
>>> comparisons = mir_eval.chord.mirex(ref_labels, est_labels)
>>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)
mir_eval.chord.majmin(reference_labels, estimated_labels)

Compare chords along major-minor rules. Chords with qualities outside Major/minor/no-chord are ignored.

Parameters:
reference_labelslist, len=n

Reference chord labels to score against.

estimated_labelslist, len=n

Estimated chord labels to score against.

Returns:
comparison_scoresnp.ndarray, shape=(n,), dtype=float

Comparison scores, in [0.0, 1.0], or -1 if the comparison is out of gamut.

Examples

>>> (ref_intervals,
...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
>>> (est_intervals,
...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
>>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
...     est_intervals, est_labels, ref_intervals.min(),
...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
...     mir_eval.chord.NO_CHORD)
>>> (intervals,
...  ref_labels,
...  est_labels) = mir_eval.util.merge_labeled_intervals(
...      ref_intervals, ref_labels, est_intervals, est_labels)
>>> durations = mir_eval.util.intervals_to_durations(intervals)
>>> comparisons = mir_eval.chord.majmin(ref_labels, est_labels)
>>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)
mir_eval.chord.majmin_inv(reference_labels, estimated_labels)

Compare chords along major-minor rules, with inversions. Chords with qualities outside Major/minor/no-chord are ignored, and the bass note must exist in the triad (bass in [1, 3, 5]).

Parameters:
reference_labelslist, len=n

Reference chord labels to score against.

estimated_labelslist, len=n

Estimated chord labels to score against.

Returns:
comparison_scoresnp.ndarray, shape=(n,), dtype=float

Comparison scores, in [0.0, 1.0], or -1 if the comparison is out of gamut.

Examples

>>> (ref_intervals,
...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
>>> (est_intervals,
...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
>>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
...     est_intervals, est_labels, ref_intervals.min(),
...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
...     mir_eval.chord.NO_CHORD)
>>> (intervals,
...  ref_labels,
...  est_labels) = mir_eval.util.merge_labeled_intervals(
...      ref_intervals, ref_labels, est_intervals, est_labels)
>>> durations = mir_eval.util.intervals_to_durations(intervals)
>>> comparisons = mir_eval.chord.majmin_inv(ref_labels, est_labels)
>>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)
mir_eval.chord.sevenths(reference_labels, estimated_labels)

Compare chords along MIREX ‘sevenths’ rules. Chords with qualities outside [maj, maj7, 7, min, min7, N] are ignored.

Parameters:
reference_labelslist, len=n

Reference chord labels to score against.

estimated_labelslist, len=n

Estimated chord labels to score against.

Returns:
comparison_scoresnp.ndarray, shape=(n,), dtype=float

Comparison scores, in [0.0, 1.0], or -1 if the comparison is out of gamut.

Examples

>>> (ref_intervals,
...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
>>> (est_intervals,
...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
>>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
...     est_intervals, est_labels, ref_intervals.min(),
...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
...     mir_eval.chord.NO_CHORD)
>>> (intervals,
...  ref_labels,
...  est_labels) = mir_eval.util.merge_labeled_intervals(
...      ref_intervals, ref_labels, est_intervals, est_labels)
>>> durations = mir_eval.util.intervals_to_durations(intervals)
>>> comparisons = mir_eval.chord.sevenths(ref_labels, est_labels)
>>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)
mir_eval.chord.sevenths_inv(reference_labels, estimated_labels)

Compare chords along MIREX ‘sevenths’ rules. Chords with qualities outside [maj, maj7, 7, min, min7, N] are ignored.

Parameters:
reference_labelslist, len=n

Reference chord labels to score against.

estimated_labelslist, len=n

Estimated chord labels to score against.

Returns:
comparison_scoresnp.ndarray, shape=(n,), dtype=float

Comparison scores, in [0.0, 1.0], or -1 if the comparison is out of gamut.

Examples

>>> (ref_intervals,
...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
>>> (est_intervals,
...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
>>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
...     est_intervals, est_labels, ref_intervals.min(),
...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
...     mir_eval.chord.NO_CHORD)
>>> (intervals,
...  ref_labels,
...  est_labels) = mir_eval.util.merge_labeled_intervals(
...      ref_intervals, ref_labels, est_intervals, est_labels)
>>> durations = mir_eval.util.intervals_to_durations(intervals)
>>> comparisons = mir_eval.chord.sevenths_inv(ref_labels, est_labels)
>>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)
mir_eval.chord.directional_hamming_distance(reference_intervals, estimated_intervals)

Compute the directional hamming distance between reference and estimated intervals as defined by [1] and used for MIREX ‘OverSeg’, ‘UnderSeg’ and ‘MeanSeg’ measures.

Parameters:
reference_intervalsnp.ndarray, shape=(n, 2), dtype=float

Reference chord intervals to score against.

estimated_intervalsnp.ndarray, shape=(m, 2), dtype=float

Estimated chord intervals to score against.

Returns:
directional hamming distancefloat

directional hamming distance between reference intervals and estimated intervals.

Examples

>>> (ref_intervals,
...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
>>> (est_intervals,
...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
>>> overseg = 1 - mir_eval.chord.directional_hamming_distance(
...     ref_intervals, est_intervals)
>>> underseg = 1 - mir_eval.chord.directional_hamming_distance(
...     est_intervals, ref_intervals)
>>> seg = min(overseg, underseg)
mir_eval.chord.overseg(reference_intervals, estimated_intervals)

Compute the MIREX ‘OverSeg’ score.

Parameters:
reference_intervalsnp.ndarray, shape=(n, 2), dtype=float

Reference chord intervals to score against.

estimated_intervalsnp.ndarray, shape=(m, 2), dtype=float

Estimated chord intervals to score against.

Returns:
oversegmentation scorefloat

Comparison score, in [0.0, 1.0], where 1.0 means no oversegmentation.

Examples

>>> (ref_intervals,
...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
>>> (est_intervals,
...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
>>> score = mir_eval.chord.overseg(ref_intervals, est_intervals)
mir_eval.chord.underseg(reference_intervals, estimated_intervals)

Compute the MIREX ‘UnderSeg’ score.

Parameters:
reference_intervalsnp.ndarray, shape=(n, 2), dtype=float

Reference chord intervals to score against.

estimated_intervalsnp.ndarray, shape=(m, 2), dtype=float

Estimated chord intervals to score against.

Returns:
undersegmentation scorefloat

Comparison score, in [0.0, 1.0], where 1.0 means no undersegmentation.

Examples

>>> (ref_intervals,
...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
>>> (est_intervals,
...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
>>> score = mir_eval.chord.underseg(ref_intervals, est_intervals)
mir_eval.chord.seg(reference_intervals, estimated_intervals)

Compute the MIREX ‘MeanSeg’ score.

Parameters:
reference_intervalsnp.ndarray, shape=(n, 2), dtype=float

Reference chord intervals to score against.

estimated_intervalsnp.ndarray, shape=(m, 2), dtype=float

Estimated chord intervals to score against.

Returns:
segmentation scorefloat

Comparison score, in [0.0, 1.0], where 1.0 means perfect segmentation.

Examples

>>> (ref_intervals,
...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
>>> (est_intervals,
...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
>>> score = mir_eval.chord.seg(ref_intervals, est_intervals)
mir_eval.chord.merge_chord_intervals(intervals, labels)

Merge consecutive chord intervals if they represent the same chord.

Parameters:
intervalsnp.ndarray, shape=(n, 2), dtype=float

Chord intervals to be merged, in the format returned by mir_eval.io.load_labeled_intervals().

labelslist, shape=(n,)

Chord labels to be merged, in the format returned by mir_eval.io.load_labeled_intervals().

Returns:
merged_ivsnp.ndarray, shape=(k, 2), dtype=float

Merged chord intervals, k <= n

mir_eval.chord.evaluate(ref_intervals, ref_labels, est_intervals, est_labels, **kwargs)

Compute weighted accuracy for all comparison functions for the given reference and estimated annotations.

Parameters:
ref_intervalsnp.ndarray, shape=(n, 2)

Reference chord intervals, in the format returned by mir_eval.io.load_labeled_intervals().

ref_labelslist, shape=(n,)

reference chord labels, in the format returned by mir_eval.io.load_labeled_intervals().

est_intervalsnp.ndarray, shape=(m, 2)

estimated chord intervals, in the format returned by mir_eval.io.load_labeled_intervals().

est_labelslist, shape=(m,)

estimated chord labels, in the format returned by mir_eval.io.load_labeled_intervals().

**kwargs

Additional keyword arguments which will be passed to the appropriate metric or preprocessing functions.

Returns:
scoresdict

Dictionary of scores, where the key is the metric name (str) and the value is the (float) score achieved.

Examples

>>> (ref_intervals,
...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
>>> (est_intervals,
...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
>>> scores = mir_eval.chord.evaluate(ref_intervals, ref_labels,
...                                  est_intervals, est_labels)