TATECHATLAS
◎ Français
Intelligence artificielle

Évaluation de la Précision et du Rappel de l'IA sur de Petits Jeux de Données

Apprenez à évaluer efficacement la précision et le rappel des modèles d'IA, en particulier lorsque vous travaillez avec de petits jeux de données de questions. Ce guide couvre les concepts, les méthodes de calcul et les considérations pratiques à l'aide de scikit-learn.

Dans ce guide

Pour évaluer la précision et le rappel sur un petit jeu de données de questions pour un modèle d'IA, vous devez définir votre vérité terrain (réponses correctes) et les prédictions du modèle. Ensuite, utilisez des bibliothèques comme scikit-learn pour calculer ces métriques. La précision mesure la proportion de prédictions positives correctement identifiées parmi toutes les prédictions positives faites par le modèle, répondant à "Parmi tous les éléments que l'IA a prédits comme pertinents, combien l'étaient réellement ?". Le rappel mesure la proportion de prédictions positives correctement identifiées parmi toutes les instances positives réelles, répondant à "Parmi tous les éléments qui étaient réellement pertinents, combien l'IA a-t-elle trouvés ?". Pour les petits jeux de données, une annotation manuelle minutieuse de la vérité terrain est cruciale, et la compréhension des implications des différentes méthodes de moyennage dans scikit-learn est importante pour interpréter les résultats avec précision.

Comprendre la Précision et le Rappel

La précision et le rappel sont des métriques fondamentales pour évaluer la performance des modèles de classification, particulièrement dans la recherche d'information et les systèmes de questions-réponses d'IA. La précision quantifie l'exactitude des prédictions positives, en se concentrant sur le ratio des vrais positifs par rapport au nombre total de positifs prédits (vrais positifs + faux positifs). Elle répond à la question : "Parmi tous les éléments que l'IA a prédits comme pertinents, combien l'étaient réellement ?" Une précision élevée signifie que le modèle est bon pour ne pas étiqueter les éléments non pertinents comme pertinents. Le rappel, quant à lui, mesure la capacité du modèle à trouver tous les éléments pertinents. Il est calculé comme le ratio des vrais positifs par rapport au nombre total d'instances positives réelles (vrais positifs + faux négatifs). Le rappel répond à : "Parmi tous les éléments qui étaient réellement pertinents, combien l'IA a-t-elle trouvés ?" Un rappel élevé indique que le modèle est efficace pour identifier la plupart des éléments pertinents.

Calcul de la Précision et du Rappel

Pour calculer la précision et le rappel, vous avez d'abord besoin d'un ensemble d'étiquettes de vérité terrain (les réponses correctes) et des prédictions faites par votre modèle d'IA pour un ensemble donné de questions. Pour une tâche de classification binaire (par exemple, pertinent/non pertinent), la précision est calculée comme VP / (VP + FP), et le rappel est VP / (VP + FN), où VP sont les Vrais Positifs, FP sont les Faux Positifs et FN sont les Faux Négatifs. Des bibliothèques comme scikit-learn fournissent des fonctions pratiques, precision_score et recall_score, pour calculer ces métriques directement. Ces fonctions prennent les vraies étiquettes (y_true) et les étiquettes prédites (y_pred) comme entrée. Pour les petits jeux de données, assurer l'exactitude de votre y_true est primordial, car toute erreur aura un impact direct sur les métriques calculées.

from sklearn.metrics import precision_score, recall_score

# Exemple de vérité terrain et de prédictions
y_true = [0, 1, 2, 0, 1, 2]  # Pertinence réelle (par ex., 0: non pertinent, 1: pertinent, 2: très pertinent)
y_pred = [0, 2, 1, 0, 0, 1]  # Pertinence prédite par l'IA

# Pour la classification binaire, vous pourriez définir la classe 'positive', par ex., classe 1
# Précision pour la classe 1
precision = precision_score(y_true, y_pred, pos_label=1, average='binary')
# Rappel pour la classe 1
recall = recall_score(y_true, y_pred, pos_label=1, average='binary')

print(f"Précision (classe 1): {precision:.2f}")
print(f"Rappel (classe 1): {recall:.2f}")

Gestion des Scénarios Multiclasses et Multilibels

Lorsque vous traitez des questions-réponses d'IA, le problème peut ne pas être strictement binaire. Vous pourriez avoir plusieurs niveaux de pertinence ou plusieurs réponses correctes pour une seule question. Les fonctions precision_score et recall_score de Scikit-learn peuvent gérer des cibles multiclasses et multilabel. Le paramètre average est crucial ici. Les options incluent 'micro' (calcul global), 'macro' (moyenne non pondérée par classe), 'weighted' (moyenne pondérée par le support), 'samples' (moyenne par instance, pour multilabel), ou None (renvoie les scores pour chaque classe). Pour les petits jeux de données, l'utilisation de average=None est souvent révélatrice car elle montre la performance pour chaque classe ou étiquette spécifique, permettant une compréhension granulaire des domaines où l'IA excelle ou peine.

