Islam Mamedov commited on
Commit
546986c
·
1 Parent(s): 3df6802

Weighted RRF (2:1): no recall recovery; hybrid still 0.86 vs dense 0.91

Browse files
Files changed (2) hide show
  1. src/ask.py +1 -1
  2. src/retrieval.py +6 -6
src/ask.py CHANGED
@@ -62,7 +62,7 @@ def main() -> None:
62
  parser = argparse.ArgumentParser()
63
  parser.add_argument("question")
64
  parser.add_argument("--k", type=int, default=TOP_K)
65
- parser.add_argument("--mode", default="hybrid_rerank",
66
  choices=["dense", "hybrid", "hybrid_rerank", "dense_rerank"])
67
  parser.add_argument("--show-chunks", action="store_true",
68
  help="print retrieved chunks (debugging/learning)")
 
62
  parser = argparse.ArgumentParser()
63
  parser.add_argument("question")
64
  parser.add_argument("--k", type=int, default=TOP_K)
65
+ parser.add_argument("--mode", default="dense",
66
  choices=["dense", "hybrid", "hybrid_rerank", "dense_rerank"])
67
  parser.add_argument("--show-chunks", action="store_true",
68
  help="print retrieved chunks (debugging/learning)")
src/retrieval.py CHANGED
@@ -79,13 +79,12 @@ def _bm25_ids(question: str, n: int) -> list[str]:
79
  return [_chunk_ids[i] for i in ranked[:n]]
80
 
81
 
82
- def _rrf_fuse(rankings: list[list[str]]) -> list[str]:
83
- """Merge multiple ranked lists: score(id) = sum over lists of
84
- 1/(RRF_K + rank). Ids high in ANY list surface; high in BOTH win."""
85
  scores: dict[str, float] = {}
86
- for ranking in rankings:
87
  for rank, cid in enumerate(ranking, 1):
88
- scores[cid] = scores.get(cid, 0.0) + 1.0 / (RRF_K + rank)
89
  return sorted(scores, key=scores.get, reverse=True)
90
 
91
 
@@ -116,7 +115,8 @@ def retrieve(question: str, k: int = 5, mode: str = "dense") -> list[dict]:
116
  ids = _rerank(question, _dense_ids(question, CANDIDATES))[:k]
117
  elif mode in ("hybrid", "hybrid_rerank"):
118
  fused = _rrf_fuse([_dense_ids(question, CANDIDATES),
119
- _bm25_ids(question, CANDIDATES)])
 
120
  candidates = fused[:CANDIDATES]
121
  if mode == "hybrid_rerank":
122
  candidates = _rerank(question, candidates)
 
79
  return [_chunk_ids[i] for i in ranked[:n]]
80
 
81
 
82
+ def _rrf_fuse(rankings: list[list[str]], weights: tuple) -> list[str]:
83
+ """Weighted RRF: score(id) = sum of w/(RRF_K + rank) over lists."""
 
84
  scores: dict[str, float] = {}
85
+ for ranking, w in zip(rankings, weights):
86
  for rank, cid in enumerate(ranking, 1):
87
+ scores[cid] = scores.get(cid, 0.0) + w / (RRF_K + rank)
88
  return sorted(scores, key=scores.get, reverse=True)
89
 
90
 
 
115
  ids = _rerank(question, _dense_ids(question, CANDIDATES))[:k]
116
  elif mode in ("hybrid", "hybrid_rerank"):
117
  fused = _rrf_fuse([_dense_ids(question, CANDIDATES),
118
+ _bm25_ids(question, CANDIDATES)],
119
+ weights=(2.0, 1.0))
120
  candidates = fused[:CANDIDATES]
121
  if mode == "hybrid_rerank":
122
  candidates = _rerank(question, candidates)