相關度 / MRR
===
###### tags: `LLM / Metrics`
###### tags: `LLM`, `Metrics`, `相關度`, `MRR`
<br>
[TOC]
<br>
## 討論
### MRR 指標如何用?
- ### gpt-o1
> MRR(Mean Reciprocal Rank)使用說明
**MRR(Mean Reciprocal Rank)** 是在資訊檢索(Information Retrieval)或問答系統(QA)等任務中,常用來評估「**搜尋結果的排名品質**」的一項指標。它的核心概念是:**只要第一個正確答案(或相關文件)排名越前,分數就越高**。以下分步說明:
---
## 1. MRR 的定義
對於每個查詢(query),我們在搜尋後得到一個「排名清單」,其中可能包含正確答案(或相關文件)以及許多不相關的內容。
- **Reciprocal Rank(RR)**:如果對於某個查詢,第 $k$ 個順位的結果是第一個正確答案,那麼此查詢的 $RR = \frac{1}{k}$。
- **Mean Reciprocal Rank(MRR)**:把所有查詢各自的 RR 分數取平均值,即
$$
\text{MRR} = \frac{1}{|Q|} \sum_{q \in Q} \left( \frac{1}{\text{rank}_q} \right)
$$
其中 $\text{rank}_q$ 是該查詢中「第一個正確答案」的排名。
### 1.1 舉例
- 如果對於某個查詢,第一個正確答案在排名第 1,則 RR = 1/1 = 1.0
- 如果在排名第 10 才出現第一個正確答案,則 RR = 1/10 = 0.1
- 如果完全找不到正確答案,則有些做法會讓 RR = 0(表示沒命中)。
---
## 2. 如何使用 MRR 進行評估
1. **準備查詢與其「正確答案 / 相關文件」的資訊**
- 通常會有一個評測集(test set),對每個查詢 $q$ 都知道真正的相關文件或正確答案是哪一個(或哪一些)。
2. **對每個查詢進行檢索或匹配,得到排序結果**
- 使用你的檢索系統、問答系統或 embedding-based 的相似度排名機制,對查詢 $q$ 產生一個結果列表:
$$
[doc_1, doc_2, doc_3, ..., doc_n]
$$
- 這些文件(或答案)會依照相似度分數或模型打分從高到低排列。
3. **找出「第一個正確答案」在排序中的位置**
- 假設第 $k$ 個文件是查詢 $q$ 的第一個正確答案,即 $\text{rank}_q = k$。
- 若沒有任何正確答案出現在結果列表中,則可將該查詢的分數視為 0。
4. **計算 Reciprocal Rank(RR)**
$$
\text{RR}(q) = \frac{1}{k}
$$
其中 $k$ 是第一個正確答案的順位。
5. **對所有查詢取平均,即得到 MRR**
$$
\text{MRR} = \frac{1}{|Q|} \sum_{q \in Q} \text{RR}(q)
$$
- 其中 $|Q|$ 為全部查詢的數量。
> **總結**:MRR 越高,代表系統傾向於把正確結果排在越前面。
---
## 3. Python 簡易示範程式
以下以一個假想的範例來示範如何計算 MRR。假設我們有三個查詢 $q_1, q_2, q_3$ 與對應的檢索結果。
```python=
def compute_mrr(ranked_lists, ground_truths):
"""
ranked_lists: list of lists,
每個元素是一個查詢的結果排序 [doc_1, doc_2, ..., doc_k]
ground_truths: list of sets,
每個查詢對應的正確答案(可能只有一個, 也可能有多個)
回傳: 平均後的 MRR 分數 (float)
"""
reciprocal_ranks = []
for ranked_docs, true_set in zip(ranked_lists, ground_truths):
# 找到第一個落在 true_set 裡的文件的排名 i
rr = 0 # 若完全沒找到正確文件就保持 0
for i, doc in enumerate(ranked_docs):
if doc in true_set:
rr = 1 / (i + 1) # i+1 是實際排名(從 1 開始算)
break
reciprocal_ranks.append(rr)
# 計算 MRR
mrr = sum(reciprocal_ranks) / len(reciprocal_ranks)
return mrr
# 舉例
ranked_lists_example = [
["docA", "docB", "docC", "docD"], # 查詢 q1 的排名結果
["docX", "docB", "docY", "docZ"], # 查詢 q2
["docC", "docB", "docA", "docZ"] # 查詢 q3
]
ground_truths_example = [
{"docC"}, # q1 的正確答案就是 docC
{"docZ"}, # q2 的正確答案就是 docZ
{"docB", "docZ"} # q3 有兩個可能都算正確
]
mrr_value = compute_mrr(ranked_lists_example, ground_truths_example)
print("MRR =", mrr_value)
```
- **解讀**:
- 對於 q1,第一個正確答案是 docC,出現在排序列表的第 3 位 → RR = 1/3 = 0.333...
- 對於 q2,第一個正確答案是 docZ,出現在第 4 位 → RR = 1/4 = 0.25
- 對於 q3,由於 docB 與 docZ 都是正確答案,但 docB 排名第 2 就已經命中 → RR = 1/2 = 0.5
- 最終 MRR = (0.333... + 0.25 + 0.5) / 3 = 0.3611...
---
## 4. 為什麼使用 MRR?
1. **看重第一個正確答案的排名**
- 有些應用重視「使用者能否儘快在結果中看到正確答案」,只要第一個正確答案排名越前越好。
2. **簡單易懂**
- 若 MRR 分數是 0.5,就大約表示使用者在平均情況下,只要查看結果列表的前兩名(1/0.5 = 2)就能找到第一個正確答案。
3. **常見於 QA 或搜尋測試**
- 在 FAQ/QA 系統、文件檢索系統或排名任務中,MRR 是一個常被引用的標準化度量指標。
---
## 5. 小結
- **MRR(Mean Reciprocal Rank)** 用來衡量「第一個正確答案的排名表現」。
- **計算過程**:
1. 為每個查詢找出「第一個正確答案」在結果清單中的位置 $k$。
2. 計算 $1/k$ 作為該查詢的 RR 分數。
3. 所有查詢的 RR 分數取平均,即 MRR。
- **分數範圍**:$0 \sim 1$,越接近 1 代表系統在所有查詢上都能在排名前列找到正確答案。
在資訊檢索或 QA 場景裡,如果你需要一個**簡潔**且**注重第一個正確結果**的指標,MRR 會是相當合適的選擇。
{%hackmd vaaMgNRPS4KGJDSFG0ZE0w %}