from sklearn.metrics import precision_score, recall_score
import numpy as np

y_true_multi = [0, 1, 2, 0, 1, 2]
y_pred_multi = [0, 2, 1, 0, 0, 1]

# Calcul de la précision et du rappel pour chaque classe
precision_scores = precision_score(y_true_multi, y_pred_multi, average=None)
recall_scores = recall_score(y_true_multi, y_pred_multi, average=None)

print(f"Précision par classe: {precision_scores}")
print(f"Rappel par classe: {recall_scores}")

# Exemple pour la moyenne pondérée
weighted_precision = precision_score(y_true_multi, y_pred_multi, average='weighted')
weighted_recall = recall_score(y_true_multi, y_pred_multi, average='weighted')

print(f"Précision pondérée: {weighted_precision:.2f}")
print(f"Rappel pondéré: {weighted_recall:.2f}")

Le Rôle de la Division par Zéro

Dans les scénarios où un dénominateur dans le calcul de la précision ou du rappel est zéro (par exemple, aucune prédiction positive n'a été faite, ou aucune instance positive réelle n'existe), une erreur de division par zéro peut survenir. Les fonctions de métriques de Scikit-learn gèrent cela avec le paramètre zero_division. La valeur par défaut est 'warn', qui renvoie 0 et déclenche un avertissement. Vous pouvez explicitement la définir sur 0.0 pour renvoyer 0 sans avertissement, 1.0 pour renvoyer 1 (utile si vous considérez qu'un modèle qui ne prédit rien pour une classe sans instances réelles est parfaitement précis/a un rappel parfait pour cette classe), ou np.nan pour exclure de tels cas de la moyenne. Pour les petits jeux de données, comprendre ces cas limites et comment zero_division affecte vos métriques est crucial pour une interprétation précise.

from sklearn.metrics import precision_score, recall_score
import numpy as np

y_true_zero = [0, 0, 0]
y_pred_zero = [0, 0, 0]

# Exemple avec division par zéro, par défaut 'warn'
print("--- Gestion de la Division par Zéro ---")
precision_warn = precision_score(y_true_zero, y_pred_zero, average=None, zero_division='warn')
recall_warn = recall_score(y_true_zero, y_pred_zero, average=None, zero_division='warn')
print(f"Précision (warn): {precision_warn}")
print(f"Rappel (warn): {recall_warn}")

# Exemple avec zero_division=1
precision_one = precision_score(y_true_zero, y_pred_zero, average=None, zero_division=1)
recall_one = recall_score(y_true_zero, y_pred_zero, average=None, zero_division=1)
print(f"Précision (zero_division=1): {precision_one}")
print(f"Rappel (zero_division=1): {recall_one}")

# Exemple avec zero_division=np.nan
precision_nan = precision_score(y_true_zero, y_pred_zero, average=None, zero_division=np.nan)
recall_nan = recall_score(y_true_zero, y_pred_zero, average=None, zero_division=np.nan)
print(f"Précision (zero_division=np.nan): {precision_nan}")
print(f"Rappel (zero_division=np.nan): {recall_nan}")

Interprétation des Résultats sur de Petits Jeux de Données

L'évaluation de la performance de l'IA sur de petits jeux de données nécessite une interprétation prudente. Une précision élevée peut être atteinte simplement parce que le modèle fait très peu de prédictions positives, et celles qu'il fait se trouvent être correctes. De même, un rappel élevé peut se produire si le jeu de données contient très peu d'instances positives réelles, et que le modèle les identifie correctement. Il est crucial de considérer les deux métriques conjointement. Une approche courante consiste à examiner la courbe Précision-Rappel, bien que pour de très petits jeux de données, elle puisse ne pas être aussi informative. Pour les systèmes de questions-réponses, un petit jeu de données peut signifier la vérification manuelle de chaque prédiction. Si le jeu de données est trop petit pour être représentatif, la précision et le rappel calculés pourraient ne pas bien se généraliser à des données plus volumineuses et non vues. Envisagez d'augmenter votre jeu de données ou d'utiliser des techniques comme la validation croisée si possible.

Compromis Précision vs Rappel

Il existe souvent un compromis entre la précision et le rappel. Augmenter l'un peut parfois diminuer l'autre. Par exemple, un modèle très conservateur qui ne prédit une réponse comme pertinente que lorsqu'il est extrêmement confiant aura probablement une précision élevée mais un faible rappel (il manque de nombreuses réponses pertinentes). Inversement, un modèle qui essaie de trouver toutes les réponses pertinentes possibles, même avec une confiance plus faible, aura probablement un rappel élevé mais une précision plus faible (il inclut de nombreuses réponses non pertinentes). Le compromis optimal dépend de l'application spécifique. Pour une IA de questions-réponses, est-il plus important de fournir uniquement des réponses correctes (précision élevée), ou de s'assurer que toutes les réponses correctes possibles sont trouvées, même si certaines réponses non pertinentes sont incluses (rappel élevé) ? Cette décision guide la manière dont vous priorisez ces métriques.

Considérations Pratiques pour les Questions-Réponses d'IA

Lors de l'application de la précision et du rappel aux questions-réponses d'IA, en particulier avec de petits jeux de données, considérez la nature de la classe 'positive'. S'agit-il d'une seule réponse correcte, ou d'un ensemble de réponses acceptables ? Si vous utilisez la recherche vectorielle (comme mentionné dans la documentation Azure AI Search), la pertinence est déterminée par la similarité vectorielle. La précision et le rappel mesurent alors à quel point la recherche de similarité récupère les documents souhaités. Pour la recherche hybride, où la recherche vectorielle et par mots-clés sont combinées, l'évaluation de la performance globale nécessite de considérer les deux aspects. Les petits jeux de données peuvent nécessiter plus d'annotations manuelles et une définition soignée de ce qui constitue un 'vrai positif' dans le contexte de la ressemblance sémantique ou conceptuelle, plutôt que de simples correspondances de mots-clés exacts.

Utilisation de precision_recall_fscore_support

Scikit-learn offre une fonction utilitaire, precision_recall_fscore_support, qui calcule la précision, le rappel, le score F1 et le nombre d'instances réelles (support) pour chaque classe. Cette fonction est particulièrement utile lorsque vous souhaitez un aperçu complet des performances de votre modèle dans toutes les classes, en particulier dans les scénarios multiclasses. Pour les petits jeux de données, voir le 'support' pour chaque classe peut être très révélateur, mettant en évidence les classes qui ont peu d'exemples, ce qui pourrait expliquer un faible rappel ou une faible précision pour ces classes spécifiques. Cette fonction simplifie le processus d'obtention de plusieurs métriques clés à la fois.

from sklearn.metrics import precision_recall_fscore_support

y_true_multi = [0, 1, 2, 0, 1, 2]
y_pred_multi = [0, 2, 1, 0, 0, 1]

precision, recall, fscore, support = precision_recall_fscore_support(y_true_multi, y_pred_multi, average=None)

print(f"Précision: {precision}")
print(f"Rappel: {recall}")
print(f"Score F1: {fscore}")
print(f"Support: {support}")

Limitations avec les Petits Jeux de Données

La principale limitation lors de l'évaluation de la précision et du rappel sur de petits jeux de données est le manque de signification statistique. Les métriques calculées sur un petit échantillon peuvent ne pas refléter avec précision la performance du modèle sur un jeu de données plus grand et plus diversifié. Un modèle pourrait très bien performer sur un petit ensemble de questions soigneusement sélectionnées simplement par hasard ou par surajustement aux exemples spécifiques. Inversement, un modèle pourrait sembler mal performer si le petit jeu de données contient des cas limites difficiles. Il est difficile de généraliser les conclusions tirées de très petits jeux de données. De plus, la définition de la 'vérité terrain' elle-même peut être subjective, en particulier dans les tâches d'IA nuancées comme les questions-réponses, et l'annotation d'un petit jeu de données pourrait ne pas capturer tout le spectre des réponses ou interprétations possibles.

Points à vérifier

  • Assurez-vous que y_true (vérité terrain) est annoté avec précision pour le petit jeu de données.
  • Vérifiez que y_pred (prédictions du modèle) correspond correctement aux étiquettes y_true.
  • Comprenez l'impact du paramètre average sur les résultats multiclasses/multilibels.
  • Considérez le comportement du paramètre zero_division pour les cas limites.
  • Analysez la précision et le rappel conjointement, pas isolément.
  • Soyez conscient que les résultats des petits jeux de données peuvent ne pas se généraliser.

Ces métriques sont plus fiables lorsqu'elles sont appliquées à des jeux de données représentatifs des données du monde réel que l'IA rencontrera. Pour de très petits jeux de données, la précision et le rappel calculés peuvent ne pas refléter fidèlement la performance réelle en raison de limitations statistiques et de surajustement potentiel. Les résultats doivent être interprétés avec prudence, et des efforts doivent être faits pour élargir le jeu de données ou utiliser la validation croisée si possible.

Sources

  1. scikit-learn: precision_score ↗
  2. scikit-learn: recall_score ↗
  3. Microsoft Learn: relevance in vector search ↗
Retour en haut ↑