Skip to content

Functional

danling.metrics.functional

binary_accuracy

Bases: _BinaryConfmatMetric

Metric function version of binary accuracy.

Relies on a confusion matrix if available, otherwise falls back to torchmetrics’ functional binary accuracy implementation.

Source code in danling/metrics/functional/binary.py
Python
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
class binary_accuracy(_BinaryConfmatMetric):
    """
    Metric function version of binary accuracy.

    Relies on a confusion matrix if available, otherwise falls back to
    torchmetrics' functional binary accuracy implementation.
    """

    def __init__(self, threshold: float = 0.5, ignore_index: int | None = -100, *, name: Optional[str] = "acc") -> None:
        super().__init__(threshold=threshold, ignore_index=ignore_index, name=name)

    def __call__(self, state: MetricState) -> Tensor | float:
        confmat = state.confmat
        if confmat is None:
            return self._fallback(state, tm_binary_accuracy)

        correct = torch.diag(confmat).sum()
        total = confmat.sum()
        return correct / total if total > 0 else torch.tensor(float("nan"), device=confmat.device)

binary_auprc

Bases: _BinaryMetricBase

Metric function version of binary AUPRC.

Source code in danling/metrics/functional/binary.py
Python
128
129
130
131
132
133
134
135
136
137
138
139
class binary_auprc(_BinaryMetricBase):
    """
    Metric function version of binary AUPRC.
    """

    def __init__(self, ignore_index: int | None = -100, *, name: Optional[str] = "auprc") -> None:
        super().__init__(name=name, preds_targets=True, ignore_index=ignore_index)

    def __call__(self, state: MetricState) -> Tensor | float:
        if self._is_empty(state):
            return self._nan()
        return tm_binary_auprc(state.preds, state.targets, ignore_index=self.ignore_index)

binary_auroc

Bases: _BinaryMetricBase

Metric function version of binary AUROC.

Requires raw predictions and targets; does not use confusion matrix.

Source code in danling/metrics/functional/binary.py
Python
112
113
114
115
116
117
118
119
120
121
122
123
124
125
class binary_auroc(_BinaryMetricBase):
    """
    Metric function version of binary AUROC.

    Requires raw predictions and targets; does not use confusion matrix.
    """

    def __init__(self, ignore_index: int | None = -100, *, name: Optional[str] = "auroc") -> None:
        super().__init__(name=name, preds_targets=True, ignore_index=ignore_index)

    def __call__(self, state: MetricState) -> Tensor | float:
        if self._is_empty(state):
            return self._nan()
        return tm_binary_auroc(state.preds, state.targets, ignore_index=self.ignore_index)

binary_balanced_accuracy

Bases: _BinaryConfmatMetric

Metric function version of binary balanced accuracy.

Source code in danling/metrics/functional/binary.py
Python
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
class binary_balanced_accuracy(_BinaryConfmatMetric):
    """
    Metric function version of binary balanced accuracy.
    """

    def __init__(
        self, threshold: float = 0.5, ignore_index: int | None = -100, *, name: Optional[str] = "balanced_accuracy"
    ) -> None:
        super().__init__(threshold=threshold, ignore_index=ignore_index, name=name)

    def __call__(self, state: MetricState) -> Tensor | float:
        confmat = state.confmat
        if confmat is None:
            recall = self._fallback(state, tm_binary_recall)
            specificity = self._fallback(state, tm_binary_specificity)
            return 0.5 * (recall + specificity)

        tp = confmat[1, 1]
        fn = confmat[1, 0]
        tn = confmat[0, 0]
        fp = confmat[0, 1]
        tpr = tp / (tp + fn).clamp(min=1)
        tnr = tn / (tn + fp).clamp(min=1)
        return 0.5 * (tpr + tnr)

binary_f1

Bases: binary_fbeta

Metric function version of binary F1 score.

Source code in danling/metrics/functional/binary.py
Python
312
313
314
315
316
317
318
class binary_f1(binary_fbeta):
    """
    Metric function version of binary F1 score.
    """

    def __init__(self, threshold: float = 0.5, ignore_index: int | None = -100, *, name: Optional[str] = "f1") -> None:
        super().__init__(beta=1.0, threshold=threshold, ignore_index=ignore_index, name=name)

binary_fbeta

Bases: _BinaryConfmatMetric

