Tech

[RAG] VectorDB Embedding

aeightchill 2025. 5. 19. 21:47
728x90

 

 

사용자가 원하는 정보

  1. 사용자의 질문과 관련있는 데이터
    • 관련이 있다는 것을 판단하는 기준은 vector가 된다.
    • vector : 단어 또는 문장의 유사도를 파악해서 관련성을 측정한다.
  2. Vector를 생성하는 방법
    • Embedding 모델을 활용해서 vector 생성한다.
    • 문장에서 비슷한 단어가 자주 붙어있는 것을 학습한다.
      • 예를 들어, A : "왕은 왕자의 아버지다." / B : "여왕은 왕자의 어머니다."
      • "왕자의" 라는 단어 앞에 등장하는 "왕"과 "여왕"은 유사할 가능성이 높다.

 


 

Vector Databse

  1. Embedding 모델을 활용해 생성된 vector를 저장한다.
    • vector와 함꼐 metadata도 저장된다.
      • metadata : 문서의 이름, 페이지 번호 등의 데이터
    • hallucination을 대비하기 위해서 어떤 문서에서 가져왔는지 출처를 같이 보여주는 것이 중요하다.
  2. vector를 대상으로 유사도 검색을 한다.
    • 사용자의 질문과 가장 비슷한 문서를 가져온다. (Retrieval)
      • 소득세법을 RAG의 knowledge base로 활용한다.
      • 문서 전체를 활용하게 되면 속도도 느리고, 토큰수 초과로 답변 생성이 안될 수 있다.
      • 문서를 chunking하는 작업이 매우 중요하다.
    • 가져온 문서를 prompt를 통해서 LLM에 제공한다. (Augmented)
    • LLM은 prompt를 활용해서 답변을 생성한다. (Generation)

 


 

벡터 임베딩(Vector Embedding)

문자, 단어, 문장, 이미지 등 다양한 데이터를 고정된 크기의 수치 벡터(vector)로 변환하는 기법

머신러닝과 딥러닝 모델은 숫자 데이터를 입력으로 받아야 하므로, 텍스트나 범주형 데이터처럼 원래 숫자가 아닌 데이터를 수치화할 필요가 있다. → 이 과정에서 임베딩이 사용

 

왜 사용할까?

  • 의미 보존 : 같은 의미를 가진 데이터는 비슷한 벡터로 표현되도록 함.
  • 차원 축소 : 원-핫 인코딩처럼 희소한 벡터보다 효율적.
  • 유사도 계산 : 벡터 간 코사인 유사도, 거리 계산 등을 통해 의미적 관계 파악이 가능함.

 


 

예제

 

1. 패키지 설치

%pip install -q python-dotenv langchain-openai

 

 

2. 환경변수 불러오기

#  .env 파일에 OPENAI_API_KEY 등록

import os
from dotenv import load_dotenv
load_dotenv()

 

 

3. openai client 불러오기

from openai import OpenAI
client = OpenAI()

 

 

4. numpy를 사용해서 코사인 유사도 계산

1 : 방향이 같음 (완전 유사)

0 : 직각 (무관)​                   

-1 : 방향이 반대                    

import numpy as np
def cosine_similarity(vec1, vec2):
    """
    Compute the cosine similarity between two vectors.

    parameters:
    vec1 (numpy array) : First vector
    vec2 (numpy array) : Second vector

    Returns:
    float : Cosine similarity between vec1 and vec2
    """
    dot_product = np.dot(vec1, vec2)
    norm_vec1 = np.linalg.norm(vec1)
    norm_vec2 = np.linalg.norm(vec2)
    
    if norm_vec1 == 0 or norm_vec2 == 0:
        return 0.0
    
    return dot_product / (norm_vec1 * norm_vec2)

 

 

5. "King" Embedding

king_embedding_response = client.embeddings.create(
    input="king",
    model="text-embedding-3-large"
)

king_vector = np.array(king_embedding_response.data[0].embedding)

 

king_vector

 

array([ 0.01040417, 0.02499519, -0.0014776 , ..., 0.00835009, 0.01049861, -0.00254005])

 

 

6. "Queen" Embedding

queen_embedding_response = client.embeddings.create(
    input="queen",
    model="text-embedding-3-large"
)

queen_vector = np.array(queen_embedding_response.data[0].embedding)

 

queen_vector

 

array([-0.01385735, 0.0008602 , -0.0167823 , ..., 0.00017693, 0.01159847, 0.00638929])

 

 

7. King Vector와 Queen Vector의 코사인 유사도 계산

similarity = cosine_similarity(king_vector, queen_vector)
print(similarity)

 

result : 0.5552268369726672

 

 

8. King과 Slave의 코사인 유사도 계산

slave_embedding_response = client.embeddings.create(
    input="slave",
    model="text-embedding-3-large"
)
slave_vector = np.array(slave_embedding_response.data[0].embedding)
similarity_king_slave = cosine_similarity(king_vector, slave_vector)
print(similarity_king_slave)

 

result : 0.2947745074537994

  • King은 Slave보다 Queen과 더 의미적으로 가깝다.

 

 

 

 

728x90