def difference(self, reference, hypothesis, uem=None, uemified=False): """Get error analysis as `Annotation` Labels are (status, reference_label, hypothesis_label) tuples. `status` is either 'correct', 'confusion', 'missed detection' or 'false alarm'. `reference_label` is None in case of 'false alarm'. `hypothesis_label` is None in case of 'missed detection'. Parameters ---------- uemified : bool, optional Returns "uemified" version of reference and hypothesis. Defaults to False. Returns ------- errors : `Annotation` """ R, H, common_timeline = self.uemify(reference, hypothesis, uem=uem, collar=self.collar, skip_overlap=self.skip_overlap, returns_timeline=True) errors = Annotation(uri=reference.uri, modality=reference.modality) # loop on all segments for segment in common_timeline: # list of labels in reference segment rlabels = R.get_labels(segment, unique=False) # list of labels in hypothesis segment hlabels = H.get_labels(segment, unique=False) _, details = self.matcher(rlabels, hlabels) for r, h in details[MATCH_CORRECT]: track = errors.new_track(segment, prefix=MATCH_CORRECT) errors[segment, track] = (MATCH_CORRECT, r, h) for r, h in details[MATCH_CONFUSION]: track = errors.new_track(segment, prefix=MATCH_CONFUSION) errors[segment, track] = (MATCH_CONFUSION, r, h) for r in details[MATCH_MISSED_DETECTION]: track = errors.new_track(segment, prefix=MATCH_MISSED_DETECTION) errors[segment, track] = (MATCH_MISSED_DETECTION, r, None) for h in details[MATCH_FALSE_ALARM]: track = errors.new_track(segment, prefix=MATCH_FALSE_ALARM) errors[segment, track] = (MATCH_FALSE_ALARM, None, h) if uemified: return reference, hypothesis, errors else: return errors
def regression(self, reference, before, after, uem=None, uemified=False): _, before, errors_before = self.difference( reference, before, uem=uem, uemified=True) reference, after, errors_after = self.difference( reference, after, uem=uem, uemified=True) behaviors = Annotation(uri=reference.uri, modality=reference.modality) # common (up-sampled) timeline common_timeline = errors_after.get_timeline().union( errors_before.get_timeline()) common_timeline = common_timeline.segmentation() # align 'before' errors on common timeline B = self._tagger(errors_before, common_timeline) # align 'after' errors on common timeline A = self._tagger(errors_after, common_timeline) for segment in common_timeline: old_errors = B.get_labels(segment, unique=False) new_errors = A.get_labels(segment, unique=False) n1 = len(old_errors) n2 = len(new_errors) n = max(n1, n2) match = np.zeros((n, n), dtype=int) for i1, e1 in enumerate(old_errors): for i2, e2 in enumerate(new_errors): match[i1, i2] = self._match_errors(e1, e2) mapping = self.munkres.compute(2 - match) for i1, i2 in mapping: if i1 >= n1: track = behaviors.new_track(segment, candidate=REGRESSION, prefix=REGRESSION) behaviors[segment, track] = ( REGRESSION, None, new_errors[i2]) elif i2 >= n2: track = behaviors.new_track(segment, candidate=IMPROVEMENT, prefix=IMPROVEMENT) behaviors[segment, track] = ( IMPROVEMENT, old_errors[i1], None) elif old_errors[i1][0] == MATCH_CORRECT: if new_errors[i2][0] == MATCH_CORRECT: track = behaviors.new_track(segment, candidate=BOTH_CORRECT, prefix=BOTH_CORRECT) behaviors[segment, track] = ( BOTH_CORRECT, old_errors[i1], new_errors[i2]) else: track = behaviors.new_track(segment, candidate=REGRESSION, prefix=REGRESSION) behaviors[segment, track] = ( REGRESSION, old_errors[i1], new_errors[i2]) else: if new_errors[i2][0] == MATCH_CORRECT: track = behaviors.new_track(segment, candidate=IMPROVEMENT, prefix=IMPROVEMENT) behaviors[segment, track] = ( IMPROVEMENT, old_errors[i1], new_errors[i2]) else: track = behaviors.new_track(segment, candidate=BOTH_INCORRECT, prefix=BOTH_INCORRECT) behaviors[segment, track] = ( BOTH_INCORRECT, old_errors[i1], new_errors[i2]) behaviors = behaviors.smooth() if uemified: return reference, before, after, behaviors else: return behaviors
def regression(self, reference, before, after, uem=None, uemified=False): _, before, errors_before = self.difference(reference, before, uem=uem, uemified=True) reference, after, errors_after = self.difference(reference, after, uem=uem, uemified=True) behaviors = Annotation(uri=reference.uri, modality=reference.modality) # common (up-sampled) timeline common_timeline = errors_after.get_timeline().union( errors_before.get_timeline()) common_timeline = common_timeline.segmentation() # align 'before' errors on common timeline B = self._tagger(errors_before, common_timeline) # align 'after' errors on common timeline A = self._tagger(errors_after, common_timeline) for segment in common_timeline: old_errors = B.get_labels(segment, unique=False) new_errors = A.get_labels(segment, unique=False) n1 = len(old_errors) n2 = len(new_errors) n = max(n1, n2) match = np.zeros((n, n), dtype=int) for i1, e1 in enumerate(old_errors): for i2, e2 in enumerate(new_errors): match[i1, i2] = self._match_errors(e1, e2) mapping = self.munkres.compute(2 - match) for i1, i2 in mapping: if i1 >= n1: track = behaviors.new_track(segment, candidate=REGRESSION, prefix=REGRESSION) behaviors[segment, track] = (REGRESSION, None, new_errors[i2]) elif i2 >= n2: track = behaviors.new_track(segment, candidate=IMPROVEMENT, prefix=IMPROVEMENT) behaviors[segment, track] = (IMPROVEMENT, old_errors[i1], None) elif old_errors[i1][0] == MATCH_CORRECT: if new_errors[i2][0] == MATCH_CORRECT: track = behaviors.new_track(segment, candidate=BOTH_CORRECT, prefix=BOTH_CORRECT) behaviors[segment, track] = (BOTH_CORRECT, old_errors[i1], new_errors[i2]) else: track = behaviors.new_track(segment, candidate=REGRESSION, prefix=REGRESSION) behaviors[segment, track] = (REGRESSION, old_errors[i1], new_errors[i2]) else: if new_errors[i2][0] == MATCH_CORRECT: track = behaviors.new_track(segment, candidate=IMPROVEMENT, prefix=IMPROVEMENT) behaviors[segment, track] = (IMPROVEMENT, old_errors[i1], new_errors[i2]) else: track = behaviors.new_track(segment, candidate=BOTH_INCORRECT, prefix=BOTH_INCORRECT) behaviors[segment, track] = (BOTH_INCORRECT, old_errors[i1], new_errors[i2]) behaviors = behaviors.support() if uemified: return reference, before, after, behaviors else: return behaviors
def difference(self, reference, hypothesis, uem=None, uemified=False): """Get error analysis as `Annotation` Labels are (status, reference_label, hypothesis_label) tuples. `status` is either 'correct', 'confusion', 'missed detection' or 'false alarm'. `reference_label` is None in case of 'false alarm'. `hypothesis_label` is None in case of 'missed detection'. Parameters ---------- uemified : bool, optional Returns "uemified" version of reference and hypothesis. Defaults to False. Returns ------- errors : `Annotation` """ reference, hypothesis = self.uemify( reference, hypothesis, uem=uem, collar=self.collar) reference, hypothesis = self._handle_unknowns(reference, hypothesis) # common (up-sampled) timeline common_timeline = reference.get_timeline().union( hypothesis.get_timeline()) common_timeline = common_timeline.segmentation() # align reference on common timeline R = self._tagger(reference, common_timeline) # translate and align hypothesis on common timeline H = self._tagger(hypothesis, common_timeline) errors = Annotation(uri=reference.uri, modality=reference.modality) # loop on all segments for segment in common_timeline: # list of labels in reference segment rlabels = R.get_labels(segment, unknown=self.unknown, unique=False) # list of labels in hypothesis segment hlabels = H.get_labels(segment, unknown=self.unknown, unique=False) _, details = self.matcher(rlabels, hlabels) for r, h in details[MATCH_CORRECT]: track = errors.new_track(segment, prefix=MATCH_CORRECT) errors[segment, track] = (MATCH_CORRECT, r, h) for r, h in details[MATCH_CONFUSION]: track = errors.new_track(segment, prefix=MATCH_CONFUSION) errors[segment, track] = (MATCH_CONFUSION, r, h) for r in details[MATCH_MISSED_DETECTION]: track = errors.new_track(segment, prefix=MATCH_MISSED_DETECTION) errors[segment, track] = (MATCH_MISSED_DETECTION, r, None) for h in details[MATCH_FALSE_ALARM]: track = errors.new_track(segment, prefix=MATCH_FALSE_ALARM) errors[segment, track] = (MATCH_FALSE_ALARM, None, h) if uemified: return reference, hypothesis, errors else: return errors