File size: 1,285 Bytes
fc329a3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
"""Size-stratified coverage metrics."""
import numpy as np


def size_stratified_coverage(
    covered: np.ndarray,
    radius: np.ndarray,
    n_bins: int = 5,
) -> dict[int, float]:
    """Coverage within radius/size bins.

    Bins are quantile-based to avoid empty tails when set sizes are skewed.
    """
    covered = np.asarray(covered, dtype=bool)
    radius = np.asarray(radius, dtype=float)

    if len(radius) == 0:
        return {}

    if np.allclose(radius, radius[0]):
        return {0: float(covered.mean())}

    quantiles = np.linspace(0.0, 1.0, n_bins + 1)
    edges = np.unique(np.quantile(radius, quantiles))
    if len(edges) <= 1:
        return {0: float(covered.mean())}

    bin_ids = np.digitize(radius, edges[1:-1], right=True)
    result = {}
    for b in np.unique(bin_ids):
        mask = bin_ids == b
        if mask.any():
            result[int(b)] = float(covered[mask].mean())
    return result


def size_stratified_coverage_violation(
    covered: np.ndarray,
    radius: np.ndarray,
    alpha: float,
    n_bins: int = 5,
) -> float:
    """Maximum coverage deviation across prediction-size bins."""
    sc = size_stratified_coverage(covered, radius, n_bins=n_bins)
    target = 1.0 - alpha
    return max(abs(v - target) for v in sc.values())