Aller au contenu
English

Métriques de récupération

  • Leçon 8
  • 45 min
  • Module 3 : Choisir les métriques par composant

Ce que vous saurez faire

Mesurez un composant de recherche seul, à partir de résultats enregistrés et d’étiquettes de pertinence. Quand une réponse est fausse, ces mesures vous indiquent trois choses. La recherche a-t-elle trouvé les preuves? Quelle proportion? À quelle distance du début de la liste?

Avant de commencerCe qu’il faut savoir et avoir sous la mainEnviron 45 minutes

Ce que vous devez savoir

  • La précision@k et le rappel@k sur une liste classée, présentés dans Le compromis entre précision et rappel du cours Apprentissage automatique : du problème à un modèle fiable. Si vous ne l’avez pas suivi, cette leçon explique ce qu’il vous faut.
  • Les évaluations par composant, le niveau intermédiaire de la pyramide d’évaluation, présentées dans Choisir les niveaux d’évaluation.

Vous n’avez pas besoin du cours RAG : créer une IA qui utilise vos données. Cette leçon fournit les résultats de recherche qu’il a produits.

Ce qu’il vous faut sur votre ordinateur

  • Le projet ~/projects/eval-harness avec .venv actif : python -m pytest affiche 13 passed (13 tests réussis). Sinon, copiez l’instantané end-of-m02, comme l’explique Utiliser un instantané.
  • Le dépôt des laboratoires dans ~/projects/nextia-learning-labs, présenté dans Choisir les niveaux d’évaluation. Vous en copiez quatre fichiers.

Aucun compte ni aucune clé. Testé avec Python 3.12.13 sur macOS (Apple silicon). Les commandes Windows ne sont pas testées.

Vous posez une question à une collègue : « Quelle est la durée de garantie d’un arroseur de jardin? » Elle va au classeur et rapporte cinq dossiers, le meilleur sur le dessus. Quelle était la qualité de sa recherche?

  • Le bon dossier se trouve-t-il parmi les cinq?
  • La réponse se trouve à deux endroits. A-t-elle rapporté les deux?
  • Combien des cinq dossiers étaient utiles, et combien en avez-vous ouverts pour rien?
  • Un dossier utile était-il sur le dessus ou au bas de la pile?

Si le bon dossier n’est pas parmi les cinq, vous ne pouvez pas répondre, même en lisant attentivement. Cet échec vient de la recherche, pas de vous.

De nombreux systèmes d’IA commencent par récupérer de l’information. Ils cherchent dans une collection de documents et transmettent les meilleurs passages à un modèle de langage. L’assistant de politiques de Larkfield, créé dans le cours RAG, fonctionne ainsi. Quand sa réponse est fausse, il y a deux causes possibles. Soit la recherche n’a pas trouvé les preuves, soit le modèle ne les a pas utilisées.

Un test de la réponse finale ne permet pas de distinguer ces causes. Vous testez donc la recherche seule : c’est une évaluation par composant. Il vous faut seulement deux choses, toutes deux enregistrées dans des fichiers :

  • Des résultats de recherche enregistrés. Pour chaque question, les passages renvoyés par la recherche, les meilleurs en premier. Ils proviennent de quatre méthodes de recherche du cours RAG.
  • Des étiquettes de pertinence. Pour chaque question, les passages qui contiennent les preuves. La personne qui a rédigé le cours RAG les a marqués, puis un script les a vérifiés. Cela reste la lecture d’une seule personne.

Aucune recherche ne s’exécute dans cette leçon. Vous évaluez seulement ses sorties enregistrées, exactement comme les réponses enregistrées de l’assistant.

Le problème : la recherche n’a jamais montré la réponse

Section intitulée « Le problème : la recherche n’a jamais montré la réponse »

Voici une vraie question, Q34 : « How long is the warranty on a garden sprinkler? » Les preuves se trouvent dans la politique de garantie, dans un tableau réparti sur deux passages. Voici les 5 premiers résultats de la recherche par mots-clés et de la recherche avec reclassement :