Metric function version of binary F-beta score.

Source code in danling/metrics/functional/binary.py
Python
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
class binary_fbeta(_BinaryConfmatMetric):
    """
    Metric function version of binary F-beta score.
    """

    def __init__(
        self,
        beta: float = 1.0,
        threshold: float = 0.5,
        ignore_index: int | None = -100,
        *,
        name: Optional[str] = "fbeta",
    ) -> None:
        self.beta = beta
        super().__init__(threshold=threshold, ignore_index=ignore_index, name=name)

    def __call__(self, state: MetricState) -> Tensor | float:
        confmat = state.confmat
        if confmat is None:
            return self._fallback(state, tm_binary_fbeta, beta=self.beta)

        tp = confmat[1, 1]
        fp = confmat[0, 1]
        fn = confmat[1, 0]
        beta_square = self.beta * self.beta
        numerator = (1 + beta_square) * tp
        denominator = numerator + beta_square * fn + fp
        return numerator / denominator.clamp(min=1)

binary_hamming_loss

Bases: _BinaryConfmatMetric

Metric function version of binary hamming loss.

Source code in danling/metrics/functional/binary.py
Python
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
class binary_hamming_loss(_BinaryConfmatMetric):
    """
    Metric function version of binary hamming loss.
    """

    def __init__(
        self, threshold: float = 0.5, ignore_index: int | None = -100, *, name: Optional[str] = "hamming_loss"
    ) -> None:
        super().__init__(threshold=threshold, ignore_index=ignore_index, name=name)

    def __call__(self, state: MetricState) -> Tensor | float:
        confmat = state.confmat
        if confmat is None:
            return self._fallback(state, tm_binary_hamming_loss)

        fp = confmat[0, 1]
        fn = confmat[1, 0]
        total = confmat.sum()
        return (fp + fn) / total if total > 0 else torch.tensor(float("nan"), device=confmat.device)

binary_iou

Bases: binary_jaccard_index

Alias of binary Jaccard index.

Source code in danling/metrics/functional/binary.py
Python
252
253
254
255
256
257
258
class binary_iou(binary_jaccard_index):
    """
    Alias of binary Jaccard index.
    """

    def __init__(self, threshold: float = 0.5, ignore_index: int | None = -100, *, name: Optional[str] = "iou") -> None:
        super().__init__(threshold=threshold, ignore_index=ignore_index, name=name)

binary_jaccard_index

Bases: _BinaryConfmatMetric

Metric function version of binary Jaccard index (IoU).

Source code in danling/metrics/functional/binary.py
Python
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
class binary_jaccard_index(_BinaryConfmatMetric):
    """
    Metric function version of binary Jaccard index (IoU).
    """

    def __init__(
        self, threshold: float = 0.5, ignore_index: int | None = -100, *, name: Optional[str] = "jaccard"
    ) -> None:
        super().__init__(threshold=threshold, ignore_index=ignore_index, name=name)

    def __call__(self, state: MetricState) -> Tensor | float:
        confmat = state.confmat
        if confmat is None:
            return self._fallback(state, tm_binary_jaccard_index)

        tp = confmat[1, 1]
        fp = confmat[0, 1]
        fn = confmat[1, 0]
        return tp / (tp + fp + fn).clamp(min=1)

binary_precision

Bases: _BinaryConfmatMetric

Metric function version of binary precision.

Source code in danling/metrics/functional/binary.py
Python
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
class binary_precision(_BinaryConfmatMetric):
    """
    Metric function version of binary precision.
    """

    def __init__(
        self, threshold: float = 0.5, ignore_index: int | None = -100, *, name: Optional[str] = "precision"
    ) -> None:
        super().__init__(threshold=threshold, ignore_index=ignore_index, name=name)

    def __call__(self, state: MetricState) -> Tensor | float:
        confmat = state.confmat
        if confmat is None:
            return self._fallback(state, tm_binary_precision)

        tp = confmat[1, 1]
        fp = confmat[0, 1]
        denom = (tp + fp).clamp(min=1)
        return tp / denom

binary_recall

Bases: _BinaryConfmatMetric

Metric function version of binary recall.

