Retriever(검색기) 비교
Retriever 기법 | 장점 | 단점 | 사용 시기 |
---|---|---|---|
Similarity Search | - 간단하고 빠른 검색 가능 - 높은 유사성의 문서를 효과적으로 찾음 |
- 정밀한 검색이 어려울 수 있음 - 다중 의미를 가진 쿼리에 약함 |
- 쿼리와 관련된 문서를 빠르게 찾고자 할 때 - 단순한 유사성 기반의 검색이 필요한 경우 |
Maximum Marginal Relevance (MMR) | - 정보 다양성을 높여 중복 문서 필터링 가능 - 다양한 답변을 제공할 수 있음 |
- 계산 비용이 더 많이 듦 - 검색 속도가 느려질 수 있음 |
- 중복되지 않는 다양한 정보를 원할 때 - 여러 관점을 가진 문서를 선택하고자 할 때 |
Similarity Score Threshold | - 일정 수준 이상의 유사성만 필터링 - 특정 임계값 이상의 관련성 있는 문서만 선택 가능 |
- 임계값 설정이 까다로울 수 있음 - 임계값이 낮으면 유사하지 않은 문서가 포함될 수 있음 |
- 특정 수준 이상의 관련성 있는 문서만 필요할 때 - 정확한 문서 검색이 중요한 경우 |
Parent-Child Document Retrieval | - 문서의 계층적 관계를 고려한 검색 가능 - 부모 문서와 자식 문서 간의 관계 파악에 유리 |
- 구현이 복잡하고 계산 비용이 높음 - 특정 구조의 문서에만 적합 |
- 논문, 보고서, 기술 문서, 서적 등과 같이 계층적 구조(장-절-단락 등)의 검색시 필요 |
Dense Passage Retrieval (DPR) | - 문서의 의미를 잘 반영하는 임베딩을 통해 검색 - 비슷한 의미를 가진 문서를 효과적으로 검색 가능 |
- 임베딩 생성에 높은 계산 비용이 필요 - 매우 큰 데이터셋에서의 검색 성능이 떨어질 수 있음 |
- 의미 기반의 정교한 검색이 필요한 경우 - 동의어, 유사어가 많은 쿼리를 처리해야 할 때 |
BM25 (Okapi BM25) | - 전통적인 TF-IDF 기반의 효율적이고 효과적인 검색 - 문서의 중요도와 관련성을 잘 반영 |
- 의미 기반의 검색에는 한계가 있음 - 동의어나 유사어 처리에 약함 |
- 간단하고 효율적인 키워드 기반 검색이 필요할 때 - 문서의 빈도와 역빈도를 고려한 검색이 필요한 경우 |
간단한 코드 예시
1. Similarity Search
# Similarity Search 설정 및 사용
retriever = vectorstore.as_retriever()
# 쿼리로 문서 검색
query = "확률이란 무엇인가?"
retrieved_docs = retriever.get_relevant_documents(query)
# 결과 출력
for doc in retrieved_docs:
print(doc.page_content[:200])
2. Maximum Marginal Relevance (MMR)
# MMR 설정 및 사용
retriever = vectorstore.as_retriever(search_type="mmr", search_kwargs={'k': 5})
# 쿼리로 문서 검색
query = "확률이란 무엇인가?"
retrieved_docs = retriever.get_relevant_documents(query)
# 결과 출력
for doc in retrieved_docs:
print(doc.page_content[:200])
3. Similarity Score Threshold
# Similarity Score Threshold 설정 및 사용
retriever = vectorstore.as_retriever(search_type="similarity_score_threshold", search_kwargs={'k': 5, "score_threshold": 0.7})
# 쿼리로 문서 검색
query = "확률이란 무엇인가?"
retrieved_docs = retriever.get_relevant_documents(query)
# 결과 출력
for doc in retrieved_docs:
print(doc.page_content[:200])
4. Parent-Child Document Retrieval
# 문서를 청크로 나누기
parent_splitter = RecursiveCharacterTextSplitter(chunk_size=900)
child_splitter = RecursiveCharacterTextSplitter(chunk_size=300)
parent_chunks = parent_splitter.split_text(document_text)
# Parent-Child Document Retrieval 설정 및 사용
retriever = ParentDocumentRetriever(
vectorstore=vectorstore,
docstore=InMemoryStore(),
child_splitter=child_splitter,
parent_splitter=parent_splitter
)
# 쿼리로 문서 검색
query = "확률이란 무엇인가?"
retrieved_docs = retriever.get_relevant_documents(query)
# 결과 출력
for doc in retrieved_docs:
print(doc.page_content[:200])
5. Dense Passage Retrieval (DPR)
# DPR 설정 및 사용
retriever = DPRRetriever(vectorstore=vectorstore, embeddings=embeddings)
# 쿼리로 문서 검색
query = "확률이란 무엇인가?"
retrieved_docs = retriever.get_relevant_documents(query)
# 결과 출력
for doc in retrieved_docs:
print(doc.page_content[:200])
6. BM25 (Okapi BM25)
# BM25 설정 및 사용
retriever = BM25Retriever(vectorstore=vectorstore)
# 쿼리로 문서 검색
query = "확률이란 무엇인가?"
retrieved_docs = retriever.get_relevant_documents(query)
# 결과 출력
for doc in retrieved_docs:
print(doc.page_content[:200])
'langchain 공부' 카테고리의 다른 글
딥러닝 모델의 변화와 Transformer의 탄생(LLM 역사와 발전1) (9) | 2024.09.01 |
---|---|
RunnablePassthrough() 사용 이유 (0) | 2024.08.29 |
LLM 프로젝트를 기획할 때 겪게 되는 어려운 점들 (0) | 2024.08.12 |
langchain 퓨샷 프롬프트(prompt) (0) | 2024.08.04 |
langchain 프롬프트(prompt) 기초 (0) | 2024.08.03 |