File size: 1,266 Bytes
4687353
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
from __future__ import annotations

from typing import Any, Dict

import numpy as np
from sklearn.metrics import average_precision_score, f1_score


def _safe_average_precision(y_true: np.ndarray, y_score: np.ndarray) -> float:
    if np.unique(y_true).size < 2:
        return 0.0
    return float(average_precision_score(y_true, y_score))


def compute_metrics(
    targets: np.ndarray,
    logits: np.ndarray,
    threshold: float = 0.5,
) -> Dict[str, Any]:
    probs = 1.0 / (1.0 + np.exp(-logits))
    preds = (probs >= threshold).astype(np.int32)
    per_attr_ap = []
    per_attr_f1 = []
    for idx in range(targets.shape[1]):
        yt = targets[:, idx]
        yp = preds[:, idx]
        ys = probs[:, idx]
        per_attr_ap.append(_safe_average_precision(yt, ys))
        per_attr_f1.append(float(f1_score(yt, yp, zero_division=0)))

    macro_f1 = float(f1_score(targets, preds, average="macro", zero_division=0))
    micro_f1 = float(f1_score(targets, preds, average="micro", zero_division=0))
    map_score = float(np.mean(per_attr_ap)) if per_attr_ap else 0.0
    return {
        "map": map_score,
        "macro_f1": macro_f1,
        "micro_f1": micro_f1,
        "per_attribute_ap": per_attr_ap,
        "per_attribute_f1": per_attr_f1,
    }