पाठ 17 / 28

Golden Set पर Recall@k, MRR और nDCG

असली सवालों के labelled set से retrieval गुणवत्ता मापें।

जो नहीं मापते उसे सुधार नहीं सकते

Golden set बनाएँ: 50 से 200 असली सवाल, हर एक पर उसका उत्तर देने वाले दस्तावेज़(ों) का label, बिना उत्तर वाले सवाल भी शामिल करके। फिर निकालें: Recall@k (शीर्ष k में मिले प्रासंगिक दस्तावेज़ों का अंश; मुख्य संख्या जब बाद का चरण, जैसे LLM, सिर्फ़ वही उपयोग कर सके जो आपने retrieve किया), Precision@k, MRR (पहले प्रासंगिक परिणाम की 1 / rank का औसत; उत्तर को पहले रखने को पुरस्कृत करता है) और nDCG (श्रेणीबद्ध प्रासंगिकता और rank स्थितियाँ सँभालता है)। प्रति query प्रकार रिपोर्ट करें और सबसे बुरी queries देखें, क्योंकि औसत विफलताएँ छिपाते हैं। मॉडल, chunking, index settings, filters या reranker बदलने पर set चलाएँ और परिणाम configuration के साथ रखें।

मापें, फिर सुधारें

Labelled सवालों का set, recall और MRR, और error विश्लेषण दिखाते हैं क्या ठीक करना है।

तीन चरण: label, मापें, निदान।
चित्र 5.1 — Label, मापें और निदान।

तीन सवालों के लिए Recall और MRR, चलाकर

मैंने यह Python virtual environment में numpy 2.5.3, scikit-learn 1.9.1 और faiss-cpu 1.15.1 के साथ चलाया, निश्चित random seeds के साथ ताकि संख्याएँ दोहराई जाएँ। "vacation days" के लिए सही दस्तावेज़ दूसरे स्थान पर है, इसलिए recall@1 0 पर recall@3 1 और MRR 0.5 है। "hotel limit" सटीक है। "stolen laptop" प्रासंगिक दस्तावेज़ पूरी तरह चूकता है। औसत: recall@3 = 0.667, MRR = 0.5। यहाँ retrieved सूचियाँ गणना दिखाने के लिए हाथ से लिखे उदाहरण हैं।

def recall_at_k(retrieved, relevant, k): return len(set(retrieved[:k]) & set(relevant)) / len(relevant)
def mrr(retrieved, relevant):
    for i, d in enumerate(retrieved, 1):
        if d in relevant: return 1 / i
    return 0.0

cases = {
    "vacation days":   (["d2", "d1", "d9"], ["d1"]),
    "hotel limit":     (["d6", "d5", "d7"], ["d6"]),
    "stolen laptop":   (["d3", "d4", "d8"], ["d10"]),
}
for name, (got, rel) in cases.items():
    print(f"{name:14} recall@1={recall_at_k(got, rel, 1):.1f} recall@3={recall_at_k(got, rel, 3):.1f} mrr={mrr(got, rel):.2f}")
n = len(cases)
print("mean recall@3:", round(sum(recall_at_k(g, r, 3) for g, r in cases.values()) / n, 3),
      "| mean MRR:", round(sum(mrr(g, r) for g, r in cases.values()) / n, 3))

Output:

vacation days  recall@1=0.0 recall@3=1.0 mrr=0.50
hotel limit    recall@1=1.0 recall@3=1.0 mrr=1.00
stolen laptop  recall@1=0.0 recall@3=0.0 mrr=0.00
mean recall@3: 0.667 | mean MRR: 0.5

अनुत्तरणीय सवाल शामिल करें

आपके set का लगभग 10 से 20% बिना उत्तर वाला हो, ताकि आप माप सकें कि system सही ढंग से कुछ नहीं लौटाता।

त्वरित जाँच: MRR किसे पुरस्कृत करता है?

  • बड़े vectors उपयोग करना
  • ज़्यादा परिणाम लौटाना
  • पहले प्रासंगिक परिणाम को ऊपर के पास रखना
  • कम latency
Answer

पहले प्रासंगिक परिणाम को ऊपर के पास रखना — Rank 1 पर पहला प्रासंगिक परिणाम 1 स्कोर करता है; rank 4 पर 0.25।