검색
← 모듈 로드맵

검색의 기초: TF-IDF · BM25 · 벡터 검색 · 검색 평가 지표

강의 · 입문자 · KAITABASE 정리

원제 · Introduction to Information Retrieval (Manning · Raghavan · Schütze) 참고

역색인 · TF-IDF · BM25 · 벡터 검색 · P@k · MRR · nDCG를 손계산하는 RAG 검색 기초

먼저 알아야 할 것

임베딩과 코사인 유사도로그 계산토큰화

다루는 내용

RAG 품질을 좌우하는 검색 단계의 기초를 다룹니다. 역색인과 tf-idf, BM25의 tf 포화 · 길이 보정을 작은 문서 4개로 직접 계산합니다. 밀집 벡터 검색과 근사 최근접 탐색, 하이브리드 검색, 청킹 원칙, precision@k · recall@k · MRR · nDCG 평가 지표까지 정리합니다.

해설

검색의 기초: TF-IDF · BM25 · 벡터 검색 · 검색 평가 지표

RAG(검색 증강 생성)의 품질은 대부분 검색 단계 에서 정해집니다. 이 수업에서는 검색 엔진의 기본 자료 구조인 역색인, 단어 일치 점수 TF-IDF와 BM25, 임베딩으로 하는 벡터 검색과 근사 최근접 탐색, 둘을 합치는 하이브리드, 문서 자르기(청킹), 그리고 검색 결과가 좋은지 숫자로 재는 precision@k · recall@k · MRR · nDCG를 작은 예로 직접 계산합니다.

항목내용
참고 출처Christopher D. Manning · Prabhakar Raghavan · Hinrich Schütze, 『Introduction to Information Retrieval』 (Cambridge University Press, 2008, 온라인 무료판 nlp.stanford.edu/IR-book) — 6장(가중치 · tf-idf), 8장(평가), 11.4.3절(Okapi BM25)
트랙 · 수준RAG·검색 · 기초
이 수업이 다루는 범위역색인, tf · idf · tf-idf, BM25와 k1k_1 · bb, 밀집 벡터 검색과 ANN, 하이브리드 검색, 청킹, 검색 평가 지표

들어가기 전에

  • 임베딩과 벡터 유사도 — 문장 벡터와 코사인 유사도. 벡터 검색은 이것을 대량으로 하는 일입니다.
  • 로그(log⁡\log)를 계산할 줄 알면 충분합니다. 계산기는 써도 됩니다.

한눈에 보기

  • 역색인이 왜 빠른 검색의 바탕인지 압니다.
  • 드문 단어에 더 큰 점수를 주는 idf, 같은 단어 반복을 덜 쳐주는 BM25의 포화 · 길이 보정을 숫자로 계산합니다.
  • 단어 일치 검색(희소)과 벡터 검색(밀집)이 각각 언제 강하고 약한지 비교합니다.
  • precision@k · recall@k · MRR · nDCG를 손으로 계산하고, RAG 평가에 어떻게 쓰는지 압니다.

1. 역색인

직관(해설용 비유). 책 맨 뒤의 '찾아보기'입니다. 단어마다 그 단어가 나오는 쪽 번호가 적혀 있어서, 책 전체를 넘기지 않고 바로 찾아갑니다.

단계.

  1. 문서를 토큰(단어)으로 자릅니다.
  2. 단어마다 "그 단어가 들어 있는 문서 목록(포스팅 목록)"을 만듭니다. 몇 번 나왔는지(tf)도 함께 적습니다.
  3. 질의가 오면 질의 단어들의 포스팅 목록만 꺼내 점수를 매깁니다.

숫자로 해 보기(해설용 문서 4개).

문서내용(토큰)길이
d1환불 규정 환불 기간4
d2배송 일정 안내3
d3환불 신청 방법 안내 페이지5
d4회원 가입 안내3

역색인의 일부: 환불 → d1(2회), d3(1회), 기간 → d1(1회), 안내 → d2, d3, d4. 질의 「환불 기간」은 d1 · d3만 보면 됩니다. 문서가 수백만 개여도 질의 단어의 목록만 읽습니다.

2. tf · idf · tf-idf

직관. 문서에 질의 단어가 많이 나올수록(tf), 그리고 그 단어가 다른 문서엔 드물수록(idf) 그 문서가 관련 있을 가능성이 큽니다. '안내'처럼 어디에나 나오는 단어는 구별력이 없습니다.

