feat(retrieval): 实现 Embedding/Vector/RRF/Reranker 混合检索引擎
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
"""RRF 排名融合与分数归一化。"""
|
||||
|
||||
|
||||
def rrf_fuse(ranked_lists: list[list[str]], k: int = 60) -> dict[str, float]:
|
||||
"""Reciprocal Rank Fusion:对多个「按相关性降序」的 block_id 列表做排名融合。
|
||||
|
||||
每个 block 的融合分 = Σ 1/(k + rank),rank 从 1 开始。返回 block_id -> 融合分。
|
||||
"""
|
||||
scores: dict[str, float] = {}
|
||||
for ids in ranked_lists:
|
||||
for rank, block_id in enumerate(ids, start=1):
|
||||
scores[block_id] = scores.get(block_id, 0.0) + 1.0 / (k + rank)
|
||||
return scores
|
||||
|
||||
|
||||
def normalize_scores(items: list[tuple[str, float]]) -> list[tuple[str, float]]:
|
||||
"""把 (block_id, score) 列表 min-max 归一化到 [0,1],score 越大越相关。"""
|
||||
if not items:
|
||||
return []
|
||||
values = [score for _, score in items]
|
||||
lo, hi = min(values), max(values)
|
||||
span = hi - lo
|
||||
if span == 0:
|
||||
return [(block_id, 1.0) for block_id, _ in items]
|
||||
return [(block_id, round((score - lo) / span, 6)) for block_id, score in items]
|
||||
Reference in New Issue
Block a user