74caa9d112
- crawler/:豆果(主)/下厨房/Bing 爬虫 + dishes.jsonl(3056 菜→9167 图映射)+ verify_repair 按 URL 重下 - retrieval/:三路检索(BM25 + 本地 BGE-M3 向量 + RRF 融合),FastAPI + 前端;写死图片目录(默认 crawler/images,可 IMAGE_DIR 覆盖)、绑 0.0.0.0 局域网访问、启动自动建索引、服务器 serve 图片 - 图片(1.7G)与向量模型(2.3G)不进 git Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
20 lines
873 B
Python
20 lines
873 B
Python
# -*- coding: utf-8 -*-
|
|
"""RRF(Reciprocal Rank Fusion)融合多路排名。
|
|
|
|
RRF 只看「排名」不看「分数量纲」,天然解决 BM25 分数与余弦相似度不可比的问题:
|
|
fused(d) = Σ_method w_method * 1 / (k + rank_method(d))
|
|
k 越大,头部名次的权重差异越平缓(经验默认 60)。
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
|
|
def rrf(rankings: dict[str, list[str]], weights: dict[str, float],
|
|
k: int = 60) -> list[tuple[str, float]]:
|
|
"""rankings: {method: [name 按相关性降序]};返回 [(name, fused_score)] 降序。"""
|
|
score: dict[str, float] = {}
|
|
for method, names in rankings.items():
|
|
w = weights.get(method, 1.0)
|
|
for rank, name in enumerate(names, start=1):
|
|
score[name] = score.get(name, 0.0) + w * (1.0 / (k + rank))
|
|
return sorted(score.items(), key=lambda kv: kv[1], reverse=True)
|