Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 12 additions & 13 deletions doc/source/pyplots/tutorial.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@

notebook.width = 10
plt.rcParams['figure.figsize'] = (notebook.width, 3)
plt.rcParams["figure.figsize"] = (notebook.width, 3)

# only display [0, 20] timerange
notebook.crop = Segment(0, 40)

# plot reference
plt.subplot(211)
reference = Annotation()
reference[Segment(0, 10)] = 'A'
reference[Segment(12, 20)] = 'B'
reference[Segment(24, 27)] = 'A'
reference[Segment(30, 40)] = 'C'
reference[Segment(0, 10)] = "A"
reference[Segment(12, 20)] = "B"
reference[Segment(24, 27)] = "A"
reference[Segment(30, 40)] = "C"
notebook.plot_annotation(reference, legend=True, time=False)
plt.gca().text(0.6, 0.15, 'reference', fontsize=16)
plt.gca().text(0.6, 0.15, "reference", fontsize=16)

# plot hypothesis
plt.subplot(212)
hypothesis = Annotation()
hypothesis[Segment(2, 13)] = 'a'
hypothesis[Segment(13, 14)] = 'd'
hypothesis[Segment(14, 20)] = 'b'
hypothesis[Segment(22, 38)] = 'c'
hypothesis[Segment(38, 40)] = 'd'
hypothesis[Segment(2, 13)] = "a"
hypothesis[Segment(13, 14)] = "d"
hypothesis[Segment(14, 20)] = "b"
hypothesis[Segment(22, 38)] = "c"
hypothesis[Segment(38, 40)] = "d"
notebook.plot_annotation(hypothesis, legend=True, time=True)
plt.gca().text(0.6, 0.15, 'hypothesis', fontsize=16)
plt.gca().text(0.6, 0.15, "hypothesis", fontsize=16)

plt.show()
1 change: 1 addition & 0 deletions src/pyannote/metrics/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from .base import f_measure

import importlib.metadata

__version__ = importlib.metadata.version("pyannote-metrics")

__all__ = ["f_measure"]
50 changes: 31 additions & 19 deletions src/pyannote/metrics/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ class BaseMetric:
def metric_name(cls) -> str:
raise NotImplementedError(
cls.__name__ + " is missing a 'metric_name' class method. "
"It should return the name of the metric as string."
"It should return the name of the metric as string."
)

@classmethod
def metric_components(cls) -> MetricComponents:
raise NotImplementedError(
cls.__name__ + " is missing a 'metric_components' class method. "
"It should return the list of names of metric components."
"It should return the list of names of metric components."
)

def __init__(self, **kwargs):
Expand All @@ -84,9 +84,14 @@ def name(self):
# TODO: use joblib/locky to allow parallel processing?
# TODO: signature could be something like __call__(self, reference_iterator, hypothesis_iterator, ...)

def __call__(self, reference: Union[Timeline, Annotation],
hypothesis: Union[Timeline, Annotation],
detailed: bool = False, uri: Optional[str] = None, **kwargs):
def __call__(
self,
reference: Union[Timeline, Annotation],
hypothesis: Union[Timeline, Annotation],
detailed: bool = False,
uri: Optional[str] = None,
**kwargs,
):
"""Compute metric value and accumulate components

Parameters
Expand Down Expand Up @@ -247,10 +252,12 @@ def __iter__(self):
for uri, component in self.results_:
yield uri, component

def compute_components(self,
reference: Union[Timeline, Annotation],
hypothesis: Union[Timeline, Annotation],
**kwargs) -> Details:
def compute_components(
self,
reference: Union[Timeline, Annotation],
hypothesis: Union[Timeline, Annotation],
**kwargs,
) -> Details:
"""Compute metric components

Parameters
Expand All @@ -269,8 +276,8 @@ def compute_components(self,
"""
raise NotImplementedError(
self.__class__.__name__ + " is missing a 'compute_components' method."
"It should return a dictionary where keys are component names "
"and values are component values."
"It should return a dictionary where keys are component names "
"and values are component values."
)

def compute_metric(self, components: Details):
Expand All @@ -289,12 +296,13 @@ def compute_metric(self, components: Details):
"""
raise NotImplementedError(
self.__class__.__name__ + " is missing a 'compute_metric' method. "
"It should return the actual value of the metric based "
"on the precomputed component dictionary given as input."
"It should return the actual value of the metric based "
"on the precomputed component dictionary given as input."
)

def confidence_interval(self, alpha: float = 0.9) \
-> Tuple[float, Tuple[float, float]]:
def confidence_interval(
self, alpha: float = 0.9
) -> Tuple[float, Tuple[float, float]]:
"""Compute confidence interval on accumulated metric values

Parameters
Expand All @@ -319,13 +327,17 @@ def confidence_interval(self, alpha: float = 0.9) \
values = [r[self.metric_name_] for _, r in self.results_]

if len(values) == 0:
raise ValueError("Please evaluate a bunch of files before computing confidence interval.")

raise ValueError(
"Please evaluate a bunch of files before computing confidence interval."
)

elif len(values) == 1:
warnings.warn("Cannot compute a reliable confidence interval out of just one file.")
warnings.warn(
"Cannot compute a reliable confidence interval out of just one file."
)
center = lower = upper = values[0]
return center, (lower, upper)

else:
return scipy.stats.bayes_mvs(values, alpha=alpha)[0]

Expand Down
2 changes: 2 additions & 0 deletions src/pyannote/metrics/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,12 @@

import numpy as np
import pandas as pd

# command line parsing
from docopt import docopt
from pyannote.core import Annotation
from pyannote.core import Timeline

# evaluation protocols
from pyannote.database import get_protocol
from pyannote.database.util import get_annotated
Expand Down
Loading