Evaluation metrics for highFIS estimators.
This module provides a small, sklearn-style evaluation API for both
regression and classification tasks.
Classification Metrics
accuracy: standard accuracy score
balanced_accuracy: average recall over classes
precision_macro: macro-averaged precision
recall_macro: macro-averaged recall
f1_macro: macro-averaged F1 score
precision_micro: micro-averaged precision
recall_micro: micro-averaged recall
f1_micro: micro-averaged F1 score
confusion_matrix: confusion matrix by class
classes: sorted union of true and predicted labels
Regression Metrics
mse: mean squared error
mae: mean absolute error
rmse: root mean squared error
r2: coefficient of determination
median_absolute_error: median absolute error
mean_bias_error: average prediction bias
max_error: maximum absolute error
std_error: standard deviation of residuals
explained_variance: explained variance score
mape: mean absolute percentage error
smape: symmetric mean absolute percentage error
msle: mean squared logarithmic error
pearson: Pearson correlation coefficient
Notes
- The module exports
compute_metrics and the helper classes
ClassificationMetrics and RegressionMetrics.
compute_metrics validates metric names and returns only the
requested subset.
- All metrics accept raw array-like inputs and flatten non-1D arrays.
ClassificationMetrics
Standard classification metrics.
accuracy
staticmethod
Return classification accuracy.
Source code in highfis/metrics.py
| @staticmethod
def accuracy(y_true: Any, y_pred: Any, sample_weight: Any | None = None) -> float:
"""Return classification accuracy."""
return float(accuracy_score(y_true, y_pred, sample_weight=sample_weight))
|
balanced_accuracy
staticmethod
Return the balanced accuracy score.
Source code in highfis/metrics.py
| @staticmethod
def balanced_accuracy(y_true: Any, y_pred: Any, sample_weight: Any | None = None) -> float:
"""Return the balanced accuracy score."""
return float(balanced_accuracy_score(y_true, y_pred, sample_weight=sample_weight))
|
classes
staticmethod
Return the sorted set of predicted and true classes.
Note
sample_weight is ignored.
Source code in highfis/metrics.py
| @staticmethod
def classes(
y_true: Any,
y_pred: Any,
sample_weight: Any | None = None,
) -> np.ndarray:
"""Return the sorted set of predicted and true classes.
Note:
``sample_weight`` is ignored.
"""
if sample_weight is not None:
warnings.warn("sample_weight is ignored by classes", UserWarning, stacklevel=2)
y_true_arr = _flatten_array(y_true)
y_pred_arr = _flatten_array(y_pred)
return np.unique(np.concatenate([y_true_arr, y_pred_arr]))
|
confusion_matrix
staticmethod
Return the confusion matrix for the predictions.
Source code in highfis/metrics.py
| @staticmethod
def confusion_matrix(
y_true: Any,
y_pred: Any,
sample_weight: Any | None = None,
) -> np.ndarray:
"""Return the confusion matrix for the predictions."""
y_true_arr = _flatten_array(y_true)
y_pred_arr = _flatten_array(y_pred)
return confusion_matrix(y_true_arr, y_pred_arr, sample_weight=sample_weight)
|
f1_macro
staticmethod
Return macro-averaged F1 score.
Source code in highfis/metrics.py
| @staticmethod
def f1_macro(y_true: Any, y_pred: Any, sample_weight: Any | None = None) -> float:
"""Return macro-averaged F1 score."""
return float(f1_score(y_true, y_pred, average="macro", zero_division=0, sample_weight=sample_weight))
|
f1_micro
staticmethod
Return micro-averaged F1 score.
Source code in highfis/metrics.py
| @staticmethod
def f1_micro(y_true: Any, y_pred: Any, sample_weight: Any | None = None) -> float:
"""Return micro-averaged F1 score."""
return float(f1_score(y_true, y_pred, average="micro", zero_division=0, sample_weight=sample_weight))
|
precision_macro
staticmethod
Return macro-averaged precision.
Source code in highfis/metrics.py
| @staticmethod
def precision_macro(y_true: Any, y_pred: Any, sample_weight: Any | None = None) -> float:
"""Return macro-averaged precision."""
return float(precision_score(y_true, y_pred, average="macro", zero_division=0, sample_weight=sample_weight))
|
precision_micro
staticmethod
Return micro-averaged precision.
Source code in highfis/metrics.py
| @staticmethod
def precision_micro(y_true: Any, y_pred: Any, sample_weight: Any | None = None) -> float:
"""Return micro-averaged precision."""
return float(precision_score(y_true, y_pred, average="micro", zero_division=0, sample_weight=sample_weight))
|
recall_macro
staticmethod
Return macro-averaged recall.
Source code in highfis/metrics.py
| @staticmethod
def recall_macro(y_true: Any, y_pred: Any, sample_weight: Any | None = None) -> float:
"""Return macro-averaged recall."""
return float(recall_score(y_true, y_pred, average="macro", zero_division=0, sample_weight=sample_weight))
|
recall_micro
staticmethod
Return micro-averaged recall.
Source code in highfis/metrics.py
| @staticmethod
def recall_micro(y_true: Any, y_pred: Any, sample_weight: Any | None = None) -> float:
"""Return micro-averaged recall."""
return float(recall_score(y_true, y_pred, average="micro", zero_division=0, sample_weight=sample_weight))
|
ClassificationMetricsPytorch
Standard classification metrics using PyTorch.
accuracy
staticmethod
Return classification accuracy.
Source code in highfis/metrics.py
| @staticmethod
def accuracy(y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None) -> float:
"""Return classification accuracy."""
if sample_weight is not None:
return (torch.sum((y_true == y_pred).float() * sample_weight) / torch.sum(sample_weight)).item()
return torch.mean((y_true == y_pred).float()).item()
|
balanced_accuracy
staticmethod
Return the balanced accuracy score.
Source code in highfis/metrics.py
| @staticmethod
def balanced_accuracy(
y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None
) -> float:
"""Return the balanced accuracy score."""
classes = torch.unique(y_true)
recalls = []
for c in classes:
true_c = y_true == c
if sample_weight is not None:
w_c = sample_weight[true_c]
den = torch.sum(w_c)
if den == 0:
recalls.append(torch.tensor(0.0, device=y_true.device))
else:
recalls.append(torch.sum((y_pred[true_c] == c).float() * w_c) / den)
else:
recalls.append(torch.mean((y_pred[true_c] == c).float()))
return torch.stack(recalls).mean().item() if recalls else 0.0
|
classes
staticmethod
Return the sorted union of true and predicted labels.
Note
sample_weight is ignored.
Source code in highfis/metrics.py
| @staticmethod
def classes(y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None) -> np.ndarray:
"""Return the sorted union of true and predicted labels.
Note:
``sample_weight`` is ignored.
"""
if sample_weight is not None:
warnings.warn("sample_weight is ignored by classes", UserWarning, stacklevel=2)
return torch.unique(torch.cat([y_true, y_pred])).cpu().numpy()
|
confusion_matrix
staticmethod
Return the confusion matrix.
Source code in highfis/metrics.py
| @staticmethod
def confusion_matrix(
y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None
) -> np.ndarray:
"""Return the confusion matrix."""
classes, inverse = torch.unique(torch.cat([y_true, y_pred]), return_inverse=True)
n_classes = len(classes)
y_true_idx = inverse[: len(y_true)]
y_pred_idx = inverse[len(y_true) :]
indices = y_true_idx * n_classes + y_pred_idx
if sample_weight is not None:
cm = torch.bincount(indices, weights=sample_weight, minlength=n_classes**2)
else:
cm = torch.bincount(indices, minlength=n_classes**2)
return cm.reshape(n_classes, n_classes).cpu().numpy()
|
f1_macro
staticmethod
Return macro-averaged F1 score.
Source code in highfis/metrics.py
| @staticmethod
def f1_macro(y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None) -> float:
"""Return macro-averaged F1 score."""
_, _, f1 = ClassificationMetricsPytorch._precision_recall_f1_macro(y_true, y_pred, sample_weight)
return f1.item()
|
f1_micro
staticmethod
Return micro-averaged F1 score.
Source code in highfis/metrics.py
| @staticmethod
def f1_micro(y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None) -> float:
"""Return micro-averaged F1 score."""
_, _, f1 = ClassificationMetricsPytorch._precision_recall_f1_micro(y_true, y_pred, sample_weight)
return f1.item()
|
precision_macro
staticmethod
Return macro-averaged precision.
Source code in highfis/metrics.py
| @staticmethod
def precision_macro(y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None) -> float:
"""Return macro-averaged precision."""
prec, _, _ = ClassificationMetricsPytorch._precision_recall_f1_macro(y_true, y_pred, sample_weight)
return prec.item()
|
precision_micro
staticmethod
Return micro-averaged precision.
Source code in highfis/metrics.py
| @staticmethod
def precision_micro(y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None) -> float:
"""Return micro-averaged precision."""
prec, _, _ = ClassificationMetricsPytorch._precision_recall_f1_micro(y_true, y_pred, sample_weight)
return prec.item()
|
recall_macro
staticmethod
Return macro-averaged recall.
Source code in highfis/metrics.py
| @staticmethod
def recall_macro(y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None) -> float:
"""Return macro-averaged recall."""
_, rec, _ = ClassificationMetricsPytorch._precision_recall_f1_macro(y_true, y_pred, sample_weight)
return rec.item()
|
recall_micro
staticmethod
Return micro-averaged recall.
Source code in highfis/metrics.py
| @staticmethod
def recall_micro(y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None) -> float:
"""Return micro-averaged recall."""
_, rec, _ = ClassificationMetricsPytorch._precision_recall_f1_micro(y_true, y_pred, sample_weight)
return rec.item()
|
RegressionMetrics
Standard regression metrics.
explained_variance
staticmethod
Return explained variance.
Source code in highfis/metrics.py
| @staticmethod
def explained_variance(y_true: Any, y_pred: Any, sample_weight: Any | None = None) -> float:
"""Return explained variance."""
return float(explained_variance_score(y_true, y_pred, sample_weight=sample_weight))
|
mae
staticmethod
Return mean absolute error.
Source code in highfis/metrics.py
| @staticmethod
def mae(y_true: Any, y_pred: Any, sample_weight: Any | None = None) -> float:
"""Return mean absolute error."""
return float(mean_absolute_error(y_true, y_pred, sample_weight=sample_weight))
|
mape
staticmethod
Return mean absolute percentage error.
Source code in highfis/metrics.py
| @staticmethod
def mape(y_true: Any, y_pred: Any, sample_weight: Any | None = None) -> float:
"""Return mean absolute percentage error."""
return float(mean_absolute_percentage_error(y_true, y_pred, sample_weight=sample_weight))
|
max_error
staticmethod
Return maximum absolute error.
Note
sample_weight is ignored.
Source code in highfis/metrics.py
| @staticmethod
def max_error(y_true: Any, y_pred: Any, sample_weight: Any | None = None) -> float:
"""Return maximum absolute error.
Note:
``sample_weight`` is ignored.
"""
if sample_weight is not None:
warnings.warn("sample_weight is ignored by max_error", UserWarning, stacklevel=2)
return float(max_error(y_true, y_pred))
|
mean_bias_error
staticmethod
Return mean bias error (prediction minus truth).
Source code in highfis/metrics.py
| @staticmethod
def mean_bias_error(y_true: Any, y_pred: Any, sample_weight: Any | None = None) -> float:
"""Return mean bias error (prediction minus truth)."""
y_true_arr = _flatten_array(y_true)
y_pred_arr = _flatten_array(y_pred)
if sample_weight is not None:
return float(np.average(y_pred_arr - y_true_arr, weights=sample_weight))
return float(np.mean(y_pred_arr - y_true_arr))
|
Return median absolute error.
Source code in highfis/metrics.py
| @staticmethod
def median_absolute_error(y_true: Any, y_pred: Any, sample_weight: Any | None = None) -> float:
"""Return median absolute error."""
return float(median_absolute_error(y_true, y_pred, sample_weight=sample_weight))
|
mse
staticmethod
Return mean squared error.
Source code in highfis/metrics.py
| @staticmethod
def mse(y_true: Any, y_pred: Any, sample_weight: Any | None = None) -> float:
"""Return mean squared error."""
return float(mean_squared_error(y_true, y_pred, sample_weight=sample_weight))
|
msle
staticmethod
Return mean squared logarithmic error.
Source code in highfis/metrics.py
| @staticmethod
def msle(y_true: Any, y_pred: Any, sample_weight: Any | None = None) -> float:
"""Return mean squared logarithmic error."""
try:
return float(mean_squared_log_error(y_true, y_pred, sample_weight=sample_weight))
except ValueError:
return float(np.nan)
|
pearson
staticmethod
Return Pearson correlation coefficient.
Note
sample_weight is ignored.
Source code in highfis/metrics.py
| @staticmethod
def pearson(y_true: Any, y_pred: Any, sample_weight: Any | None = None) -> float:
"""Return Pearson correlation coefficient.
Note:
``sample_weight`` is ignored.
"""
if sample_weight is not None:
warnings.warn("sample_weight is ignored by pearson", UserWarning, stacklevel=2)
y_true_arr = _flatten_array(y_true)
y_pred_arr = _flatten_array(y_pred)
if y_true_arr.size < 2 or np.std(y_true_arr) == 0 or np.std(y_pred_arr) == 0:
return float(np.nan)
with np.errstate(invalid="ignore", divide="ignore"):
return float(np.corrcoef(y_true_arr, y_pred_arr)[0, 1])
|
r2
staticmethod
Return coefficient of determination (R²).
Source code in highfis/metrics.py
| @staticmethod
def r2(y_true: Any, y_pred: Any, sample_weight: Any | None = None) -> float:
"""Return coefficient of determination (R²)."""
return float(r2_score(y_true, y_pred, sample_weight=sample_weight))
|
rmse
staticmethod
Return root mean squared error.
Source code in highfis/metrics.py
| @staticmethod
def rmse(y_true: Any, y_pred: Any, sample_weight: Any | None = None) -> float:
"""Return root mean squared error."""
return float(np.sqrt(mean_squared_error(y_true, y_pred, sample_weight=sample_weight)))
|
smape
staticmethod
Return symmetric mean absolute percentage error.
Source code in highfis/metrics.py
| @staticmethod
def smape(y_true: Any, y_pred: Any, sample_weight: Any | None = None) -> float:
"""Return symmetric mean absolute percentage error."""
y_true_arr = _flatten_array(y_true)
y_pred_arr = _flatten_array(y_pred)
numerator = np.abs(y_pred_arr - y_true_arr) * 2.0
denominator = np.abs(y_true_arr) + np.abs(y_pred_arr)
with np.errstate(divide="ignore", invalid="ignore"):
ratio = np.where(denominator == 0.0, 0.0, numerator / denominator)
if sample_weight is not None:
return float(np.average(ratio, weights=sample_weight))
return float(np.mean(ratio))
|
std_error
staticmethod
Return the standard deviation of the errors.
Note
sample_weight is ignored.
Source code in highfis/metrics.py
| @staticmethod
def std_error(y_true: Any, y_pred: Any, sample_weight: Any | None = None) -> float:
"""Return the standard deviation of the errors.
Note:
``sample_weight`` is ignored.
"""
if sample_weight is not None:
warnings.warn("sample_weight is ignored by std_error", UserWarning, stacklevel=2)
y_true_arr = _flatten_array(y_true)
y_pred_arr = _flatten_array(y_pred)
if y_true_arr.size < 2:
return 0.0
return float(np.std(y_pred_arr - y_true_arr, ddof=1))
|
RegressionMetricsPytorch
Standard regression metrics using PyTorch.
explained_variance
staticmethod
Return explained variance.
Note
Uses biased variance (unbiased=False) to match scikit-learn's
explained_variance_score implementation.
Source code in highfis/metrics.py
| @staticmethod
def explained_variance(
y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None
) -> float:
"""Return explained variance.
Note:
Uses biased variance (unbiased=False) to match scikit-learn's
explained_variance_score implementation.
"""
y_true = y_true.float()
y_pred = y_pred.float()
if sample_weight is not None:
sample_weight = sample_weight.float()
mean_diff = torch.sum((y_true - y_pred) * sample_weight) / torch.sum(sample_weight)
var_diff = torch.sum(((y_true - y_pred - mean_diff) ** 2) * sample_weight) / torch.sum(sample_weight)
mean_y = torch.sum(y_true * sample_weight) / torch.sum(sample_weight)
var_y = torch.sum(((y_true - mean_y) ** 2) * sample_weight) / torch.sum(sample_weight)
else:
var_diff = torch.var(y_true - y_pred, unbiased=False)
var_y = torch.var(y_true, unbiased=False)
return (1.0 - var_diff / var_y).item() if var_y > 0 else 0.0
|
mae
staticmethod
Return mean absolute error.
Source code in highfis/metrics.py
| @staticmethod
def mae(y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None) -> float:
"""Return mean absolute error."""
y_true = y_true.float()
y_pred = y_pred.float()
if sample_weight is not None:
sample_weight = sample_weight.float()
return (torch.sum(torch.abs(y_true - y_pred) * sample_weight) / torch.sum(sample_weight)).item()
return torch.mean(torch.abs(y_true - y_pred)).item()
|
mape
staticmethod
Return mean absolute percentage error.
Source code in highfis/metrics.py
| @staticmethod
def mape(y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None) -> float:
"""Return mean absolute percentage error."""
y_true = y_true.float()
y_pred = y_pred.float()
eps = torch.finfo(y_true.dtype).eps
ratio = torch.abs(y_true - y_pred) / torch.clamp(torch.abs(y_true), min=eps)
if sample_weight is not None:
sample_weight = sample_weight.float()
return (torch.sum(ratio * sample_weight) / torch.sum(sample_weight)).item()
return torch.mean(ratio).item()
|
max_error
staticmethod
Return maximum absolute error.
Note
sample_weight is ignored.
Source code in highfis/metrics.py
| @staticmethod
def max_error(y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None) -> float:
"""Return maximum absolute error.
Note:
``sample_weight`` is ignored.
"""
y_true = y_true.float()
y_pred = y_pred.float()
if sample_weight is not None:
sample_weight = sample_weight.float()
warnings.warn("sample_weight is ignored by max_error", UserWarning, stacklevel=2)
return torch.max(torch.abs(y_true - y_pred)).item()
|
mean_bias_error
staticmethod
Return mean bias error (prediction minus truth).
Source code in highfis/metrics.py
| @staticmethod
def mean_bias_error(y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None) -> float:
"""Return mean bias error (prediction minus truth)."""
y_true = y_true.float()
y_pred = y_pred.float()
diff = y_pred - y_true
if sample_weight is not None:
sample_weight = sample_weight.float()
return (torch.sum(diff * sample_weight) / torch.sum(sample_weight)).item()
return torch.mean(diff).item()
|
Return median absolute error.
Source code in highfis/metrics.py
| @staticmethod
def median_absolute_error(
y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None
) -> float:
"""Return median absolute error."""
y_true = y_true.float()
y_pred = y_pred.float()
errors = torch.abs(y_true - y_pred)
if sample_weight is not None:
sample_weight = sample_weight.float()
# Weighted median matching scikit-learn
sorted_indices = torch.argsort(errors)
sorted_errors = errors[sorted_indices]
sorted_weights = sample_weight[sorted_indices]
cum_weights = torch.cumsum(sorted_weights, dim=0)
total_weight = cum_weights[-1]
half_weight = total_weight / 2.0
idx = torch.searchsorted(cum_weights, half_weight)
idx = torch.clamp(idx, max=max(0, len(sorted_errors) - 1))
if idx < len(sorted_errors) - 1 and cum_weights[idx] == half_weight:
return ((sorted_errors[idx] + sorted_errors[idx + 1]) / 2.0).item()
return sorted_errors[idx].item()
return torch.quantile(errors, 0.5).item()
|
mse
staticmethod
Return mean squared error.
Source code in highfis/metrics.py
| @staticmethod
def mse(y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None) -> float:
"""Return mean squared error."""
y_true = y_true.float()
y_pred = y_pred.float()
if sample_weight is not None:
sample_weight = sample_weight.float()
return (torch.sum(((y_true - y_pred) ** 2) * sample_weight) / torch.sum(sample_weight)).item()
return torch.mean((y_true - y_pred) ** 2).item()
|
msle
staticmethod
Return mean squared logarithmic error.
Source code in highfis/metrics.py
| @staticmethod
def msle(y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None) -> float:
"""Return mean squared logarithmic error."""
y_true = y_true.float()
y_pred = y_pred.float()
if torch.any(y_true < 0) or torch.any(y_pred < 0):
return float("nan")
log_diff = torch.log1p(y_true) - torch.log1p(y_pred)
if sample_weight is not None:
sample_weight = sample_weight.float()
return (torch.sum((log_diff**2) * sample_weight) / torch.sum(sample_weight)).item()
return torch.mean(log_diff**2).item()
|
pearson
staticmethod
Return Pearson correlation coefficient.
Note
sample_weight is ignored.
Source code in highfis/metrics.py
| @staticmethod
def pearson(y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None) -> float:
"""Return Pearson correlation coefficient.
Note:
``sample_weight`` is ignored.
"""
y_true = y_true.float()
y_pred = y_pred.float()
if sample_weight is not None:
sample_weight = sample_weight.float()
warnings.warn("sample_weight is ignored by pearson", UserWarning, stacklevel=2)
if y_true.numel() < 2:
return float("nan")
vx = y_true - torch.mean(y_true)
vy = y_pred - torch.mean(y_pred)
corr = torch.sum(vx * vy) / (torch.sqrt(torch.sum(vx**2) * torch.sum(vy**2)))
if torch.isnan(corr) or torch.isinf(corr):
return float("nan")
return corr.item()
|
r2
staticmethod
Return coefficient of determination (R²).
Source code in highfis/metrics.py
| @staticmethod
def r2(y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None) -> float:
"""Return coefficient of determination (R²)."""
y_true = y_true.float()
y_pred = y_pred.float()
if sample_weight is not None:
sample_weight = sample_weight.float()
mean_y = torch.sum(y_true * sample_weight) / torch.sum(sample_weight)
ss_res = torch.sum(((y_true - y_pred) ** 2) * sample_weight)
ss_tot = torch.sum(((y_true - mean_y) ** 2) * sample_weight)
else:
mean_y = torch.mean(y_true)
ss_res = torch.sum((y_true - y_pred) ** 2)
ss_tot = torch.sum((y_true - mean_y) ** 2)
if ss_tot == 0:
return 1.0 if ss_res == 0 else 0.0
return (1.0 - ss_res / ss_tot).item()
|
rmse
staticmethod
Return root mean squared error.
Source code in highfis/metrics.py
| @staticmethod
def rmse(y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None) -> float:
"""Return root mean squared error."""
y_true = y_true.float()
y_pred = y_pred.float()
if sample_weight is not None:
sample_weight = sample_weight.float()
return torch.sqrt(torch.sum(((y_true - y_pred) ** 2) * sample_weight) / torch.sum(sample_weight)).item()
return torch.sqrt(torch.mean((y_true - y_pred) ** 2)).item()
|
smape
staticmethod
Return symmetric mean absolute percentage error.
Source code in highfis/metrics.py
| @staticmethod
def smape(y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None) -> float:
"""Return symmetric mean absolute percentage error."""
y_true = y_true.float()
y_pred = y_pred.float()
numerator = torch.abs(y_pred - y_true) * 2.0
denominator = torch.abs(y_true) + torch.abs(y_pred)
ratio = torch.where(denominator == 0.0, torch.zeros_like(numerator), numerator / denominator)
if sample_weight is not None:
sample_weight = sample_weight.float()
return (torch.sum(ratio * sample_weight) / torch.sum(sample_weight)).item()
return torch.mean(ratio).item()
|
std_error
staticmethod
Return the standard deviation of the errors.
Note
sample_weight is ignored.
Source code in highfis/metrics.py
| @staticmethod
def std_error(y_true: torch.Tensor, y_pred: torch.Tensor, sample_weight: torch.Tensor | None = None) -> float:
"""Return the standard deviation of the errors.
Note:
``sample_weight`` is ignored.
"""
y_true = y_true.float()
y_pred = y_pred.float()
if sample_weight is not None:
sample_weight = sample_weight.float()
warnings.warn("sample_weight is ignored by std_error", UserWarning, stacklevel=2)
if y_true.numel() < 2:
return 0.0
return torch.std(y_pred - y_true, unbiased=True).item()
|
compute_metrics
Compute a set of named evaluation metrics.
Parameters:
| Name |
Type |
Description |
Default |
task
|
Task
|
"classification" or "regression".
|
required
|
y_true
|
Any
|
Ground-truth labels or targets.
|
required
|
y_pred
|
Any
|
Predicted labels or values.
|
required
|
sample_weight
|
Any | None
|
|
None
|
metrics
|
Sequence[str] | None
|
Optional list of metric names to compute.
|
None
|
Returns:
| Type |
Description |
dict[str, Any]
|
Dictionary mapping metric names to scalar float results.
|
Source code in highfis/metrics.py
| def compute_metrics(
task: Task,
y_true: Any,
y_pred: Any,
sample_weight: Any | None = None,
metrics: Sequence[str] | None = None,
) -> dict[str, Any]:
"""Compute a set of named evaluation metrics.
Args:
task: ``"classification"`` or ``"regression"``.
y_true: Ground-truth labels or targets.
y_pred: Predicted labels or values.
sample_weight: Optional sample weights.
metrics: Optional list of metric names to compute.
Returns:
Dictionary mapping metric names to scalar float results.
"""
if isinstance(y_true, torch.Tensor) and isinstance(y_pred, torch.Tensor):
if sample_weight is not None and not isinstance(sample_weight, torch.Tensor):
sample_weight = torch.as_tensor(sample_weight, device=y_true.device, dtype=y_true.dtype)
return compute_metrics_pytorch(task, y_true, y_pred, sample_weight, metrics)
if task == "classification":
return _compute_classification_numpy(y_true, y_pred, sample_weight, metrics)
if task == "regression":
return _compute_regression_numpy(y_true, y_pred, sample_weight, metrics)
raise ValueError("task must be 'classification' or 'regression'")
|
compute_metrics_pytorch
Compute a set of named evaluation metrics using PyTorch.
Source code in highfis/metrics.py
| def compute_metrics_pytorch(
task: Task,
y_true: torch.Tensor,
y_pred: torch.Tensor,
sample_weight: torch.Tensor | None = None,
metrics: Sequence[str] | None = None,
) -> dict[str, Any]:
"""Compute a set of named evaluation metrics using PyTorch."""
if y_true.ndim != 1:
y_true = y_true.ravel()
if y_pred.ndim != 1:
y_pred = y_pred.ravel()
if sample_weight is not None and sample_weight.ndim != 1:
sample_weight = sample_weight.ravel()
if y_true.numel() != y_pred.numel():
raise ValueError(
f"Found input variables with inconsistent numbers of samples: [{y_true.numel()}, {y_pred.numel()}]"
)
if task == "classification":
return _compute_classification_pytorch(y_true, y_pred, sample_weight, metrics)
if task == "regression":
return _compute_regression_pytorch(y_true, y_pred, sample_weight, metrics)
raise ValueError("task must be 'classification' or 'regression'")
|