Rang Recherche par mots-clés (document / section) Recherche avec reclassement (document / section)
1 product-care-garden-furniture / Warranty warranty-policy / Warranty periods by product category ✓
2 help-centre-faq / How long does a refund take? product-care-garden-furniture / Warranty
3 refunds-and-payments / How long a refund takes product-care-hedge-trimmer-ht550 / Warranty
4 privacy-policy / How long we keep it damaged-or-wrong-items / After 14 days
5 returns-policy / Refunds warranty-claims-procedure / Pressure washer pumps

Avec la recherche par mots-clés, aucun passage pertinent n’atteint le modèle. Les mots « how long » (combien de temps) attirent des passages sur les délais de remboursement et de conservation des données. N’importe quel modèle échouerait ici, ou dirait qu’il ne sait pas. Avec la recherche avec reclassement, le bon passage est au rang 1. Le problème vient de la recherche, et seule une mesure de recherche peut le montrer.

Pour une question, appelez les passages renvoyés par la recherche la liste classée, et les passages étiquetés les passages pertinents. Choisissez k, le nombre de résultats que le modèle reçoit : ici, 5.

  • hit@k : 1 si au moins un passage pertinent figure parmi les k premiers, sinon 0. « Les preuves sont-elles présentes quelque part? »
  • rappel@k : la proportion des passages pertinents qui figurent parmi les k premiers. « Quelle proportion des preuves arrive? »
  • précision@k : la proportion des k premiers passages qui est pertinente. « Quelle proportion de ce que lit le modèle est utile? »
  • rang réciproque (RR) : 1 ÷ le rang du premier passage pertinent. Le rang 1 donne 1, le rang 2 donne 1/2, le rang 3 donne 1/3. Aucun passage pertinent parmi les k premiers donne 0. « À quelle distance du début de la liste sont les preuves? »

Chaque mesure est calculée par question, puis on en fait la moyenne sur les questions. La moyenne des rangs réciproques est le rang réciproque moyen (MRR). Certaines questions n’ont aucun passage pertinent, car les documents n’y répondent pas. Il n’y a rien à trouver pour elles, donc les mesures les excluent.

Ce sont la précision et le rappel de la dernière leçon, appliqués à une liste plutôt qu’à une décision oui ou non.

Cinq questions inventées, les 5 premiers résultats de chacune et toutes les valeurs. Elles forment l’exemple détaillé dans tests/test_retrieval.py.

Cinq listes classées de cinq résultats chacune, avec les résultats pertinents marqués r1 ou r2 et les quatre valeurs pour chaque question.
L'exemple détaillé : cinq questions, les 5 premiers résultats de chacune, les meilleurs en premier. r1 et r2 sont des passages pertinents; un tiret indique un passage non pertinent. La moyenne des cinq donne un MRR de 0,567.
Description textuelle du diagramme

La question A nécessite 1 passage, trouvé au rang 1 : hit 1, rappel 1, précision 0,2, RR 1. La question B nécessite 1 passage, trouvé au rang 3 : hit 1, rappel 1, précision 0,2, RR 1/3. La question C nécessite 2 passages, trouvés aux rangs 2 et 4 : hit 1, rappel 1, précision 0,4, RR 1/2. La question D nécessite 1 passage, non trouvé : toutes les valeurs sont 0. La question E nécessite 2 passages, dont un trouvé au rang 1 : hit 1, rappel 0,5, précision 0,2, RR 1. Moyennes des cinq : hit@5 0,8, rappel@5 0,7, précision@5 0,2, MRR 0,567.

Examinez deux questions de près.

  • B trouve son passage, mais seulement au rang 3. Le hit et le rappel indiquent « parfait ». Seul le RR, 1/3, montre que le modèle doit d’abord lire deux passages inutiles.
  • E a son passage au rang 1, donc son RR est 1. Mais elle nécessite deux passages, et le second manque. Seul le rappel, 0,5, le montre.

