일전에 Pinecorn Vector DB에 올라온 유튜브 컨텐츠를 본적이있다.
Keyword 와 embedding 을 동시에 결합한 hybrid search에 관한 내용이였다.
즉 sparse vector와 dense vector의 유사성 결과를 결합하여 둘 다 사용하는 방식이다.
하지만 pinecorn을 사용하면 서비스 시 라이센스 비용이 발생하게된다.
그래서 당시에는 직접 구현해보려고 했지만, 결합하기 어려웠다.
왜냐하면, 벡터의 유사성은 0~1로 맵핑할 수 있지만,
keyword 의 점수 스코어인 BM25 스코어는 정해진 범위가 없었기 때문이였다.
(0~1값으로 맵핑하기가 어려웠다.)
적절하게 조합하면 사용할 수 있겠지만, 그것은 검증된 방법이 아닌 임의로 사용한 방법이라
설득하기도 어려울 뿐더러, 지속적인 테스트가 동반되어야했다.
하지만, 엘라스틱서치에서 발표한 Vector Search 자료에서 RRF에 대한 내용을 알고
적절하게 두 쿼리에 대한 검색 결과를 결합하는 방법을 알수있었다.
Reciprocal rank fusion (RRF)은 서로 다른 관련성 지표(relevance indicators)를 가진 여러 개의 결과 집합(result sets)을 하나의 결과 집합으로 결합하는 방법입니다.
RRF는 튜닝을 필요로 하지 않으며, 서로 다른 관련성 지표들이 상호 관련되지 않아도 고품질의 결과를 얻을 수 있습니다.
RRF는 각 문서의 순위에 대한 점수를 결정하기 위해 다음과 같은 공식을 사용합니다.
score = 0.0
for q in queries:
if d in result(q):
score += 1.0 / ( k + rank( result(q), d ) )
return score
# k는 순위에 대한 상수입니다.
# q는 질의(query)의 집합에서 하나의 질의를 의미합니다.
# d는 q의 결과 집합에서의 문서(document)를 나타냅니다.
# result(q)는 질의 q의 결과 집합을 의미합니다.
# rank(result(q), d)는 d가 result(q)에서의 순위를 나타냅니다. 순위는 1부터 시작합니다.
위의 공식에서,
각 질의(query)에 대해 순회하며 다음 작업을 수행합니다.
해당 문서(d)가 질의의 결과 집합(result(q))에 존재한다면,
점수(score)에 1.0을 해당 문서의 순위의 역수로 더합니다.
여기서 순위는 1부터 시작합니다. 즉, 순위가 낮을수록 높은 점수를 얻게 됩니다.
각 질의에 대해 순회를 마친 후, 최종적인 점수를 반환합니다.
이 점수는 각 질의에서의 순위를 고려하여 문서의 상대적인 중요도를 반영합니다.
따라서, RRF는 다양한 관련성 지표를 가진 결과 집합들을 효과적으로 결합하여 더 정확하고 종합적인 결과를 얻을 수 있도록 도와줍니다.
예를 들어, 검색 엔진에서 "과일"에 대한 세 가지 다른 질의 결과 집합이 있습니다. 각 질의 결과 집합은 다음과 같은 문서들을 포함하고 있습니다:
질의 1 결과(result(q1)): [A, B, C, D]
질의 2 결과(result(q2)): [B, D, E, F]
질의 3 결과(result(q3)): [A, C, F, G]
여기서 k는 1로 설정하겠습니다.
RRF를 사용하여 이들 결과 집합을 결합하여 최종 결과 집합을 생성합니다. 각 문서의 점수는 다음과 같이 계산됩니다:
문서 A의 점수:
score(A) = 1.0 / (1 + rank(result(q1), A)) + 1.0 / (1 + rank(result(q3), A))
= 1.0 / (1 + 1) + 1.0 / (1 + 1) + 0
= 0.5 + 0.5 + 0
= 1.0
문서 B의 점수:
score(B) = 1.0 / (1 + rank(result(q1), B)) + 1.0 / (1 + rank(result(q2), B))
= 1.0 / (1 + 2) + 1.0 / (1 + 1) + 0
= 0.33 + 0.5 + 0
= 0.83
문서 C의 점수:
score(C) = 1.0 / (1 + rank(result(q1), C)) + 1.0 / (1 + rank(result(q3), C))
= 1.0 / (1 + 3) + 0 + 1.0 / (1 + 2)
= 0.25 + 0 +0.33
= 0.58
나머지 문서들에 대해서도 동일한 방식으로 점수를 계산합니다.
따라서, RRF를 사용하여 결합된 결과 집합은 다음과 같습니다 (순위는 점수가 높은 순서로 매겨집니다):
최종 결과 집합: [A, B, C, D, E, F, G]
이 예시에서 RRF를 통해 다른 질의 결과를 결합하여 상대적인 중요도에 따라 문서의 순위를 조정했습니다. 이를 통해 다른 질의 결과의 관련성을 종합적으로 고려하여 더 나은 검색 결과를 얻을 수 있습니다.
RRF에 대한 공식을 이해해보았다.
정확히 Pinecorn에서 RRF를 사용하는지는 알 수 없지만,
Elastic Search에 Vector Search는 RRF를 사용한다고 명시되어있다.
현재 우리 챗봇은 embedding만 사용해서 결과를 도출하지만,
BM25의 장점도 충분히 있으니 하이브리드를 적용해보고싶다.
참고: https://www.elastic.co/guide/en/elasticsearch/reference/current/rrf.html