相關度 / 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 %}