Configurer les statistiques
Les statistiques sont les valeurs au niveau de l'exécution qu'un évaluateur expose à partir de ses scores par enregistrement : une moyenne, un total, un percentile ou une métrique de classification telle que le F1. Ce sont celles que vous voyez dans l'en-tête du tableau d'exécutions, dans les graphiques au fil du temps, et que vous ciblez avec un objectif.
Par défaut, un évaluateur calcule l’ensemble historique (avg, min, max, std, count). Déclarez statistics si vous voulez un autre ensemble : un nombre total d’échecs, des percentiles de latence ou aucune statistique.
Chaque statistique déclarée est une déclaration sérialisable comprise par le SDK, le backend et Studio. Elle peut donc être recalculée après filtrage ou réévaluation, représentée dans un graphique, comparée et contrôlée par un objectif.
Exemple rapide
from mistralai.evaluations import Evaluator, Goal, Statistic
Evaluator(
name="latency_ms",
description="End-to-end response time in milliseconds.",
scorer=latency_scorer,
statistics=[
Statistic.percentile(95, goal=Goal.lte(500)),
Statistic.percentile(50),
Statistic.percentile(75),
],
)Les factories
La factory Statistic déclare chaque réduction intégrée :
| Méthode | Signification | ID |
|---|---|---|
Statistic.avg() | Moyenne arithmétique des scores numériques | avg |
Statistic.sum() | Somme des scores numériques (par exemple, un nombre total d’échecs) | sum |
Statistic.min() | Plus petit score numérique | min |
Statistic.max() | Plus grand score numérique | max |
Statistic.std() | Écart type de la population | std |
Statistic.count() | Nombre de scores numériques réussis et non nuls | count |
Statistic.percentile(p) | Le percentile p, 0 <= p <= 100 | p50, p95, p99.9, … |
Chaque ID est canonique et stable : avg, sum, min, max, std, count et p{p} pour les percentiles (p50, p95). Les ID servent à référencer une statistique dans le SDK, la payload d’exécution et l’interface. Ils ne changent donc jamais une fois déclarés. Une médiane correspond à Statistic.percentile(50) — il n’existe pas de factory distincte pour elle.
Il n’existe volontairement pas de réduction rate : un taux correspond à avg sur des scores 0/1.
Omission ou liste explicite
Le champ statistics a deux modes :
- Omis (par défaut) — le comportement historique est conservé. Studio détecte le type de score et, pour les scores numériques, expose l’ensemble par défaut
avg,min,max,std,count. - Une liste explicite — fait autorité. Seules ces statistiques sont calculées et exposées, dans l’ordre indiqué, sans ajout de valeurs par défaut implicites. Une liste vide
statistics=[]signifie que l’évaluateur n’expose aucune statistique au niveau de l’exécution.
La première entrée de la liste effective est la statistique principale de l’évaluateur : la valeur unique affichée dans l’en-tête du tableau des exécutions pour une présentation compacte. Il s’agit d’une convention d’affichage, pas d’une option persistée.
Exemples
Ensemble par défaut (omission)
Omettre statistics conserve l’ensemble par défaut :
Evaluator(name="quality", scorer=quality_scorer)
# exposes avg, min, max, std, count — avg is the headlineTotal des échecs
Un évaluateur dont la fonction de scoring renvoie 0/1 par enregistrement, expose uniquement le nombre total d’échecs et impose un seuil à zéro :
from mistralai.evaluations import Evaluator, Goal, Statistic
Evaluator(
name="failures",
description="1 when the record failed, 0 otherwise.",
scorer=failure_scorer, # returns numeric 0 or 1
statistics=[Statistic.sum(goal=Goal.lte(0))],
)sum additionne les scores 0/1, et son objectif fait échouer l’exécution si un enregistrement a échoué.
Percentiles de latence
from mistralai.evaluations import Evaluator, Goal, Statistic
Evaluator(
name="latency_ms",
description="End-to-end response time in milliseconds.",
scorer=latency_scorer,
statistics=[
Statistic.percentile(95, goal=Goal.lte(500)),
Statistic.percentile(50),
Statistic.percentile(75),
],
)Cela expose exactement p50, p75 et p95 — pas de avg, min, max, std ni count. Comme p95 est en premier, il devient la statistique principale affichée dans l’en-tête du tableau des exécutions, et son Goal.lte(500) fait échouer l’exécution lorsque la latence au 95e percentile dépasse 500 ms.
Statistiques de classification
precision, recall et f1 proviennent d'une matrice de confusion sur les paires d'étiquettes (expected, predicted), ils nécessitent donc deux étiquettes par enregistrement. L'étiquette prédite est la value du score. L'étiquette attendue est lue dans les metadata du score, sous expected_key (par défaut "expected").
| Méthode | Signification | ID |
|---|---|---|
Statistic.precision(...) | Précision (valeur prédictive positive) | precision, precision_macro, … |
Statistic.recall(...) | Rappel (taux de vrais positifs) | recall, recall_micro, … |
Statistic.f1(...) | F1, la moyenne harmonique de la précision et du rappel | f1, f1_weighted, … |
Chaque fabrique prend exactement un des arguments suivants :
positive_label: une métrique binaire, calculée par rapport à cette seule classe.average: une métrique multi-classes, moyennée avec"macro","micro"ou"weighted".
Les deux modes acceptent également les arguments optionnels expected_key, labels et goal.
Binaire
from mistralai.evaluations import Evaluator, Score, Statistic
def scorer(ctx) -> Score:
# value: the model's prediction; metadata["expected"]: the ground-truth label
return Score(value=ctx.output, metadata={"expected": ctx.input_record["expected"]})
Evaluator(
name="spam_classifier",
scorer=scorer,
statistics=[
Statistic.f1(positive_label="spam"), # headline
Statistic.precision(positive_label="spam"),
Statistic.recall(positive_label="spam"),
],
)Les étiquettes sont des scores catégoriels, donc l'évaluateur obtient aussi les fréquences de prédiction. Studio affiche les métriques à côté de la matrice de confusion à partir de laquelle elles ont été calculées, et additionne les matrices entre les exécutions pour agréger les métriques dans la liste des exécutions.
Multi-classes
statistics=[
Statistic.f1(average="macro"), # id: f1_macro
Statistic.precision(average="weighted"), # id: precision_weighted
Statistic.recall(average="micro"), # id: recall_micro
]Les moyennes macro et weighted dépendent des classes présentes. Passez labels pour fixer l'ensemble des classes, par exemple Statistic.f1(average="macro", labels=["fr", "en", "de"]), afin que la valeur reste comparable quand un filtre retire tous les enregistrements d'une classe.
Métriques non définies et étiquettes manquantes
- Une métrique est
null(affichée comme-) quand son dénominateur est nul, par exemple la précision quand le modèle ne prédit jamais la classe positive. - Un score sans étiquette attendue dans ses métadonnées ne peut pas entrer dans la matrice de confusion. Il est exclu des métriques et compté dans
excluded_count, affiché dans Studio à côté du nombre d'enregistrements scorés.
Pour l'exactitude, vous n'avez pas besoin d'une statistique de classification : attribuez un score de 1 quand la prédiction correspond à l'étiquette attendue et 0 sinon, puis déclarez Statistic.avg().
Objectifs au niveau des statistiques
Un objectif associé à une statistique cible cette statistique — à la fois au niveau de l’enregistrement et de l’agrégation de l’exécution. C’est la méthode recommandée pour contrôler une exécution et remplacer aggregate_goal :
# Recommended
Evaluator(
name="accuracy",
scorer=accuracy_scorer,
statistics=[Statistic.avg(goal=Goal.gte(0.9))],
)
# Deprecated — prefer a statistic-level goal
Evaluator(
name="accuracy",
scorer=accuracy_scorer,
aggregate_goal=Goal.gte(0.9),
)Un objectif au niveau d’une statistique ne porte jamais son propre metric : la cible est la statistique à laquelle il est associé. (Seul le chemin obsolète aggregate_goal utilise metric pour nommer une statistique.)
Les scores doivent être numériques 0/1, pas booléens
Les réductions numériques nécessitent des scores numériques. Un évaluateur qui se base sur réussite/échec doit émettre 0 ou 1 numériques, pas True/False. Les booléens sont classés comme valeurs catégorielles, donc un scorer qui renvoie un booléen produit des statistiques catégorielles (fréquences et mode) et aucune des réductions numériques ci-dessus ne s'applique.
def failure_scorer(ctx) -> int:
return 1 if failed(ctx) else 0 # numeric — correct
def failure_scorer(ctx) -> bool:
return failed(ctx) # boolean — categorical, no sum/percentileL’algorithme de percentile
Statistic.percentile(p) utilise l’algorithme Hyndman-Fan type-7 (valeur par défaut de NumPy). Pour des scores triés x de longueur n et un rang h = (n - 1) * p / 100, le résultat interpole linéairement entre x[floor(h)] et x[ceil(h)] ; un score unique renvoie ce score. Le même algorithme s’exécute dans le SDK Python, le SDK TypeScript et le backend. Les mêmes scores produisent donc toujours la même valeur.
Échantillons vides
Lorsqu’aucun score numérique réussi n’alimente le calcul, un count déclaré vaut 0 et toutes les autres statistiques déclarées valent null (non évaluables). Un ensemble de données vide ne peut donc jamais satisfaire par accident un objectif comme Statistic.sum(goal=Goal.lte(0)).