Exercices Entraîner son LLM Évaluer un embedding fine-tuné
🎉

Bravo!

Avancé 🧠 Fondamentaux 30 XP 0 personnes ont réussi

Évaluer un embedding fine-tuné

Quand tu fine-tunes un modèle d'embedding (comme text-embedding-3-small d'OpenAI), tu veux vérifier qu'il retrouve mieux les documents pertinents qu'avant. Pour ça, on utilise deux métriques standard du domaine du retrieval : le Hit Rate et le MRR (Mean Reciprocal Rank).

Imagine que tu as un moteur de recherche interne. Pour chaque question, il te renvoie une liste de documents classés par pertinence. Le Hit Rate te dit : "dans quel pourcentage des cas, le bon document apparaît dans le top K résultats ?" Le MRR va plus loin : "en moyenne, à quelle position se trouve le bon document ?"

Le Hit Rate est binaire : soit le bon document est dans le top K (1), soit il n'y est pas (0). On fait la moyenne sur toutes les questions.

Le MRR est plus nuancé. Si le bon document est en position 1, le score est 1/1 = 1.0. En position 2, c'est 1/2 = 0.5. En position 5, c'est 1/5 = 0.2. Si le bon document n'est pas trouvé, c'est 0. On fait la moyenne sur toutes les questions.

Question : "Comment installer Python ?"
Résultats : ["Guide Java", "Install Python", "FAQ Django", ...]
Document pertinent : "Install Python"
Position du bon document : 2
Reciprocal Rank : 1/2 = 0.5

Écris une fonction evaluer_retrieval(questions, resultats, documents_pertinents, k=5) qui prend :
1. questions : une liste de chaînes (les requêtes)
2. resultats : une liste de listes de chaînes (les documents retournés pour chaque question, classés du plus au moins pertinent)
3. documents_pertinents : un dictionnaire qui associe chaque question au document correct
4. k : le nombre de résultats à considérer pour le Hit Rate

La fonction renvoie un dictionnaire avec :
- "hit_rate" : le pourcentage de questions où le document pertinent est dans le top K, arrondi à 4 décimales
- "mrr" : le Mean Reciprocal Rank, arrondi à 4 décimales
- "details" : liste de dicts avec "question", "position" (position du bon doc, 0 si non trouvé), "hit" (True/False), "reciprocal_rank"

Exemple :

questions = ["Q1", "Q2"]
resultats = [["doc_a", "doc_b", "doc_c"], ["doc_x", "doc_y"]]
pertinents = {"Q1": "doc_b", "Q2": "doc_z"}
r = evaluer_retrieval(questions, resultats, pertinents, k=3)
r["hit_rate"] vaut 0.5 (Q1 trouvé en top 3, Q2 non trouvé)
r["mrr"] vaut 0.25 (Q1 en position 2 donc 1/2 = 0.5, Q2 non trouvé donc 0, moyenne = 0.25)

Tests (4/6)

Cas de base
questions = ['Q1', 'Q2']
resultats = [['a', 'b', 'c'], ['x', 'y', 'z']]
pertinents = {'Q1': 'b', 'Q2': 'z'}
r = evaluer_retrieval(questions, resultats, pertinents, k=3)
assert r['hit_rate'] == 1.0
assert r['details'][0]['position'] == 2
assert r['details'][1]['position'] == 3
Document non trouvé
questions = ['Q1']
resultats = [['a', 'b', 'c']]
pertinents = {'Q1': 'inconnu'}
r = evaluer_retrieval(questions, resultats, pertinents, k=3)
assert r['hit_rate'] == 0.0
assert r['mrr'] == 0.0
assert r['details'][0]['position'] == 0
MRR calcul correct
questions = ['Q1', 'Q2']
resultats = [['bon', 'x'], ['x', 'bon']]
pertinents = {'Q1': 'bon', 'Q2': 'bon'}
r = evaluer_retrieval(questions, resultats, pertinents, k=5)
assert r['mrr'] == 0.75, f'MRR devrait etre 0.75 (1/1 + 1/2) / 2, obtenu {r["mrr"]}'
Hit Rate avec K restrictif
questions = ['Q1', 'Q2', 'Q3']
resultats = [['a', 'bon'], ['bon', 'a'], ['a', 'b', 'c', 'bon']]
pertinents = {'Q1': 'bon', 'Q2': 'bon', 'Q3': 'bon'}
r = evaluer_retrieval(questions, resultats, pertinents, k=2)
assert r['hit_rate'] == round(2/3, 4), 'Seuls Q1 et Q2 ont le bon doc dans le top 2'

+ 0 tests cachés

Indices (3 disponibles)

solution.py