밀집 검색과 희소 검색의 비교: 상충 관계
밀집 임베딩이 정확한 키워드 일치를 놓치는 경우와 BM25가 의미상 바꿔 표현된 문장을 놓치는 경우를 이해하고, 두 방식을 결합하면 어느 한 방식만 사용할 때보다 일관되게 더 나은 성능을 내는 이유를 알아봅니다.
밀집 검색과 희소 검색의 비교: 상충 관계은(는) CoddyKit의 무료 AI Engineering Academy 강의입니다. 이것은 4개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Engineering Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Engineering Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
근본적으로 다른 두 가지 검색 신호
최신 검색 시스템은 서로 다른 두 가지 신호에 의존합니다. 밀집 검색은 의미를 연속 벡터 공간에 인코딩하고, 희소 검색은 정확한 용어의 출현 횟수를 셉니다. 이 두 신호는 서로 보완적이며 대체 관계가 아닙니다. 각 신호의 장단점을 이해하는 것이 두 신호를 효과적으로 사용하는 시스템을 구축하는 첫 단계입니다.
밀집 임베딩의 작동 방식
밀집 검색은 신경망 인코더를 사용하여 질의와 각 문서를 고차원 벡터로 변환합니다. 유사도는 벡터 사이의 코사인 거리 또는 내적으로 측정합니다. 인코더는 대규모 텍스트 말뭉치로 학습되었기 때문에 공통 단어가 전혀 없더라도 의미적으로 관련된 구문이 벡터 공간에서 서로 가까워집니다. 이것이 밀집 검색의 핵심 장점입니다.
from openai import OpenAI
import numpy as np
client = OpenAI()
def embed(text: str) -> list[float]:
resp = client.embeddings.create(
model='text-embedding-3-small',
input=text,
)
return resp.data[0].embedding
def cosine_similarity(a, b):
a, b = np.array(a), np.array(b)
return float(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)))
q = embed('How do I cancel my subscription?')
d = embed('Steps to unsubscribe from the service')
print(cosine_similarity(q, d)) # high similarity despite different words밀집 검색이 실패하는 경우
밀집 모델은 인코더 학습 과정에서 충분히 나타나지 않았던 희귀 용어를 처리하는 데 어려움을 겪습니다. RTX-4090-Ti-OC 같은 특정 제품 모델 번호, 의약품 이름, 독점적인 내부 식별자가 포함된 질의는 인코더가 해당 토큰 시퀀스에 대한 학습된 표현을 갖고 있지 않기 때문에 올바른 문서와 일치하지 않는 경우가 많습니다. 벡터가 임베딩 공간에서 도움이 되지 않는 위치에 놓이는 것입니다.
희소 BM25 검색의 작동 방식
BM25(Best Matching 25)는 문서에 질의 용어가 얼마나 자주 나타나는지를 바탕으로 문서에 점수를 매기는 확률적 순위 함수입니다. 문서 길이에 따라 정규화하고 용어 빈도 포화 효과를 완화합니다. 그 결과 희소 점수 벡터가 생성됩니다. 문서에는 전체 어휘의 일부만 포함되므로 대부분의 차원은 0입니다.
# BM25 scoring formula (conceptual)
# score(D, Q) = sum over query terms t of:
# IDF(t) * (tf(t,D) * (k1 + 1)) / (tf(t,D) + k1 * (1 - b + b * |D|/avgdl))
# k1 controls term frequency saturation (typically 1.2-2.0)
# b controls document length normalization (typically 0.75)
# IDF(t) = log((N - df(t) + 0.5) / (df(t) + 0.5))
# N = total documents, df(t) = documents containing term t
# tf(t,D) = frequency of t in document D, |D| = doc length, avgdl = average doc lengthBM25의 강점: 정확한 용어와 전문 용어
BM25는 정확히 일치해야 하는 정확한 기술 용어, 제품 이름, 오류 코드, 숫자 식별자가 포함된 질의에서 뛰어난 성능을 보입니다. ORA-01017(Oracle 오류 코드)에 대한 질의를 수행하면 해당 문자열을 정확히 포함하는 문서가 데이터베이스 인증을 일반적으로 설명하는 문서보다 훨씬 높은 순위에 오릅니다. 특정 코드를 본 적이 없는 밀집 모델에서는 이것이 불가능합니다.
from rank_bm25 import BM25Okapi
corpus = [
'Oracle database ORA-01017 invalid username or password logon denied',
'Database authentication and connection troubleshooting guide',
'How to resolve login errors in Oracle and MySQL databases',
]
tokenized_corpus = [doc.lower().split() for doc in corpus]
bm25 = BM25Okapi(tokenized_corpus)
query = 'ORA-01017 error fix'
scores = bm25.get_scores(query.lower().split())
print(dict(zip(range(len(corpus)), scores)))
# doc 0 scores highest because it contains ORA-01017BM25가 실패하는 경우: 바꿔 쓰기와 동의어
BM25는 의미를 바꿔 표현한 문장을 인식하지 못합니다. '자동차 엔진 수리'에 관한 문서는 정확히 일치하는 단어가 없기 때문에 '차량 모터 유지 관리'에 대한 질의에 0점을 받습니다. 때로는 어휘 격차라고도 하는 이 어휘 불일치 문제 때문에 순수 키워드 검색은 같은 생각을 다른 단어로 표현한 관련 콘텐츠를 대량으로 놓치게 됩니다.
from rank_bm25 import BM25Okapi
corpus = [
'automobile engine repair and maintenance tips',
'car motor maintenance guide for beginners',
'vehicle powertrain service intervals',
]
tokenized = [doc.split() for doc in corpus]
bm25 = BM25Okapi(tokenized)
scores = bm25.get_scores(['car', 'motor', 'maintenance'])
print(scores)
# doc 1 scores high, doc 0 and 2 score lower despite being semantically related벤치마크 근거: 하이브리드 방식의 일관된 우위
BEIR, MS MARCO 및 기업 질의응답 데이터 세트의 벤치마크에서는 하이브리드 검색이 밀집 검색이나 희소 검색만 사용하는 방식보다 일관되게 우수하다는 결과가 나타납니다. NDCG@10 기준으로 5~15% 향상됩니다. BM25가 도움을 주는 사실 확인형 검색과 밀집 임베딩이 도움을 주는 바꿔 쓰기 질의가 섞인 데이터 세트에서 향상 폭이 가장 큽니다. 모든 질의 유형에서 단 하나의 검색 방식이 우세하지는 않습니다.
질의 유형 분석: 어떤 검색기가 우세한가
질의 유형을 분석하면 어떤 검색기가 더 나은 성능을 낼지 예측할 수 있습니다. 밀집 검색은 개념적 질문, 바꿔 쓰기, 광범위한 주제 질의에서 우세합니다. BM25는 고유명사, 버전 번호, 코드 조각, 두문자어, 희귀한 기술 용어가 포함된 질의에서 우세합니다. 하이브리드 방식은 질의 유형을 미리 알 수 없을 때 항상 우세합니다. 운영 환경에서는 대부분 이 경우에 해당합니다.
# Query type heuristics
def predict_retriever_advantage(query: str) -> str:
tokens = query.split()
has_numbers = any(t[0].isdigit() for t in tokens)
has_uppercase_acronyms = any(t.isupper() and len(t) > 2 for t in tokens)
is_short = len(tokens) <= 4
if has_numbers or has_uppercase_acronyms:
return 'BM25 likely wins (exact terms)'
elif is_short:
return 'Dense likely wins (semantic matching needed)'
else:
return 'Hybrid recommended (mixed signals)'점수 비호환성 문제
밀집 검색 결과와 희소 검색 결과를 결합하는 일은 두 결과의 점수가 서로 호환되지 않는 척도로 표현되기 때문에 쉽지 않습니다. 코사인 유사도는 -1에서 1 사이의 값을 생성하지만, BM25는 말뭉치 크기에 따라 달라지는 상한 없는 양수 점수를 생성합니다. 따라서 두 점수를 단순히 더할 수는 없습니다. 일반적인 해결 방법은 점수 기반 결합 대신 순위 기반 결합을 사용하는 것입니다. 즉, 원시 점수가 아니라 순위가 매겨진 목록을 병합합니다.
실전 판단: 각각 언제 사용할까
말뭉치가 어휘가 일관된 좁은 분야에 속하고, 바꿔 쓴 표현 사이에서도 의미를 일반화해야 한다면 밀집 검색만 사용하십시오. 질의가 주로 정확한 식별자를 찾는 조회형이고 데이터셋이 작아 전수 검색이 가능하다면 BM25만 사용하십시오. 질의 유형이 다양한 모든 운영 RAG 시스템에서는 하이브리드 검색을 사용하십시오. 추가 비용은 크지 않지만 재현율 향상은 상당하기 때문입니다.
성능과 인프라 간의 절충
밀집 검색에는 GPU 가속 근사 최근접 이웃 검색 또는 벡터 데이터베이스가 필요하므로 인프라 비용이 추가됩니다. BM25는 역색인을 사용해 CPU에서만 실행되며 매우 빠릅니다. 하이브리드 검색에는 두 인프라 구성 요소와 결합 단계가 모두 필요합니다. 대부분의 운영 사용 사례에서는 재현율 향상을 위해 추가 복잡성을 감수할 만하지만, 인프라 예산과 비교해 판단해야 합니다.
빠른 확인
이 수업에서 배운 밀집 검색과 희소 검색의 절충점을 얼마나 이해했는지 확인해 보십시오.
수업 요약
이 수업에서는 다음을 배웠습니다. 밀집 검색은 의미를 포착하지만 드문 정확한 용어에는 약하고, BM25 희소 검색은 정확한 키워드를 처리하지만 바꿔 쓴 표현을 놓치며, 하이브리드 검색은 다양한 질의 유형에서 어느 한 방법만 사용하는 것보다 일관되게 더 나은 성능을 냅니다. 두 방법의 점수는 서로 호환되지 않으므로 점수를 더하지 말고 순위 결합을 사용해 병합해야 합니다. 다음으로 Python에서 BM25 키워드 검색을 구현합니다.
AI 튜터와 함께 Python을(를) 배우세요 — 무료
브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.
- 코스
- 30
- 레슨
- 120
자주 묻는 질문
“밀집 검색과 희소 검색의 비교: 상충 관계” 강의는 무료인가요?
네 — “밀집 검색과 희소 검색의 비교: 상충 관계” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Engineering Academy 강의 전체를 잠금 해제할 수 있습니다. AI Engineering Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“밀집 검색과 희소 검색의 비교: 상충 관계”에서 뭘 배우나요?
밀집 임베딩이 정확한 키워드 일치를 놓치는 경우와 BM25가 의미상 바꿔 표현된 문장을 놓치는 경우를 이해하고, 두 방식을 결합하면 어느 한 방식만 사용할 때보다 일관되게 더 나은 성능을 내는 이유를 알아봅니다. 브라우저에서 직접 실행하는 실습 코드로 AI Engineering Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
AI Engineering Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 AI Engineering Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 1번째 강의입니다.
“밀집 검색과 희소 검색의 비교: 상충 관계” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 AI Engineering Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 AI Engineering Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 밀집 검색과 희소 검색의 비교: 상충 관계
- BM25 키워드 검색 구현
- 점수 병합을 위한 상호 순위 융합
- Pinecone과 pgvector의 하이브리드 검색