Source code for bayesflow.diagnostics.metrics.brier_score

from typing import Any
from collections.abc import Sequence

import numpy as np


[docs] def brier_score( estimates: np.ndarray, targets: np.ndarray, model_names: Sequence[str] = None, ) -> dict[str, Any]: """ Computes the (multi-class) Brier score of a model comparison network [1]. The Brier score is a strictly proper scoring rule: it is minimized in expectation by the true posterior model probabilities, and thus jointly rewards calibration and sharpness. Lower is better, with 0 attained by perfectly confident, correct predictions. [1] Brier, G. W. (1950). Verification of forecasts expressed in terms of probability. Monthly Weather Review, 78(1), 1-3. Make sure that ``targets`` are **one-hot encoded** classes (i.e., model indices)! Parameters ---------- estimates : array of shape (num_sim, num_models) The predicted posterior model probabilities. targets : array of shape (num_sim, num_models) The one-hot-encoded true model indices. model_names : Sequence[str], optional (default = None) Optional model names to show in the output. By default, models are called "M_" + model index. Returns ------- result : dict Dictionary containing: - "values" : np.ndarray The one-vs-rest Brier score per model, i.e., the mean squared difference between the predicted probability of model ``m`` and its one-hot indicator. - "aggregate" : float The multi-class Brier score, equal to the sum of the per-model values. - "metric_name" : str The name of the metric ("Brier Score"). - "model_names" : list[str] The (inferred) model names. """ if model_names is None: model_names = ["M_" + str(i) for i in range(1, estimates.shape[-1] + 1)] per_model = np.mean((estimates - targets) ** 2, axis=0) return dict( values=per_model, aggregate=per_model.sum(), metric_name="Brier Score", model_names=list(model_names), )