Skip to content

04 벡터 검색 실습

컴퓨터는 텍스트를 직접 이해하지 못합니다.
임베딩이란 텍스트(문자)를 컴퓨터가 계산할 수 있는 **숫자 벡터(배열)**로 변환하는 과정입니다.

"오늘 날씨가 좋다" → [0.12, -0.87, 0.44, ... , 0.03] (768개 숫자)
"The weather is nice" → [0.11, -0.85, 0.46, ... , 0.02] (768개 숫자)

💡 핵심: 의미가 비슷한 문장은 벡터 공간에서 가까운 위치에 놓입니다.
위 두 문장처럼 언어가 달라도 의미가 같으면 비슷한 벡터가 만들어집니다.


단어 임베딩 (Word Embedding): “개별 식재료의 맛”

Section titled “단어 임베딩 (Word Embedding): “개별 식재료의 맛””
  • 개념: ‘사과’, ‘맛있다’, ‘먹다’ 등 단어 하나하나를 고유한 벡터(숫자)로 변환하는 것입니다. (예: Word2Vec)
  • 특징: 단어들 사이의 관계(사과와 바나나는 비슷하다)는 잘 알 수 있습니다.
  • 비유: 당근, 양파, 카레 가루 등 각각의 식재료가 어떤 맛을 내는지 파악하는 단계입니다.

단어에서 문장으로의 확장: “단순한 짬짜면?”

Section titled “단어에서 문장으로의 확장: “단순한 짬짜면?””

단어 임베딩을 배웠으니, 이제 “사과가 맛있다”라는 문장을 기계에 넣고 싶어집니다. 가장 단순한 응용 방법은 무엇일까요?

  • 초기 접근법 (단어 벡터의 평균): 문장에 쓰인 단어들의 임베딩 벡터 값을 그냥 더하거나 평균을 내버리는 방식입니다.
  • 치명적 한계: 이 방식은 ‘어순’과 ‘문맥’을 완전히 무시합니다.
    • 예시: “내가 너를 때렸다”와 “너가 나를 때렸다”는 단어 구성이 똑같아서 기계가 완전히 같은 문장(같은 벡터 값)으로 인식해 버립니다. 식재료를 그냥 한 냄비에 다 때려 넣고 섞어버린 셈입니다.

문장 임베딩 (Sentence Embedding): “완성된 요리의 맛”

Section titled “문장 임베딩 (Sentence Embedding): “완성된 요리의 맛””
  • 개념: 위와 같은 단어 임베딩의 한계를 극복하기 위해, 단순히 단어를 합치는 것을 넘어 문장 전체의 문맥과 어순을 고려해 하나의 압축된 벡터로 변환하는 기술입니다. (예: SBERT, 트랜스포머 기반 모델)
  • 특징: “내가 너를 때렸다”와 “너가 나를 때렸다”의 뉘앙스 차이를 완벽하게 구분하여 서로 다른 벡터 공간에 배치합니다.
  • 비유: 식재료들이 어떤 순서로, 어떻게 조리되어 최종적으로 어떤 ‘완성된 요리(카레라이스)‘의 맛과 향을 내는지 그 전체적인 느낌을 파악하는 것입니다.

📊 한눈에 보는 비교 (강의 화면용 추천)

Section titled “📊 한눈에 보는 비교 (강의 화면용 추천)”
구분단어 임베딩 (Word Embedding)문장 임베딩 (Sentence Embedding)
분석 단위개별 단어문장 또는 문단 전체
어순 파악불가능 (단어의 존재 유무만 앎)가능 (문맥과 뉘앙스를 완벽히 이해)
비유개별 식재료의 맛완성된 요리의 전체적인 맛
주요 활용연관 검색어 찾기, 단어 군집화시맨틱 검색(RAG), AI 챗봇 질문 의도 파악, 문서 요약/분류
대표 모델Word2Vec, GloVeBERT, GTE, BGE

“단어 임베딩이 식재료 하나하나의 맛을 분석하는 것이라면, 문장 임베딩은 그 재료들이 조화롭게 섞인 완성된 요리의 맛을 평가하는 것입니다. 우리가 만드는 챗봇이 ‘문맥’을 찰떡같이 알아듣는 이유는, 단순히 단어의 합을 넘어 문장 전체를 꿰뚫어 보는 이 문장 임베딩 기술 덕분입니다.”


1-3. 코사인 유사도(Cosine Similarity)

Section titled “1-3. 코사인 유사도(Cosine Similarity)”

두 벡터 간의 **방향(각도)**을 이용해 유사도를 측정합니다.
벡터의 크기(길이)에 영향받지 않아 텍스트 비교에 가장 많이 사용됩니다.

