Source code for snn.metrics.functions

import numpy as np


[docs] def accuracy(y_pred, y_true): """Classification accuracy.""" if y_pred.ndim > 1 and y_pred.shape[-1] > 1: pred_labels = np.argmax(y_pred, axis=-1) else: pred_labels = (y_pred.flatten() >= 0.5).astype(int) if y_true.ndim > 1 and y_true.shape[-1] > 1: true_labels = np.argmax(y_true, axis=-1) else: true_labels = y_true.flatten().astype(int) return np.mean(pred_labels == true_labels)
[docs] def binary_accuracy(y_pred, y_true, threshold=0.5): return np.mean((y_pred.flatten() >= threshold) == y_true.flatten().astype(bool))
[docs] def categorical_accuracy(y_pred, y_true): return np.mean(np.argmax(y_pred, axis=-1) == np.argmax(y_true, axis=-1))
[docs] def sparse_categorical_accuracy(y_pred, y_true): return np.mean(np.argmax(y_pred, axis=-1) == y_true.flatten().astype(int))
[docs] def top_k_accuracy(y_pred, y_true, k=5): top_k = np.argsort(y_pred, axis=-1)[:, -k:] true_labels = np.argmax(y_true, axis=-1) return np.mean([true_labels[i] in top_k[i] for i in range(len(true_labels))])
[docs] def precision(y_pred, y_true, threshold=0.5): pred = (y_pred.flatten() >= threshold).astype(int) true = y_true.flatten().astype(int) tp = np.sum((pred == 1) & (true == 1)) fp = np.sum((pred == 1) & (true == 0)) return tp / (tp + fp + 1e-8)
[docs] def recall(y_pred, y_true, threshold=0.5): pred = (y_pred.flatten() >= threshold).astype(int) true = y_true.flatten().astype(int) tp = np.sum((pred == 1) & (true == 1)) fn = np.sum((pred == 0) & (true == 1)) return tp / (tp + fn + 1e-8)
[docs] def f1_score(y_pred, y_true, threshold=0.5): p = precision(y_pred, y_true, threshold) r = recall(y_pred, y_true, threshold) return 2 * p * r / (p + r + 1e-8)
[docs] def mean_squared_error(y_pred, y_true): return np.mean((y_pred - y_true) ** 2)
[docs] def mean_absolute_error(y_pred, y_true): return np.mean(np.abs(y_pred - y_true))
[docs] def r2_score(y_pred, y_true): ss_res = np.sum((y_true - y_pred) ** 2) ss_tot = np.sum((y_true - np.mean(y_true)) ** 2) return 1.0 - ss_res / (ss_tot + 1e-8)
[docs] def confusion_matrix(y_pred, y_true, n_classes=None): if y_pred.ndim > 1 and y_pred.shape[-1] > 1: pred_labels = np.argmax(y_pred, axis=-1) else: pred_labels = (y_pred.flatten() >= 0.5).astype(int) if y_true.ndim > 1 and y_true.shape[-1] > 1: true_labels = np.argmax(y_true, axis=-1) else: true_labels = y_true.flatten().astype(int) if n_classes is None: n_classes = max(pred_labels.max(), true_labels.max()) + 1 cm = np.zeros((n_classes, n_classes), dtype=int) for t, p in zip(true_labels, pred_labels): cm[t, p] += 1 return cm
_REGISTRY = { "accuracy": accuracy, "binary_accuracy": binary_accuracy, "categorical_accuracy": categorical_accuracy, "sparse_categorical_accuracy": sparse_categorical_accuracy, "precision": precision, "recall": recall, "f1": f1_score, "f1_score": f1_score, "mse": mean_squared_error, "mean_squared_error": mean_squared_error, "mae": mean_absolute_error, "mean_absolute_error": mean_absolute_error, "r2": r2_score, "r2_score": r2_score, }
[docs] def get(identifier): if callable(identifier): return identifier if isinstance(identifier, str): key = identifier.lower() if key in _REGISTRY: return _REGISTRY[key] raise ValueError(f"Unknown metric: '{identifier}'. Available: {list(_REGISTRY)}") raise TypeError(f"Could not interpret metric: {identifier}")