(y_pred: torch.Tensor, y: torch.Tensor)
| 73 | |
| 74 | |
| 75 | def _calculate(y_pred: torch.Tensor, y: torch.Tensor) -> float: |
| 76 | if not (y.ndimension() == y_pred.ndimension() == 1 and len(y) == len(y_pred)): |
| 77 | raise AssertionError("y and y_pred must be 1 dimension data with same length.") |
| 78 | y_unique = y.unique() |
| 79 | if len(y_unique) == 1: |
| 80 | warnings.warn(f"y values can not be all {y_unique.item()}, skip AUC computation and return `Nan`.") |
| 81 | return float("nan") |
| 82 | if not y_unique.equal(torch.tensor([0, 1], dtype=y.dtype, device=y.device)): |
| 83 | warnings.warn(f"y values must be 0 or 1, but in {y_unique.tolist()}, skip AUC computation and return `Nan`.") |
| 84 | return float("nan") |
| 85 | |
| 86 | n = len(y) |
| 87 | indices = y_pred.argsort() |
| 88 | y = y[indices].cpu().numpy() # type: ignore[assignment] |
| 89 | y_pred = y_pred[indices].cpu().numpy() # type: ignore[assignment] |
| 90 | nneg = auc = tmp_pos = tmp_neg = 0.0 |
| 91 | |
| 92 | for i in range(n): |
| 93 | y_i = cast(float, y[i]) |
| 94 | if i + 1 < n and y_pred[i] == y_pred[i + 1]: |
| 95 | tmp_pos += y_i |
| 96 | tmp_neg += 1 - y_i |
| 97 | continue |
| 98 | if tmp_pos + tmp_neg > 0: |
| 99 | tmp_pos += y_i |
| 100 | tmp_neg += 1 - y_i |
| 101 | nneg += tmp_neg |
| 102 | auc += tmp_pos * (nneg - tmp_neg / 2) |
| 103 | tmp_pos = tmp_neg = 0 |
| 104 | continue |
| 105 | if y_i == 1: |
| 106 | auc += nneg |
| 107 | else: |
| 108 | nneg += 1 |
| 109 | return auc / (nneg * (n - nneg)) |
| 110 | |
| 111 | |
| 112 | def compute_roc_auc( |
no outgoing calls
no test coverage detected
searching dependent graphs…