
초보자를 위한 벡터 검색의 원리 — 코사인 유사도까지 정리하기
요약
벡터 검색의 기본 원리와 코사인 유사도의 개념을 초보자 수준에서 설명합니다. 임베딩 벡터를 활용해 의미적 유사성을 찾는 과정과 기존 키워드 검색과의 차이점을 다룹니다.
핵심 포인트
- 벡터 검색은 고차원 공간에서 쿼리와 가장 가까운 벡터를 찾는 방식입니다.
- 키워드 일치가 아닌 문맥적 의미를 기반으로 검색이 가능합니다.
- 코사인 유사도는 두 벡터 사이의 각도를 이용해 유사도를 측정합니다.
- 인덱스 구축과 검색 단계가 세트로 이루어지는 것이 특징입니다.
RAG나 시맨틱 검색 (Semantic Search)의 해설에서는 「벡터 검색 (Vector Search)」이라는 용어가 빈번하게 등장하지만, 임베딩 (Embedding)을 통해 수치화한 후 실제로 어떻게 「가까운 문서」를 찾아내는지에 대해서는 파악하기 어렵다.
이 기사는 벡터 검색의 전체상과, 대표적인 유사도 지표인 **코사인 유사도 (Cosine Similarity)**를 초보자 눈높이에 맞춰 정리한다.
| 관점 | 내용 |
|---|---|
| 정의 | 텍스트를 임베딩 벡터 (Embedding Vector)로 변환하여, 쿼리 벡터 (Query Vector)와 가까운 벡터를 고속으로 찾는 검색 방식 |
| ... | |
| 포인트: 벡터 검색은 단독으로 작동하는 마법이 아니다. 사전에 문서를 임베딩하여 벡터 DB (Vector DB)에 저장하고, 검색 시 쿼리도 동일한 모델로 임베딩한다——이 2단계가 세트다. |
벡터 검색 (vector search / similarity search)이란, 고차원 벡터 공간 (High-dimensional Vector Space) 안에서 쿼리에 가장 가까운 벡터를 찾아내는 처리다.
기존의 전문 검색 (Full-text Search / Keyword Search)과의 차이점을 표로 정리한다.
| 방식 | 매칭 기준 | 예: 「퇴근 절차를 알려줘」 |
|---|---|---|
| 키워드 검색 | 단어의 일치 · 출현 빈도 | 「퇴근」 「절차」가 포함된 문서를 히트 |
| 벡터 검색 | 벡터 공간상의 거리 | 「업무 종료 시 체크리스트」도 히트할 수 있음 |
키워드가 완전히 일치하지 않더라도 의미가 가까우면 검색 결과에 나타난다. RAG에서 「사용자의 자연어 질문」으로부터 관련 문서를 끌어올 때, 이 성질이 중요해진다.
[인덱스 구축 (Index Construction, Offline)]
문서군
→ 청크 분할 (Chunk Splitting)
...
| 페이즈 | 할 일 | 주의점 |
|---|---|---|
| 인덱스 구축 | 모든 청크를 벡터화하여 저장 | 모델과 차원수 (Dimension)를 기록해 둘 것 |
| ... | ||
| 두 벡터가 「얼마나 가까운가」를 수치화하는 지표를 **유사도 메트릭 (Similarity Metric)**이라고 한다. 벡터 검색에서 가장 많이 사용되는 것이 **코사인 유사도 (Cosine Similarity)**다. |
코사인 유사도는 두 벡터가 이루는 각도의 코사인 값을 취하는 지표다.
cosine_similarity(A, B) = (A · B) / (|A| × |B|)
A · B : 벡터 A와 B의 내적 (Inner Product, 각 요소의 곱의 총합)
|A| : 벡터 A의 길이 (Euclidean Norm)
값의 범위는 -1 ~ 1이며, 1에 가까울수록 방향이 일치 = 의미가 가깝다고 해석한다.
| 코사인 유사도 | 의미 |
|---|---|
| 1.0 | 완전히 동일한 방향 (가장 유사) |
| ... | |
| 텍스트 임베딩에서는 대부분의 경우 0.5 ~ 0.9 범위에 스코어가 분포한다. 임계값 (Threshold)은 데이터셋마다 조정이 필요하다. |
| 이유 | 설명 |
|---|---|
| 문장의 길이에 강건 (Robust) | 벡터의 「방향」만을 보기 때문에, 짧은 문장과 긴 문장의 비교에서도 극단적으로 불리해지지 않음 |
| ... | |
| 지표 | 계산 방식 |
| --- | --- |
| 코사인 유사도 | 벡터의 각도 |
| ... | |
| 많은 임베딩 모델은 출력 벡터를 정규화 (Normalization, 길이를 1로 맞춤)한다. 이 경우, 코사인 유사도와 내적은 동일한 결과가 된다. |
최소한의 예시로, 3개 문장의 유사도를 계산해 본다.
import numpy as np
def cosine_similarity(a: np.ndarray, b: np.ndarray) -> float:
dot = np.dot(a, b)
...
실무에서는 sentence-transformers나 각 사의 임베딩 API를 통해 벡터화한 후, 동일한 계산을 수행한다.
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity
model = SentenceTransformer("paraphrase-multilingual-MiniLM-L12-v2")
...
「퇴근」과 「업무 종료」 쌍은 높은 스코어를, 「유급 휴가」는 낮은 스코어를 보이는 경향이 나타날 것이다.
문서가 수천 건이라면 전수와 유사도를 계산해도 문제가 없다. 하지만 수백만 ~ 수억 건이 되면, 쿼리마다 전수 계산하는 **전수 조사 (Brute-force / Exact Search)**는 너무 느리다.
여기서 사용되는 것이 **근사 최근접 이웃 탐색 (ANN: Approximate Nearest Neighbor)**이다.
| 방식 | 개요 | 대표 사례 |
|---|---|---|
| 전수 조사 (Exact) | 모든 벡터와 유사도를 계산 | 소규모 데이터용 |
| ... |
ANN은 '완전히 정확한 Top-K'가 아니라 '거의 정확한 Top-K'를 빠르게 반환하는 트레이드오프 (Trade-off)이다. RAG 실무에서는 99% 이상의 케이스에서 충분한 정밀도가 나온다.
주요 벡터 DB에는 검색 시 다음 파라미터를 지정한다.
| 파라미터 | 의미 | 전형적인 값 |
|---|---|---|
top_k | 반환할 건수 | 3~10 (RAG에서는 넉넉하게 가져온 뒤 리랭킹 (Re-ranking)도 수행) |
metric | 유사도의 종류 | cosine (텍스트용) |
score_threshold | 임계값 이하 제외 | 0.7~0.8 (데이터셋에 따라 조정) |
ef / nprobe | ANN의 정밀도와 속도의 트레이드오프 | DB 문서 참조 |
Pinecone의 예시 (개념):
# 개념 예시: 실제 SDK는 버전에 따라 다름
results = index.query(
vector=query_embedding,
...
pgvector의 예시:
-- 코사인 거리 (1 - 코사인 유사도)로 가까운 순으로 가져오기
SELECT content, 1 - (embedding <=> query_embedding) AS similarity
FROM documents
...
pgvector에서는 <=>가 코사인 거리 연산자다. 거리가 작을수록 유사도가 높다.
- 인덱스 구축과 검색에서 동일한 임베딩 모델 · 동일한 버전을 사용하고 있는지 확인한다.
- 벡터 DB의 metric 설정이 코사인 유사도(또는 내적)로 되어 있는지 확인한다.
top_k를 결정한 후, score_threshold로 무관한 결과를 제외하는 설계를 검토한다.- 테스트 쿼리 10~20건으로, 기대하는 문서가 상위에 오는지 검색 품질을 평가한다.
- 데이터량이 늘어나면 ANN 인덱스 (HNSW 등) 구축을 검토한다.
- 검색 결과의 메타데이터 (원래 파일명, 페이지 번호 등)를 저장하여, 출처 표시에 사용할 수 있도록 한다.
패턴 1: metric의 불일치
인덱스 생성 시에는 유클리드 거리 (Euclidean Distance)를 사용하고, 검색 시에는 코사인 유사도를 사용하는 등 설정이 어긋나는 경우.
→ 대책: 인덱스 생성 시의 metric을 문서화하여 검색 코드와 일치시킨다.
패턴 2: 임계값 없이 top_k의 결과를 모두 LLM에 전달하는 경우
유사도 0.3의 무관한 청크 (Chunk)까지 컨텍스트에 포함되어 답변 품질이 떨어진다.
→ 대책: 코사인 유사도 0.7 이상(기준)만 채택하고, 모든 결과가 이를 밑돌 경우 "관련 정보 없음"이라고 반환한다.
패턴 3: top_k가 너무 작아서 리랭킹 전에 정답이 탈락하는 경우
ANN의 근사 오차로 인해, 실제로는 관련 있는 청크가 top_3에 들어가지 못한다.
→ 대책: 우선 top_k=20 정도로 가져온 뒤, 크로스 엔코더 (Cross-Encoder) 등으로 리랭킹하여 상위 5건으로 압축한다.
패턴 4: 임베딩 모델과 DB의 차원 수 불일치
1536차원의 벡터를 768차원용 인덱스에 넣으려 하여 에러가 발생한다.
→ 대책: 모델의 dimensions 파라미터와 DB 스키마를 배포 전에 검증한다.
- 벡터 검색은 임베딩 벡터 공간에서 쿼리에 가까운 문서를 찾는 방식이다.
- 코사인 유사도는 "벡터의 각도"로 의미적 유사성을 측정하며, 텍스트 검색에서 가장 일반적인 지표다.
- 소규모라면 전수 조사, 대규모라면 ANN (HNSW 등)으로 가속화한다.
- 모델의 일치, metric의 일치, 임계값 설계가 검색 품질의 전제 조건이 된다.
다음 단계로, 10건 정도의 짧은 문장을 벡터화하여 코사인 유사도 점수를 실제로 출력해 보면 임계값 설계의 감을 잡을 수 있다.
- Pinecone — What is Vector Search?
- Weaviate — Vector similarity search
- pgvector — GitHub
- Qdrant — Similarity Metrics
- Faiss — Facebook AI Similarity Search
- OpenAI Embeddings Guide
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기