26 lines
1022 B
Python
26 lines
1022 B
Python
"""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]
|