IR-book의 역문서 빈도(inverse document frequency) 정의는 다음과 같습니다.

idft=log⁡Ndft,tf-idft,d=tft,d×idft,점수(q,d)=∑t∈qtf-idft,d\mathrm{idf}_t = \log\frac{N}{\mathrm{df}_t},\qquad \text{tf-idf}_{t,d} = \mathrm{tf}_{t,d}\times\mathrm{idf}_t,\qquad \text{점수}(q,d)=\sum_{t\in q}\text{tf-idf}_{t,d}
기호뜻
NN전체 문서 수
dft\mathrm{df}_t단어 tt 가 들어 있는 문서 수
tft,d\mathrm{tf}_{t,d}문서 dd 에서 단어 tt 가 나온 횟수
qq질의(단어들의 모음)

IR-book은 예에서 상용로그를 쓰며, 로그의 밑은 순위에 영향을 주지 않는다고 말합니다. 위의 tf-idf는 가장 단순한 형태이고, 책에서는 tf에 로그를 씌우는 등 여러 변형을 다룹니다.

숫자로 해 보기(해설용, 상용로그). N=4N=4. '환불'은 d1 · d3에 있어 df=2\mathrm{df}=2, idf=log⁡102≈0.301\mathrm{idf}=\log_{10}2\approx0.301. '기간'은 d1에만 있어 idf=log⁡104≈0.602\mathrm{idf}=\log_{10}4\approx0.602.

  • d1: 2×0.301+1×0.602≈1.2042\times0.301 + 1\times0.602 \approx 1.204
  • d3: 1×0.301≈0.3011\times0.301 \approx 0.301
  • d2 · d4: 0

순위는 d1 > d3 입니다. '기간'이 더 드물어서 한 번 나와도 '환불' 두 번만큼의 점수를 줍니다.

3. BM25

직관. tf-idf에는 두 가지 아쉬움이 있습니다. ① 단어가 10번 나온 문서가 1번 나온 문서보다 10배 관련 있지는 않습니다(포화가 필요). ② 긴 문서는 단어가 많아서 저절로 tf가 커집니다(길이 보정이 필요). BM25는 이 둘을 손잡이 두 개(k1k_1, bb)로 조절합니다.

IR-book 11.4.3절의 Okapi BM25 문서 점수입니다.

RSVd=∑t∈qlog⁡Ndft⋅(k1+1) tftdk1((1−b)+b LdLave)+tftd\mathrm{RSV}_d = \sum_{t\in q}\log\frac{N}{\mathrm{df}_t}\cdot \frac{(k_1+1)\,\mathrm{tf}_{td}}{k_1\left((1-b)+b\,\dfrac{L_d}{L_{ave}}\right)+\mathrm{tf}_{td}}
기호뜻
k1k_1tf 포화 정도. 0이면 '있다/없다'만 보고, 크면 원래 tf에 가까워짐
bb길이 보정 정도(0~1). 1이면 길이로 완전히 보정, 0이면 보정 없음
LdL_d문서 dd 의 길이
LaveL_{ave}전체 문서의 평균 길이

IR-book은 실험상 k1k_1 을 1.2~2 사이, b=0.75b=0.75 로 두는 것이 합리적이며, 가능하면 개발용 평가 데이터로 맞추라고 권합니다. 책에는 log⁡N−dft+12dft+12\log\frac{N-\mathrm{df}_t+\frac12}{\mathrm{df}_t+\frac12} 형태의 idf도 나오는데, 이 형태는 절반 넘는 문서에 나오는 단어에 음수 점수를 줄 수 있어 0으로 하한을 두라고 안내합니다.

숫자로 해 보기(해설용, k1=1.2k_1=1.2, b=0.75b=0.75, 자연로그). 평균 길이 Lave=(4+3+5+3)/4=3.75L_{ave}=(4+3+5+3)/4=3.75.

  • d1(길이 4)의 분모 보정값: 1.2×(0.25+0.75×4/3.75)=1.2×1.05=1.261.2\times(0.25+0.75\times4/3.75)=1.2\times1.05=1.26
    • '환불'(tf 2, idf ln⁡2≈0.693\ln2\approx0.693): 0.693×2.2×21.26+2≈0.693×1.350≈0.9360.693\times\frac{2.2\times2}{1.26+2}\approx0.693\times1.350\approx0.936
    • '기간'(tf 1, idf ln⁡4≈1.386\ln4\approx1.386): 1.386×2.21.26+1≈1.386×0.973≈1.3501.386\times\frac{2.2}{1.26+1}\approx1.386\times0.973\approx1.350
    • 합계 ≈2.285\approx 2.285
  • d3(길이 5)의 보정값: 1.2×(0.25+0.75×5/3.75)=1.51.2\times(0.25+0.75\times5/3.75)=1.5
    • '환불'(tf 1): 0.693×2.22.5≈0.6100.693\times\frac{2.2}{2.5}\approx0.610

