Spaces:
Sleeping
Sleeping
"""Composite RAG metrics combining retrieval + generation (single‐mapping version).""" | |
from __future__ import annotations | |
from typing import Mapping | |
import math | |
def harmonic_mean(scores: Mapping[str, float]) -> float: | |
"""Compute the harmonic mean of positive scores.""" | |
if not scores: | |
return 0.0 | |
if any(v <= 0 for v in scores.values()): | |
return 0.0 | |
else: | |
inv_sum = sum(1.0 / (v) for v in scores.values()) | |
return len(scores) / inv_sum if inv_sum and inv_sum != 0 else 0.0 | |
def rag_score( | |
scores: Mapping[str, float], | |
*, | |
alpha: float = 0.5, | |
) -> float: | |
""" | |
Combine retrieval & generation sub-scores (0-1) via weighted HM. | |
""" | |
# Split the incoming flat mapping into two maps: retrieval vs generation | |
retr_map: dict[str, float] = {} | |
gen_map: dict[str, float] = {} | |
for k, v in scores.items(): | |
if k.startswith("retrieval_"): | |
retr_map[k[len("retrieval_"):]] = v | |
elif k.startswith("generation_"): | |
gen_map[k[len("generation_"):]] = v | |
else: | |
# ignore any key that doesn't start with 'retrieval_' or 'generation_' | |
pass | |
# If either side is empty, we cannot score | |
if not retr_map or not gen_map: | |
return 0.0 | |
retr_score = harmonic_mean(retr_map) | |
gen_score = harmonic_mean(gen_map) | |
if retr_score == 0 or gen_score == 0: | |
return 0.0 | |
return 1.0 / (alpha / retr_score + (1 - alpha) / gen_score) |