Ca să compari un model de embedding, o dimensiune de fragment sau căutarea hibridă cu cea pur vectorială, ai nevoie de un set de întrebări pentru care știi ce documente sunt relevante și de metrici standard din information retrieval.
Recall@K măsoară ce proporție din documentele relevante apare în primele K rezultate. MRR (Mean Reciprocal Rank) se uită doar la poziția primului rezultat relevant. nDCG (normalized Discounted Cumulative Gain, Järvelin și Kekäläinen, 2002) acceptă grade de relevanță și penalizează logaritmic rezultatele relevante aflate mai jos în listă.
Benchmark-ul public MTEB (Massive Text Embedding Benchmark) calculează pentru sarcinile de regăsire nDCG@k, MRR@k, MAP@k, precision@k și recall@k și folosește nDCG@10 ca metrică principală. Scorurile MTEB arată cum se descurcă un model pe seturile publice; pe documentele tale trebuie măsurat separat.
Concepte cheie și caracteristici
| Concept / Parametru | Descriere practică |
|---|---|
Recall@K |
Bun când contează să nu ratezi documente (contextul pentru RAG). |
MRR |
Bun când contează mai ales primul rezultat corect. |
nDCG@K |
Ține cont de grade de relevanță și de ordinea completă a rezultatelor. |
Set de evaluare |
Întrebări asociate cu ID-urile fragmentelor relevante, construite din date reale și verificate. |
Recall față de căutarea exactă |
Pentru indecși ANN, procentul din vecinii exacți regăsiți; măsoară efectul parametrilor de index, nu relevanța. |
Exemple practice și scenarii reale
Exemplul 1: MRR și Recall@K pentru un singur document corect
def reciprocal_rank(rezultate, id_corect):
for i, doc_id in enumerate(rezultate, start=1):
if doc_id == id_corect:
return 1.0 / i
return 0.0
def recall_la_k(rezultate, relevante, k=5):
return len(set(rezultate[:k]) & set(relevante)) / len(relevante)
top5 = [99, 42, 105, 12, 88]
print(reciprocal_rank(top5, 42)) # 0.5
print(recall_la_k(top5, [42, 7], 5)) # 0.5
Exemplul 2: nDCG@K cu grade de relevanță
import math
def dcg(relevante):
return sum(rel / math.log2(i + 1) for i, rel in enumerate(relevante, start=1))
def ndcg_la_k(relevante_in_ordine, k=10):
ideal = dcg(sorted(relevante_in_ordine, reverse=True)[:k])
return dcg(relevante_in_ordine[:k]) / ideal if ideal else 0.0
Greșeli frecvente și capcane
- Optimizezi doar Recall@K. Un fragment relevant găsit pe locul 10 ajunge în context printre multe nerelevante; urmărește și MRR sau nDCG.
- Construiești setul de evaluare doar cu întrebări generate de același LLM pe care îl evaluezi. Adaugă întrebări reale și verifică manual relevanța.
- Confunzi recall-ul de regăsire (relevanță) cu recall-ul indexului ANN față de căutarea exactă. Sunt măsurători diferite.