순위는 tf-idf와 같이 d1 > d3 입니다. d3는 길어서 같은 tf 1이라도 점수가 깎였습니다.

포화 확인(해설용). 평균 길이 문서에서 (k1+1)tfk1+tf\frac{(k_1+1)\mathrm{tf}}{k_1+\mathrm{tf}} 는 tf가 1, 2, 5, 10일 때 1.00, 1.38, 1.77, 1.96 입니다. 상한 k1+1=2.2k_1+1=2.2 를 넘지 못합니다. 같은 단어를 도배해도 점수가 끝없이 오르지 않습니다.

왜 아직도 BM25인가. 학습이 필요 없고, 빠르고, 제품 코드 · 오류 번호 · 사람 이름처럼 정확히 일치해야 하는 단어 에 강합니다. 그래서 RAG에서도 기본 비교 기준(베이스라인)이자 하이브리드 검색의 한 축으로 계속 씁니다.

4. 밀집 벡터 검색과 근사 최근접 탐색

직관. 단어 일치 검색은 "환불"과 "돈 돌려받기"를 다른 말로 봅니다. 문장을 임베딩 해 같은 의미 공간에 놓으면, 단어가 달라도 뜻이 가까운 문서를 찾을 수 있습니다.

단계.

  1. 문서 조각마다 문장 임베딩 벡터를 만들어 저장합니다(색인).
  2. 질의를 같은 모델로 벡터화합니다.
  3. 코사인 유사도(또는 정규화한 내적)가 큰 순서로 kk 개를 꺼냅니다.
d^=arg⁡max⁡d cos⁡(q,d)\hat d = \arg\max_{d}\ \cos(\mathbf q, \mathbf d)

근사 최근접 탐색(Approximate Nearest Neighbor, ANN). 문서가 수백만 개면 질의마다 모든 벡터와 비교하기 어렵습니다. 그래서 벡터들을 미리 묶음 · 그래프로 정리해 두고 가까울 법한 후보만 비교합니다. 대표적으로 군집으로 나눠 가까운 군집만 뒤지는 방식(IVF 계열)과, 이웃끼리 연결한 그래프를 따라가는 방식(HNSW 계열)이 있습니다. 정확도를 조금 내주고 속도를 크게 얻는 거래입니다. FAISS 같은 라이브러리와 벡터 DB가 이를 제공합니다.

희소 검색(BM25)밀집 검색(임베딩)
강점정확한 용어 · 코드 · 고유명사, 학습 불필요, 설명 쉬움다른 표현 · 동의어 · 질문형 질의
약점동의어 · 바꿔 말하기에 약함드문 고유명사 · 숫자에 약할 수 있음, 임베딩 모델 필요

하이브리드 검색. 두 방식의 결과를 합칩니다. 점수의 단위가 서로 달라서, 각자의 순위 만으로 합치는 방법이 흔합니다. 예를 들어 순위 역수 융합(Reciprocal Rank Fusion)은 문서마다 ∑1/(c+순위)\sum 1/(c+\text{순위}) 를 더합니다(cc 는 상수). 이렇게 넓게 후보를 모은 뒤, 질의와 문서를 함께 읽는 더 비싼 모델로 상위 몇 개만 다시 정렬(리랭킹)하는 구성이 많습니다.

5. 청킹: 문서를 얼마나 잘라 넣나

직관. 너무 크게 자르면 한 조각에 여러 주제가 섞여 벡터가 흐려지고 LLM에 넣을 토큰도 많아집니다. 너무 작게 자르면 답에 필요한 앞뒤 맥락이 잘려 나갑니다.