Chaque mesure détecte donc un échec qu’une autre ne voit pas. Le MRR est (1 + 1/3 + 1/2 + 0 + 1) ÷ 5 = 2,833 ÷ 5 = 0,567. La précision@5 est faible partout : 0,2. La plupart des questions ont seulement un ou deux passages pertinents, et les 5 premiers résultats occupent cinq places. Une faible précision@5 est normale ici; comparez-la entre les méthodes, pas avec 1.

  1. Récupérez les derniers fichiers des laboratoires. Dans le terminal, allez dans ~/projects :

    Fenêtre de terminal
    cd ~/projects
    git -C nextia-learning-labs pull

    Si vous avez téléchargé les laboratoires dans un fichier ZIP, téléchargez-le de nouveau.

  2. Allez dans le projet et copiez les résultats de recherche enregistrés, le module de calcul des scores et son test depuis l’instantané end-of-m03 :

    Fenêtre de terminal
    cd eval-harness
    mkdir -p data/retrieval
    cp ../nextia-learning-labs/C11/snapshots/end-of-m03/data/retrieval/rankings.json data/retrieval/
    cp ../nextia-learning-labs/C11/snapshots/end-of-m03/data/retrieval/README.md data/retrieval/
    cp ../nextia-learning-labs/C11/snapshots/end-of-m03/harness/scorers/retrieval.py harness/scorers/
    cp ../nextia-learning-labs/C11/snapshots/end-of-m03/tests/test_retrieval.py tests/
  3. Ouvrez harness/scorers/retrieval.py dans VS Code. Trouvez les quatre fonctions hit_at, recall_at, precision_at et reciprocal_rank. Chacune compte une ou deux lignes : la définition ci-dessus, écrite en Python. Lisez ensuite evaluate() : elle ignore les questions sans passage pertinent et calcule la moyenne des quatre valeurs sur les autres.

  4. Ouvrez harness/__main__.py. Ajoutez cette fonction au-dessus de def main( :

    harness/__main__.py
    def cmd_retrieval(a) -> None:
    from .scorers.retrieval import evaluate, load_rankings
    data = load_rankings()
    print(f"Saved search results: {len(data['questions'])} questions, top {a.k}")
    print(f"{'method':9}{'hit':>7}{'recall':>8}{'precision':>11}{'MRR':>7}")
    for method in data["methods"]:
    m = evaluate(data, method, a.k)
    print(f"{method:9}{m['hit']:7.3f}{m['recall']:8.3f}{m['precision']:11.3f}{m['mrr']:7.3f}")
  5. Dans main(), ajoutez la nouvelle commande sous les lignes de score, après s.set_defaults(fn=cmd_score) :

    harness/__main__.py
    s = sub.add_parser("retrieval", help="ranking measures on the saved search results")
    s.add_argument("--k", type=int, default=5)
    s.set_defaults(fn=cmd_retrieval)
  6. Exécutez les tests :

    Fenêtre de terminal
    python -m pytest

    La dernière ligne est 15 passed (15 tests réussis). test_worked_example vérifie chaque valeur des cinq questions ci-dessus.

  7. Calculez les scores des quatre méthodes de recherche :

    Fenêtre de terminal
    python -m harness retrieval
    Saved search results: 67 questions, top 5
    method hit recall precision MRR
    hybrid 0.864 0.774 0.220 0.745
    keyword 0.831 0.751 0.207 0.655
    rerank 0.898 0.808 0.231 0.831
    vector 0.915 0.816 0.234 0.769

Si retrieval donne invalid choice (choix non valide), les lignes d’analyse de la commande de l’étape 5 manquent ou se trouvent dans un autre bloc : vérifiez leur indentation. Si elle donne FileNotFoundError (fichier introuvable), rankings.json n’est pas dans data/retrieval/.

Les 67 questions comprennent 8 questions auxquelles les documents ne répondent pas. Chaque moyenne porte donc sur 59 questions. Il y a quatre méthodes. La recherche par mots-clés (BM25) compte les mots correspondants. La recherche vectorielle compare les sens. La recherche hybride fusionne les deux listes. Le reclassement réordonne les 20 premiers résultats hybrides avec un second modèle.

La meilleure méthode dépend de la mesure. La recherche vectorielle a les meilleurs hit@5 (0.915) et rappel@5 (0.816) : elle apporte le plus de preuves parmi les 5 premiers résultats. Le reclassement a le meilleur MRR (0.831) : quand il trouve les preuves, il les place près du début. La recherche par mots-clés arrive dernière pour les quatre mesures. Si le modèle lit seulement le premier passage, le reclassement est le meilleur choix. S’il lit les cinq, la recherche vectorielle devance légèrement le reclassement : pour hit@5, la différence est d’une question (54 contre 53).

La valeur de k est aussi un choix. Un k plus grand apporte plus de preuves et plus de bruit :

  • vectorielle
  • reclassement
  • hybride
  • mots-clés
Rappel@k des quatre méthodes de recherche pour k = 1, 3, 5 et 10, sur les 59 questions ayant des passages pertinents. Le rappel augmente avec k pour chaque méthode; la recherche par mots-clés reste la plus faible.
Description textuelle du graphique

Un graphique linéaire avec k (1, 3, 5, 10) sur l’axe horizontal et le rappel@k de 0 à 1 sur l’axe vertical. Vectorielle : 0.52, 0.757, 0.816, 0.845. Reclassement : 0.613, 0.777, 0.808, 0.87. Hybride : 0.528, 0.723, 0.774, 0.856. Mots-clés : 0.41, 0.678, 0.751, 0.808. À k = 1, le reclassement devance largement les autres; à k = 5 et 10, la recherche vectorielle et le reclassement sont proches.

À k = 1, le rappel du reclassement est de 0.613 et celui de la recherche vectorielle, de seulement 0.52. À k = 10, ils sont presque égaux. La précision suit le mouvement inverse : à k = 10, environ un passage sur huit est pertinent. Chaque passage supplémentaire coûte des jetons et donne au modèle plus de contenu à ignorer.

Un détail si vous suivez aussi le cours RAG. Ce banc d’évaluation compte le rappel par passage pertinent (segment). Le cours RAG compte les sections pertinentes, donc son rappel@5 par mots-clés est de 0,771, pas de 0,751. Le hit, la précision et le MRR sont identiques dans les deux. Q34 montre la différence. Son tableau forme une section répartie sur deux passages. Le rappel du reclassement pour Q34 est donc de 0,5 ici, et de 1,0 dans le cours RAG.

  1. Démarrez Python dans le dossier du projet et calculez vous-même les scores de Q34 :

    >>> from harness.scorers.retrieval import load_rankings, recall_at, precision_at, reciprocal_rank
    >>> data = load_rankings()
    >>> q = next(q for q in data["questions"] if q["id"] == "Q34")
    >>> q["question"]
    'How long is the warranty on a garden sprinkler?'
    >>> relevant = set(q["relevant"])
    >>> q["relevant"]
    ['d9a5bd8ea531', 'b47ef9ac1993']
    >>> for method in ("keyword", "rerank"):
    ... ranked = data["rankings"][method]["Q34"]
    ... print(method, recall_at(ranked, relevant, 5), precision_at(ranked, relevant, 5), reciprocal_rank(ranked, relevant, 5))
    ...
    keyword 0.0 0.0 0.0
    rerank 0.5 0.2 1.0

    Quittez Python avec exit().

  2. Faites une prédiction avant d’exécuter la commande : à k = 1, comment se comparent le hit, la précision et le MRR pour une méthode? Exécutez ensuite python -m harness retrieval --k 1.

Afficher le résultat et la raison
Saved search results: 67 questions, top 1
method hit recall precision MRR
hybrid 0.678 0.528 0.678 0.678
keyword 0.542 0.410 0.542 0.542
rerank 0.797 0.613 0.797 0.797
vector 0.678 0.520 0.678 0.678

Avec un seul résultat, les trois posent la même question : le premier résultat est-il pertinent? Si oui, le hit est 1, la précision est 1 ÷ 1 et le RR est 1/1. Sinon, les trois valent 0. Le rappel est plus faible, car une question ayant deux passages pertinents peut en recevoir au plus la moitié dans une seule place. À k = 1, le reclassement bat clairement la recherche vectorielle (0,797 contre 0,678). À k = 5, la recherche vectorielle a le hit@5 le plus élevé.

Mesure Utilisez-la quand Ce qu’elle ne détecte pas
hit@k Le modèle a besoin d’un passage pour répondre Un second passage manquant; le rang
rappel@k Une réponse nécessite plusieurs passages (une règle et son exception) Leur position dans la liste
précision@k Le contexte est coûteux, ou le bruit induit le modèle en erreur Si le bon passage est présent
MRR Le modèle ou la personne qui lit utilise surtout le premier résultat Tous les passages pertinents après le premier

Les mesures coûtent peu une fois les étiquettes créées : de simples comptages sur des fichiers enregistrés. Le coût vient des étiquettes. Quelqu’un doit lire les documents, marquer les preuves pour chaque question, puis vérifier ces marques. Elles ont aussi des limites. Un passage contenant la moitié de la réponse compte comme pertinent. Un passage non étiqueté qui répond aussi à la question compte comme du bruit. Les mesures de récupération indiquent si les preuves sont arrivées, pas si la réponse finale les a utilisées. Cela nécessite les vérifications de la prochaine leçon.

Erreur courante

Compter les questions sans réponse

Symptôme : une collègue évalue la recherche par mots-clés avec un petit script. Il donne un hit@5 de 0,731, pas de 0,831. Le reclassement passe de 0,898 à 0,791. « Notre recherche est moins bonne que ce qu’indique le rapport. »

Cause : le script divise par les 67 questions. Huit d’entre elles (Q14 à Q21) n’ont aucun passage pertinent, car les documents n’y répondent pas : « Offrons-nous un rabais étudiant? » Leur hit ne peut être que 0. La recherche par mots-clés trouve les preuves pour 49 des 59 questions auxquelles les documents peuvent répondre : 49 ÷ 59 = 0,831, mais 49 ÷ 67 = 0,731.

Solution : excluez les questions sans passage pertinent, comme le fait evaluate(), et indiquez combien de questions la moyenne couvre. Mesurez autrement les questions sans réponse : le système devrait dire que les documents n’y répondent pas. C’est une vérification de la réponse, pas de la recherche.

Vérifiez votre compréhension

Deux méthodes de recherche ont le même hit@5 sur un ensemble de questions. Qu'est-ce qui peut encore différer, et quelle mesure le montre?

Afficher la réponse

Le rang des preuves et la proportion qui arrive. Le MRR montre le rang : une méthode peut placer le passage pertinent en premier, l’autre au rang 4 ou 5. Le rappel@5 montre la proportion des preuves qui arrive, pour les questions nécessitant plus d’un passage. Dans l’exemple détaillé, B et E ont tous deux un hit de 1; le RR de B est 1/3, et le rappel de E est 0,5.

Vérifiez votre compréhension

L'assistant de politiques de Larkfield donne une durée de garantie erronée pour Q34 avec la recherche par mots-clés. Avant de changer la requête, que disent les mesures de récupération?

Afficher la réponse

Avec la recherche par mots-clés, Q34 a un hit@5 de 0, un rappel@5 de 0 et un RR de 0. Aucun des deux passages du tableau de garantie ne figure parmi les 5 premiers résultats. Le modèle n’a jamais vu les preuves, donc une meilleure requête ne peut pas corriger le problème. Changez d’abord la recherche : la recherche avec reclassement place un passage du tableau au rang 1 (rappel@5 0,5, RR 1).

Vérifiez votre compréhension

Pourquoi la précision@5 est-elle faible pour chaque méthode (environ 0,2), et est-ce un problème?

Afficher la réponse

La plupart des questions ont seulement un ou deux passages pertinents, et k = 5 offre toujours cinq places. Même une recherche parfaite obtient donc au plus 0,2 pour une question ayant un seul passage pertinent. Ce n’est pas un problème en soi. Comparez la précision@k entre les méthodes au même k, et rappelez-vous que chaque passage supplémentaire coûte des jetons.

Récapitulatif

  • Une évaluation par composant évalue la recherche seule, à partir de résultats enregistrés et d’étiquettes de pertinence. Aucune recherche ne s’exécute.
  • hit@k : des preuves sont-elles présentes? rappel@k : quelle proportion? précision@k : quelle proportion des k premiers résultats est utile? MRR : à quelle distance du début?
  • Chaque mesure détecte un échec que les autres ne voient pas. Dans l’exemple détaillé, le MRR est de 0,567.
  • Sur les 59 questions de Larkfield ayant une réponse, à k = 5, la recherche vectorielle a les meilleurs hit et rappel (0,915, 0,816). Le reclassement a le meilleur MRR (0,831). À k = 1, le reclassement mène clairement.
  • Excluez les questions sans passage pertinent et indiquez combien de questions la moyenne couvre.

Votre projet contient maintenant harness/scorers/retrieval.py, data/retrieval/ et la commande retrieval, et python -m pytest affiche 15 passed. Ensuite, le composant le plus difficile à mesurer : la réponse écrite.

Leçon suivante : Métriques des sorties générées