RRF(Reciprocal Rank Fusion)
다중 검색기(BM25, 임베딩 등)의 결과를 통합할 때 점수 척도가 달라 발생하는 문제를 해결합니다.
RRF 알고리즘 핵심
순위 기반 점수 계산 공식:
document_score = ∑(1 / (k + rank_position))
k는 일반적으로 60으로 설정하며, 상위 순위 문서에 가중치를 부여합니다.
Python 구현 예제
from collections import defaultdict
def combine_rankings(ranking_sets, k=60):
combined_scores = defaultdict(float)
for ranking in ranking_sets:
for position, doc_id in enumerate(ranking):
combined_scores[doc_id] += 1 / (k + position + 1)
return sorted(combined_scores.items(),
key=lambda item: item[1],
reverse=True)
# 사용 예시
bm25_ranking = ['docA', 'docB', 'docC']
vector_ranking = ['docC', 'docA', 'docD']
merged_results = combine_rankings([bm25_ranking, vector_ranking])
Cross-Encoder 재정렬
쿼리와 문서를 동시에 입력받아 관련성을 직접 평가하는 딥러닝 모델입니다.
Bi-Encoder vs Cross-Encoder
- Bi-Encoder: 단일 벡터 비교, 빠른 속도但 정확도 낮음
- Cross-Encoder: 전체 문맥 분석, 높은 정확도但 처리 속도 느림
Python 구현 예제
from sentence_transformers import CrossEncoder
def rerank_documents(query, candidate_docs):
reranker = CrossEncoder("cross-encoder/ms-marco-MiniLM-L-12-v2")
query_doc_pairs = [(query, doc) for doc in candidate_docs]
relevance_scores = reranker.predict(query_doc_pairs)
return sorted(zip(candidate_docs, relevance_scores),
key=lambda x: x[1],
reverse=True)
# 사용 예시
search_query = "신경망 최적화 방법"
document_candidates = ["문서1 내용", "문서2 내용", "문서3 내용"]
sorted_results = rerank_documents(search_query, document_candidates)
통합 검색 시스템 아키텍처
- BM25로 상위 100개 문서 초기 검색
- 벡터 검색으로 상위 100개 문서 추가 검색
- RRF를 이용한 순위 통합
- 상위 20개 후보 문서 선정
- Cross-Encoder로 재정렬
- 최종 상위 5개 문서 선택
기술 비교
| 특성 | RRF | Cross-Encoder |
|---|---|---|
| 처리 속도 | 초고속 | 상대적 저속 |
| 정확도 | 중간 | 매우 높음 |
| 사용 시점 | 다중 소스 통합 | 후보 문서 재정렬 |
실무 적용 가이드
- RRF로 다양한 검색 결과 통합
- Cross-Encoder 적용은 20~50개 후보 문서로 제한
- 전체 문서에 Cross-Encoder 적용 금지(성능 저하)