실무 원칙(해설).

  1. 문단 · 제목 같은 문서 구조를 따라 먼저 자릅니다.
  2. 조각 경계에서 문장이 끊기지 않도록 앞뒤를 조금 겹치게(overlap) 둡니다.
  3. 조각에 문서 제목 · 절 제목 같은 메타데이터를 붙여 검색과 출처 표시에 씁니다.
  4. 정답이 정해진 평가 질문 몇십 개로 조각 크기를 바꿔 가며 아래 지표로 비교해 정합니다. "정답 크기"는 데이터마다 다릅니다.
mermaid
flowchart LR
  A[문서] --> B[청킹 · 메타데이터]
  B --> C[역색인<br/>BM25]
  B --> D[임베딩 · ANN 색인]
  Q[질의] --> C
  Q --> D
  C --> E[순위 융합]
  D --> E
  E --> F[리랭킹 상위 k]
  F --> G[LLM에 근거로 전달]
  F --> H[평가: P@k · R@k · MRR · nDCG]

6. 검색 평가 지표

직관. "상위 몇 개 안에 정답 문서가 얼마나, 얼마나 위에 들어왔나"를 잽니다. RAG에서는 LLM이 상위 kk 개만 보므로 특히 중요합니다.

P@k=상위 k개 중 관련 문서 수k,R@k=상위 k개 중 관련 문서 수전체 관련 문서 수,MRR=1∣Q∣∑i=1∣Q∣1rankiP@k = \frac{\text{상위 }k\text{개 중 관련 문서 수}}{k},\qquad R@k = \frac{\text{상위 }k\text{개 중 관련 문서 수}}{\text{전체 관련 문서 수}},\qquad \mathrm{MRR} = \frac{1}{|Q|}\sum_{i=1}^{|Q|}\frac{1}{\mathrm{rank}_i}
DCG@k=∑m=1k2R(m)−1log⁡2(1+m),nDCG@k=DCG@k이상적인 순서의 DCG@k\mathrm{DCG}@k = \sum_{m=1}^{k}\frac{2^{R(m)}-1}{\log_2(1+m)},\qquad \mathrm{nDCG}@k = \frac{\mathrm{DCG}@k}{\text{이상적인 순서의 DCG}@k}
기호뜻
ranki\mathrm{rank}_i질의 ii 에서 첫 관련 문서의 순위(없으면 그 항은 0)
R(m)R(m)mm 위 문서의 관련도 점수(예: 0 무관, 1 관련, 2 매우 관련)
log⁡2(1+m)\log_2(1+m)아래 순위일수록 깎는 할인

IR-book 8장은 상위 kk 개의 정밀도(precision at k), 평균 정밀도의 평균(MAP), 그리고 위의 nDCG 식을 다룹니다. MRR은 이 장에서 정의하지 않는, 질의응답 평가에서 널리 쓰는 지표라 여기서 함께 소개합니다.

숫자로 해 보기(해설용). 관련 문서가 3개인 질의의 상위 5개 결과가 [관련, 무관, 관련, 무관, 무관] 이었습니다.

  • P@3=2/3≈0.667P@3 = 2/3 \approx 0.667, R@3=2/3≈0.667R@3 = 2/3 \approx 0.667 (관련 3개 중 2개를 찾음)

질의 3개에서 첫 관련 문서가 1위, 3위, 그리고 못 찾음이었다면 MRR=(1+1/3+0)/3≈0.444\mathrm{MRR} = (1 + 1/3 + 0)/3 \approx 0.444 입니다.

관련도 점수가 붙은 경우, 상위 3개가 [2, 0, 1] 이고 이상적인 순서가 [2, 1, 1] 이라면

  • DCG=31+01.585+12=3.5\mathrm{DCG} = \frac{3}{1} + \frac{0}{1.585} + \frac{1}{2} = 3.5
  • 이상 DCG=3+11.585+12≈4.131\mathrm{DCG} = 3 + \frac{1}{1.585} + \frac{1}{2} \approx 4.131
  • nDCG@3≈3.5/4.131≈0.847\mathrm{nDCG}@3 \approx 3.5/4.131 \approx 0.847

무엇을 쓸까. RAG에서 "LLM에게 근거가 하나라도 들어갔나"가 중요하면 recall@k, "맨 위에 바로 나오나"가 중요하면 MRR, 관련도가 여러 단계면 nDCG를 봅니다. 같은 평가 질문 세트를 고정해 두고 청킹 · 임베딩 모델 · 하이브리드 설정을 바꿀 때마다 같은 지표로 비교하는 것이 핵심입니다.