cos(θ) = (A · B) / (‖A‖ × ‖B‖)
코사인 유사도 값의미
1.0두 벡터가 완전히 같은 방향 (동일한 의미)
0.8 ~ 0.9매우 유사한 의미
0.5 ~ 0.7관련은 있으나 다른 내용
0.0 이하관련 없거나 반대 의미

방식검색 원리예시
키워드 검색단어 일치 여부”날씨”만 입력하면 “weather”는 검색 안 됨
시맨틱 검색의미 유사도”맑음”을 검색해도 “sunny”가 상위에 나옴

시맨틱 검색은 아래 3단계로 동작합니다:

① 모든 문장을 미리 임베딩 벡터로 변환 (인덱싱)
② 검색어도 임베딩 벡터로 변환
③ 검색어 벡터와 모든 문장 벡터의 코사인 유사도 계산 → 높은 순으로 반환

항목내용
이름Alibaba-NLP/gte-multilingual-base
유형Sentence Transformer (BERT 계열)
임베딩 차원768차원
최대 입력8,192 토큰
지원 언어다국어 (한국어, 영어, 중국어 등 70개 이상)
특징다국어 교차 언어 검색에 우수한 성능
from sentence_transformers import SentenceTransformer
model = SentenceTransformer(
"Alibaba-NLP/gte-multilingual-base",
trust_remote_code=True # 모델에 커스텀 Python 코드 포함 → 필수
)

⚠️ 최초 실행 시: 허깅페이스(HuggingFace) 서버에서 모델을 자동 다운로드합니다.
다운로드 후에는 로컬 캐시(~/.cache/huggingface)에 저장되어 다음 실행부터는 빠릅니다.


sentences = ["오늘 날씨가 좋다", "The weather is nice", "파이썬 프로그래밍"]
embeddings = model.encode(sentences, show_progress_bar=False)
# 결과 shape: (3, 768)
# → 3개 문장, 각각 768차원 벡터

model.encode()가 반환하는 것은 NumPy 행렬입니다.
각 행(row)이 하나의 문장에 대응하는 768차원 벡터입니다.

embeddings[0] → "오늘 날씨가 좋다" 의 벡터 (768개 숫자)
embeddings[1] → "The weather is nice" 의 벡터 (768개 숫자)
embeddings[2] → "파이썬 프로그래밍" 의 벡터 (768개 숫자)

from sklearn.metrics.pairwise import cosine_similarity
# query 한 문장을 벡터로 변환
query_vec = model.encode(["날씨가 맑고 화창해요"]) # shape: (1, 768)
# 저장된 모든 문장과 한 번에 유사도 계산
scores = cosine_similarity(query_vec, embeddings)[0]
# scores: [0.95, 0.93, 0.12] → 문장 0, 1과는 유사, 문장 2는 무관
# 정렬 후 Top-3 출력
ranked = sorted(enumerate(scores), key=lambda x: x[1], reverse=True)[:3]
for rank, (idx, score) in enumerate(ranked, 1):
print(f"{rank}위 (점수: {score:.4f}): {sentences[idx]}")

3-3. 문장 추가 시 점진적 임베딩

Section titled “3-3. 문장 추가 시 점진적 임베딩”
import numpy as np
# 새 문장 한 건만 임베딩
new_vec = model.encode(["새로운 문장"]) # shape: (1, 768)
# 기존 행렬에 새 행(row)을 추가
embeddings = np.vstack([embeddings, new_vec]) # shape: (N+1, 768)

전체를 재계산하지 않고 새 문장만 임베딩하여 이어붙이므로 효율적입니다.


앱 실행 시 10개의 사전 정의 문장이 왼쪽 테이블에 표시됩니다.

검색창에 문장을 입력하고 검색 버튼을 클릭합니다.

검색어 예시기대 결과
맑은 하늘날씨 관련 문장이 상위에 오름
sunny영어 검색어로도 한국어 문장이 검색됨
AI 학습딥러닝/머신러닝 관련 문장이 상위에 오름
카페 음료식당/카페 관련 문장이 상위에 오름

직접 문장을 작성해 추가하고, 동일 검색어로 재검색하여 새 문장이 결과에 반영되는지 확인합니다.


  1. 오늘 날씨가 화창하다The weather is sunny의 코사인 유사도는 높을까요, 낮을까요?
    → 직접 검색해서 확인해보세요. 일본어 검색도 해보세요(今日はいい天気ですね! (오늘 맑은(좋은) 날씨네요!))
  2. 완전히 다른 주제(예: 요리 레시피)를 검색했을 때 최고 점수는 얼마나 되나요? (예: 계랸찜이 먹고싶어요)
  3. 직접 만든 문장을 추가하고, 기존 문장과 얼마나 유사한지 점수로 확인해보세요.
  4. 한국어로 추가한 문장을 영어 키워드로 검색하면 나타나는지 확인해보세요.
  5. 그 외 다양한 다국어 기반 검색이 잘 되는지 확인해보세요