bioimage_py.evaluation.rand_index
Rand-index derived scores: the adapted rand error and the rand index.
Both are pure reductions of a ContingencyTable; the result is symmetric in the two
segmentations, so the table orientation does not matter.
1"""Rand-index derived scores: the adapted rand error and the rand index. 2 3Both are pure reductions of a :class:`ContingencyTable`; the result is symmetric in the two 4segmentations, so the table orientation does not matter. 5""" 6from __future__ import annotations 7 8from typing import Optional, Sequence, Tuple 9 10import numpy as np 11 12from ..runner.config import RunnerConfig 13from ..sources import SourceLike 14from ._common import build_table 15from .contingency_table import ContingencyTable 16 17__all__ = ["rand_scores", "rand_index"] 18 19 20def rand_scores(table: ContingencyTable) -> Tuple[float, float]: 21 """Compute the adapted rand error and the rand index from a contingency table. 22 23 Args: 24 table: A contingency table for the two segmentations. 25 26 Returns: 27 The adapted rand error and the rand index. 28 """ 29 n = table.n_points 30 if n == 0: 31 return 0.0, 1.0 32 sum_a2 = float(np.sum(table.sizes_a.astype("float64") ** 2)) 33 sum_b2 = float(np.sum(table.sizes_b.astype("float64") ** 2)) 34 sum_ab2 = float(np.sum(table.counts.astype("float64") ** 2)) 35 36 precision = sum_ab2 / sum_a2 37 recall = sum_ab2 / sum_b2 38 adapted_rand_error = 1.0 - (2 * precision * recall) / (precision + recall) 39 rand_index = 1.0 - (sum_a2 + sum_b2 - 2 * sum_ab2) / (n * n) 40 return float(adapted_rand_error), float(rand_index) 41 42 43def rand_index( 44 segmentation: SourceLike, 45 groundtruth: SourceLike, 46 *, 47 ignore_seg: Optional[Sequence[int]] = None, 48 ignore_gt: Optional[Sequence[int]] = None, 49 num_workers: int = 1, 50 block_shape: Optional[Tuple[int, ...]] = None, 51 job_type: str = "local", 52 job_config: Optional[RunnerConfig] = None, 53 mask: Optional[SourceLike] = None, 54) -> Tuple[float, float]: 55 """Compute the adapted rand error and the rand index between two segmentations. 56 57 Args: 58 segmentation: Candidate segmentation to evaluate (a numpy/zarr/n5 array or a `Source`). 59 groundtruth: The groundtruth segmentation; same shape as ``segmentation``. 60 ignore_seg: Labels to ignore in the segmentation (their voxels are excluded). 61 ignore_gt: Labels to ignore in the groundtruth (their voxels are excluded). 62 num_workers: Number of parallel workers used to build the contingency table. 63 block_shape: Shape of the processing blocks. Defaults to the input chunk shape. 64 job_type: Execution backend: one of ``"local"``, ``"subprocess"`` or ``"slurm"``. 65 job_config: Backend configuration (a `RunnerConfig` / `SlurmConfig`). 66 mask: Optional binary mask; voxels outside the mask are excluded. 67 68 Returns: 69 The adapted rand error and the rand index. 70 """ 71 table = build_table(segmentation, groundtruth, ignore_seg=ignore_seg, ignore_gt=ignore_gt, 72 num_workers=num_workers, block_shape=block_shape, job_type=job_type, 73 job_config=job_config, mask=mask) 74 return rand_scores(table)
21def rand_scores(table: ContingencyTable) -> Tuple[float, float]: 22 """Compute the adapted rand error and the rand index from a contingency table. 23 24 Args: 25 table: A contingency table for the two segmentations. 26 27 Returns: 28 The adapted rand error and the rand index. 29 """ 30 n = table.n_points 31 if n == 0: 32 return 0.0, 1.0 33 sum_a2 = float(np.sum(table.sizes_a.astype("float64") ** 2)) 34 sum_b2 = float(np.sum(table.sizes_b.astype("float64") ** 2)) 35 sum_ab2 = float(np.sum(table.counts.astype("float64") ** 2)) 36 37 precision = sum_ab2 / sum_a2 38 recall = sum_ab2 / sum_b2 39 adapted_rand_error = 1.0 - (2 * precision * recall) / (precision + recall) 40 rand_index = 1.0 - (sum_a2 + sum_b2 - 2 * sum_ab2) / (n * n) 41 return float(adapted_rand_error), float(rand_index)
Compute the adapted rand error and the rand index from a contingency table.
Args: table: A contingency table for the two segmentations.
Returns: The adapted rand error and the rand index.
44def rand_index( 45 segmentation: SourceLike, 46 groundtruth: SourceLike, 47 *, 48 ignore_seg: Optional[Sequence[int]] = None, 49 ignore_gt: Optional[Sequence[int]] = None, 50 num_workers: int = 1, 51 block_shape: Optional[Tuple[int, ...]] = None, 52 job_type: str = "local", 53 job_config: Optional[RunnerConfig] = None, 54 mask: Optional[SourceLike] = None, 55) -> Tuple[float, float]: 56 """Compute the adapted rand error and the rand index between two segmentations. 57 58 Args: 59 segmentation: Candidate segmentation to evaluate (a numpy/zarr/n5 array or a `Source`). 60 groundtruth: The groundtruth segmentation; same shape as ``segmentation``. 61 ignore_seg: Labels to ignore in the segmentation (their voxels are excluded). 62 ignore_gt: Labels to ignore in the groundtruth (their voxels are excluded). 63 num_workers: Number of parallel workers used to build the contingency table. 64 block_shape: Shape of the processing blocks. Defaults to the input chunk shape. 65 job_type: Execution backend: one of ``"local"``, ``"subprocess"`` or ``"slurm"``. 66 job_config: Backend configuration (a `RunnerConfig` / `SlurmConfig`). 67 mask: Optional binary mask; voxels outside the mask are excluded. 68 69 Returns: 70 The adapted rand error and the rand index. 71 """ 72 table = build_table(segmentation, groundtruth, ignore_seg=ignore_seg, ignore_gt=ignore_gt, 73 num_workers=num_workers, block_shape=block_shape, job_type=job_type, 74 job_config=job_config, mask=mask) 75 return rand_scores(table)
Compute the adapted rand error and the rand index between two segmentations.
Args:
segmentation: Candidate segmentation to evaluate (a numpy/zarr/n5 array or a Source).
groundtruth: The groundtruth segmentation; same shape as segmentation.
ignore_seg: Labels to ignore in the segmentation (their voxels are excluded).
ignore_gt: Labels to ignore in the groundtruth (their voxels are excluded).
num_workers: Number of parallel workers used to build the contingency table.
block_shape: Shape of the processing blocks. Defaults to the input chunk shape.
job_type: Execution backend: one of "local", "subprocess" or "slurm".
job_config: Backend configuration (a RunnerConfig / SlurmConfig).
mask: Optional binary mask; voxels outside the mask are excluded.
Returns: The adapted rand error and the rand index.