# Golden Set पर Recall@k, MRR और nDCG — Embeddings और Vector Search

Source: https://www.geekswithgeeks.com/hi/embeddings/e-metrics

> असली सवालों के 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, मापें, निदान।](assets/figures/embeddings/section-5-map.svg) — चित्र 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 सूचियाँ गणना दिखाने के लिए हाथ से लिखे उदाहरण हैं।

```python
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 सही ढंग से कुछ नहीं लौटाता।

**Quiz:** MRR किसे पुरस्कृत करता है?

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

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