본문 바로가기
C.W.K.
Stream
Lesson 02 of 05 · published

Reciprocal Rank Fusion

~18 min · hybrid, fusion

Level 0Scout
0 XP0/41 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

점수를 그대로 합치기 어려운 이유

검색기마다 서로 다른 척도로 점수를 매겨. 원점수를 그냥 더하면 숫자 범위가 큰 순위기가 우연히 결과를 지배해. 실제 시스템에서 널리 쓰는 해결책은 간단해. 점수가 아니라 순위로 결합하는 거야.

Reciprocal Rank Fusion(RRF)

각 후보에 대해 모든 순위기의 RRF = sum(1 / (k + rank_i))를 더해. 여기서 rank_i는 i번째 순위기에서의 위치이며 1이 가장 높아. k는 완화 상수고, 2009년 Cormack 논문이 사용한 60이 표준 기본값이야.

이렇게 얻은 결합 점수는 튀는 값에 강하고, 검색기마다 매개변수를 따로 조정할 필요가 없으며, 검색기가 3개든 5개든 10개든 같은 방식으로 쓸 수 있어.

Code

10줄 RRF·python
def reciprocal_rank_fusion(rankings: list[list[str]], k: int = 60) -> list[tuple[str, float]]:
    scores: dict[str, float] = {}
    for ranking in rankings:                       # 각 ranking 은 best first id 리스트
        for rank, doc_id in enumerate(ranking):
            scores[doc_id] = scores.get(doc_id, 0.0) + 1.0 / (k + rank + 1)
    return sorted(scores.items(), key=lambda kv: -kv[1])

vector_ids = [r[0] for r in vector_search(query, k=20)]
bm25_ids   = [r[0] for r in bm25_search(query,   k=20)]

for doc_id, score in reciprocal_rank_fusion([vector_ids, bm25_ids])[:10]:
    print(f'{score:.4f}  {doc_id}')

External links

Exercise

이전 연습에서 얻은 벡터 순위와 BM25 순위를 RRF로 결합해. 벡터만 쓴 경우, BM25만 쓴 경우, 단순 합집합과 상위 다섯 결과의 적중률을 비교하고 RRF가 어디서 이기고 지는지 기록해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.