연습 문제

  1. 문서 1,000개 중 10개에만 나오는 단어의 idf(상용로그)는?
    • 풀이: log⁡10(1000/10)=log⁡10100=2\log_{10}(1000/10)=\log_{10}100 = 2 입니다.
  2. BM25에서 b=0b=0 이면 d3('환불' tf 1)의 '환불' 점수는? (k1=1.2k_1=1.2, 자연로그 idf)
    • 풀이: 보정값이 k1=1.2k_1=1.2 가 되어 0.693×2.21.2+1=0.693×1=0.6930.693\times\frac{2.2}{1.2+1}=0.693\times1=0.693 입니다. 길이 벌점이 사라졌습니다.
  3. 관련 문서 4개 중 상위 10개에 3개가 들어왔습니다. P@10, R@10은?
    • 풀이: P@10=3/10=0.3P@10=3/10=0.3, R@10=3/4=0.75R@10=3/4=0.75 입니다.
  4. 상위 3개 관련도가 [0, 2, 1], 이상 순서 [2, 1, 0] 일 때 nDCG@3은?
    • 풀이: DCG=0+3/1.585+1/2≈1.893+0.5=2.393\mathrm{DCG}=0 + 3/1.585 + 1/2 \approx 1.893+0.5=2.393, 이상 =3+1/1.585≈3.631=3+1/1.585\approx3.631 → ≈0.659\approx0.659 입니다.

스스로 점검

  1. idf가 '안내' 같은 흔한 단어의 점수를 낮추는 이유는?
    • 답: 많은 문서에 나와 N/dfN/\mathrm{df} 가 1에 가까워지고, 로그를 씌우면 0에 가까워지기 때문입니다. 구별력이 없는 단어이기 때문입니다.
  2. BM25의 k1k_1 과 bb 는 각각 무엇을 조절하나요?
    • 답: k1k_1 은 tf가 늘 때 점수가 얼마나 빨리 포화되는지, bb 는 문서 길이로 얼마나 보정할지를 조절합니다.
  3. 벡터 검색만 쓰지 않고 BM25와 섞는 이유는?
    • 답: 벡터 검색은 바꿔 말한 표현에 강하지만 제품 코드 · 고유명사처럼 정확히 일치해야 하는 질의에 약할 수 있어, 서로의 약점을 보완하기 위해서입니다.

용어 정리

용어쉬운 뜻
역색인(inverted index)단어 → 그 단어가 있는 문서 목록
tf(term frequency)문서 안에서 단어가 나온 횟수
df(document frequency)그 단어가 들어 있는 문서 수
idf드문 단어일수록 커지는 가중치 log⁡(N/df)\log(N/\mathrm{df})
BM25tf 포화와 문서 길이 보정을 넣은 단어 일치 점수
희소 검색 / 밀집 검색단어 일치 기반 / 임베딩 벡터 기반 검색
ANN(근사 최근접 탐색)정확도를 조금 양보하고 빠르게 가까운 벡터를 찾는 방법
하이브리드 검색희소 · 밀집 결과를 합치는 검색
리랭킹(reranking)후보를 더 정밀한 모델로 다시 정렬
청킹(chunking)문서를 검색 단위 조각으로 자르기
precision@k / recall@k상위 k개의 정확도 / 상위 k개가 찾아낸 정답 비율
MRR첫 정답 순위 역수의 평균
nDCG관련도와 순위를 함께 보는 정규화 점수

더 깊이 보려면

다음에 볼 것

라이선스

본문은 KAITABASE 자체 해설입니다. 참고 자료인 『Introduction to Information Retrieval』은 Cambridge University Press의 저작물로, 저자들이 온라인판을 무료로 공개하고 있습니다(본문 재배포가 아니라 개념 · 공식만 인용). 예시 문서 · 질의 · 순위는 이 수업을 위해 만든 해설용 예입니다.

출처

AI 원리부터 이해하기 · RAG·검색 모듈

RAG·검색 모듈 학습

이 글은 RAG·검색 모듈의 학습 자료입니다. 전체 21개 자료 중 1번째입니다.

AI 기초 과정은 현재 진도 저장을 지원하지 않습니다.

출처·원문

원문 보기

요약만

본문 자체 작성 · 참고 자료 IR-book(Cambridge UP, 온라인 무료판)