langchain / / 2024. 6. 27. 07:25

[langchain] 시간 가중 벡터저장소 검색기 (Time-weighted vector store retriever)

시간 가중 벡터 저장소 검색기는 의미론적 유사성과 시간에 따른 가중치 적용을 조합하여 사용한다.

스코어링 알고리즘은 아래와 같다.

semantic_similarity + (1.0 - decay_rate) ^ hours_passed

특히, hours_passed는 객체가 마지막으로 액세스된 이후 경과한 시간을 나타내며, 생성된 이후의 시간이 아니다. 이는 자주 액세스되는 객체가 "신선한" 상태로 유지됨을 의미한다.

from datetime import datetime, timedelta

import faiss
from langchain.retrievers import TimeWeightedVectorStoreRetriever
from langchain_community.docstore import InMemoryDocstore
from langchain_community.vectorstores import FAISS
from langchain_core.documents import Document
from langchain_openai import OpenAIEmbeddings

# 임베딩 모델 정의
embeddings_model = OpenAIEmbeddings()
# 벡터 스토어 초기화
embedding_size = 1536
index = faiss.IndexFlatL2(embedding_size)
vectorstore = FAISS(embeddings_model, index, InMemoryDocstore({}), {})

낮은 감쇠율

decay_rate가 낮다는 것은 더 중요한 문서라는 것을 나타낸다. 그래서 거의 0에 가까운 숫자로 설정한다.

# 임베딩 모델 정의
embeddings = OpenAIEmbeddings()
# 벡터 스토어 초기화
embedding_size = 1536
index = faiss.IndexFlatL2(embedding_size)
vectorstore = FAISS(embeddings, index, InMemoryDocstore({}), {})
retriever = TimeWeightedVectorStoreRetriever(
    vectorstore=vectorstore, decay_rate=0.0000000000000000000000001, k=1
)

yesterday = datetime.now() - timedelta(days=1)
retriever.add_documents(
    # "hello world" 내용의 문서를 추가하고, 메타데이터에 어제 날짜를 설정합니다.
    [Document(page_content="hello world", metadata={"last_accessed_at": yesterday})]
)
# "hello foo" 내용의 문서를 추가합니다.
retriever.add_documents([Document(page_content="hello foo")])

# Hello World는 가장 중요하기 때문에 먼저 반환되며, 감쇠율이 0에 가까워 여전히 최근이기 때문입니다.
docs = retriever.get_relevant_documents("hello world")
print("====== low_rate retriever result ========")
for i, doc in enumerate(docs):
    print(doc.metadata)
    print(f"[문서 {i}] {doc.page_content.replace('\n', ' ')}")

높은 감쇠율

높은 감쇠율 (예: 9의 여러 자릿수)에서는 최근성 점수가 빠르게 0으로 수렴된다. 만일 모든 객체에 1로 설정하면 최근성이 0이 되어, 이는 벡터 조회와 동일하게 된다.

# 임베딩 모델 정의
embeddings_model = OpenAIEmbeddings()
# 벡터 스토어 초기화
embedding_size = 1536
index = faiss.IndexFlatL2(embedding_size)
vectorstore = FAISS(embeddings_model, index, InMemoryDocstore({}), {})
retriever = TimeWeightedVectorStoreRetriever(
    vectorstore=vectorstore, decay_rate=0.9999999, k=1
)

yesterday = datetime.now() - timedelta(days=1)
retriever.add_documents(
    # "hello world" 내용의 문서를 추가하고, 메타데이터에 어제 날짜를 설정합니다.
    [Document(page_content="hello world", metadata={"last_accessed_at": yesterday})]
)
# "hello foo" 내용의 문서를 추가합니다.
retriever.add_documents([Document(page_content="hello world")])

docs = retriever.get_relevant_documents("hello foo")
print("====== high_rate retriever result ========")
for i, doc in enumerate(docs):
    print(doc.metadata)
    print(f"[문서 {i}] {doc.page_content.replace('\n', ' ')}")

감쇠율(decay_rate) 정리

  • decay_rate 를 0.000001 로 매우 작게 설정한 경우: 감쇠율(즉, 정보를 망각하는 비율)이 매우 낮기 때문에 정보를 거의 잊지 않습니다. 따라서, 최신 정보이든 오래된 정보든 시간 가중치 차이가 거의 없습니다. 이럴때는 유사도에 더 높은 점수를 주게 됩니다.
  • decay_rate 를 0.999 로 1에 가깝게 설정한 경우: 감쇠율(즉, 정보를 망각하는 비율)이 매우 높습니다. 따라서, 과거의 정보는 거의다 잊어버립니다. 따라서, 이러한 경우는 최신 정보에 더 높은 점수를 주게 됩니다.

참고

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유