Source code in danling/metrics/functional/binary.py
Python
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
class binary_recall(_BinaryConfmatMetric):
    """
    Metric function version of binary recall.
    """

    def __init__(
        self, threshold: float = 0.5, ignore_index: int | None = -100, *, name: Optional[str] = "recall"
    ) -> None:
        super().__init__(threshold=threshold, ignore_index=ignore_index, name=name)

    def __call__(self, state: MetricState) -> Tensor | float:
        confmat = state.confmat
        if confmat is None:
            return self._fallback(state, tm_binary_recall)

        tp = confmat[1, 1]
        fn = confmat[1, 0]
        denom = (tp + fn).clamp(min=1)
        return tp / denom

binary_specificity

Bases: _BinaryConfmatMetric

Metric function version of binary specificity.

Source code in danling/metrics/functional/binary.py
Python
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
class binary_specificity(_BinaryConfmatMetric):
    """
    Metric function version of binary specificity.
    """

    def __init__(
        self, threshold: float = 0.5, ignore_index: int | None = -100, *, name: Optional[str] = "specificity"
    ) -> None:
        super().__init__(threshold=threshold, ignore_index=ignore_index, name=name)

    def __call__(self, state: MetricState) -> Tensor | float:
        confmat = state.confmat
        if confmat is None:
            return self._fallback(state, tm_binary_specificity)

        tn = confmat[0, 0]
        fp = confmat[0, 1]
        denom = (tn + fp).clamp(min=1)
        return tn / denom

multiclass_balanced_accuracy

Bases: MetricFunc

Metric function version of multiclass balanced accuracy.

For multiclass classification, balanced accuracy is the class-balanced recall. Only the standard multiclass definition is supported: average="macro" with k=1.

Source code in danling/metrics/functional/multiclass.py
Python
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
class multiclass_balanced_accuracy(MetricFunc):
    """
    Metric function version of multiclass balanced accuracy.

    For multiclass classification, balanced accuracy is the class-balanced recall.
    Only the standard multiclass definition is supported: `average="macro"` with `k=1`.
    """

    def __init__(
        self,
        num_classes: int,
        average: str | None = "macro",
        k: int = 1,
        ignore_index: int | None = -100,
        *,
        name: Optional[str] = "balanced_accuracy",
    ) -> None:
        require_standard_multiclass_balanced_accuracy(average, k)
        self.num_classes = num_classes
        self.average = average
        self.k = k
        self.ignore_index = ignore_index
        super().__init__(
            name=name,
            preds_targets=False,
            confmat=True,
            task="multiclass",
            num_classes=num_classes,
            ignore_index=ignore_index,
        )

    def __call__(self, state: MetricState) -> Tensor | float:
        confmat = state.confmat
        if confmat is not None:
            tp, fp, fn, _, support, _ = state.multiclass_stats
            return reduce_ratio_metric(tp, tp + fn, self.average, support, present=_present_mask(support, fp))

        return _call_tm_multiclass(
            state,
            tmcls.multiclass_recall,
            num_classes=self.num_classes,
            ignore_index=self.ignore_index,
            average=self.average,
            top_k=self.k,
            use_average=True,
            use_top_k=True,
        )

MetricFunc

Base class for metric functions with declared state requirements.

Metric functions behave like callables via __call__ and carry metadata so that metrics containers know which shared state to maintain.

Source code in danling/metrics/functional/utils.py
Python
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
class MetricFunc:
    """
    Base class for metric functions with declared state requirements.

    Metric functions behave like callables via ``__call__`` and carry metadata
    so that metrics containers know which shared state to maintain.
    """

    name: str = ""
    preds_targets: bool = False
    confmat: bool = False
    task: str | None = None
    num_classes: int | None = None
    num_labels: int | None = None
    threshold: float | None = None
    ignore_index: int | None = None

    def __init__(
        self,
        *,
        name: str | None = None,
        preds_targets: bool = False,
        confmat: bool = False,
        task: str | None = None,
        num_classes: int | None = None,
        num_labels: int | None = None,
        threshold: float | None = None,
        ignore_index: int | None = None,
    ) -> None:
        self.name = name or self.name or self.__class__.__name__
        self.preds_targets = preds_targets
        self.confmat = confmat
        self.task = task
        self.num_classes = num_classes
        self.num_labels = num_labels
        self.threshold = threshold
        self.ignore_index = ignore_index

    def __call__(self, state: MetricState) -> Tensor | float:  # pragma: no cover - interface stub
        raise NotImplementedError