Investment-Assistant

문서 검색 성능 평가: BM25와 FAISS를 활용한 Hybrid Search 분석 [12]

HeyTeddy 2024. 11. 26. 22:51
반응형

문서 검색 시스템에서 성능 평가(Evaluation)는 매우 중요한 작업입니다. 오늘은 BM25FAISS 알고리즘을 결합한 Hybrid Search를 구현하고, 이를 평가하는 과정을 소개합니다. 이 글에서는 Python 코드 예제와 함께 정확도(Precision), 재현율(Recall), F1 점수를 계산하여 검색 성능을 분석하는 방법을 다룹니다.

문서 검색 시스템 구성

우리는 두 가지 검색 알고리즘을 결합한 Hybrid Search를 사용합니다.

  • BM25: 단어 기반 검색 알고리즘으로, 검색어와 문서의 단어 겹침 정도를 바탕으로 검색.
  • FAISS: OpenAI API의 Embedding을 활용하여 의미 기반 검색을 수행.
from langchain_community.retrievers import BM25Retriever
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain.retrievers import EnsembleRetriever
import config
from sklearn.metrics import precision_score, recall_score, f1_score

# 문서 데이터
docs = [
    "우리나라는 2022년에 코로나가 유행했다.",
    "우리나라 2024년 GDP 전망은 3.0%이다.",
    "우리나라는 2022년 국낸총생산 중 연구개발 예산은 약 5%이다."
]

# 정답 데이터
gold_data = {
    "코로나가 유행한 연도": [0],
    "2022년 GDP 대비 R&D 예산": [2],
    "2024년의 국내총생산 전망": [1],
}

# BM25 설정
bm25_retriever = BM25Retriever.from_texts(
    docs, metadatas=[{"source": 1}] * len(docs)
)
bm25_retriever.k = 1

# FAISS 설정
embedding = OpenAIEmbeddings(api_key=config.OPENAI_API_KEY)
faiss_vectorstore = FAISS.from_texts(
    docs, embedding, metadatas=[{"source": i} for i in range(len(docs))]
)
faiss_retriever = faiss_vectorstore.as_retriever(search_kwargs={"k": 1})

# Hybrid Search 설정
ensemble_retriever = EnsembleRetriever(
    retrievers=[bm25_retriever, faiss_retriever],
    weights=[0.2, 0.8]
)

# 검색 실행
retrieved_docs = {query: ensemble_retriever.invoke(query) for query in gold_data}

# 평가 함수
def evaluate_search(retrieved_docs, gold_standard, documents):
    precisions = []
    recalls = []
    f1s = []

    for query in gold_standard:
        retrieved = [doc.metadata['source'] for doc in retrieved_docs[query]]
        gold = gold_standard[query]

        y_true = [1 if i in gold else 0 for i in range(len(documents))]
        y_pred = [1 if i in retrieved else 0 for i in range(len(documents))]

        # 정확도, 재현율, F1 점수
        precision = precision_score(y_true, y_pred)
        recall = recall_score(y_true, y_pred)
        f1 = f1_score(y_true, y_pred)

        precisions.append(precision)
        recalls.append(recall)
        f1s.append(f1)

    avg_precision = sum(precisions) / len(gold_standard)
    avg_recall = sum(recalls) / len(gold_standard)
    avg_f1 = sum(f1s) / len(gold_standard)
    
    return avg_precision, avg_recall, avg_f1

# 평가 실행
avg_precision, avg_recall, avg_f1 = evaluate_search(retrieved_docs, gold_data, docs)

print(avg_precision)
print(avg_recall)
print(avg_f1)

결론

이 코드는 검색 알고리즘의 성능을 정량적으로 평가하는 방법을 보여줍니다. BM25와 FAISS의 조합을 통해 문서 검색 결과를 향상시킬 수 있으며, Precision, Recall, F1 Score를 계산하여 성능을 검증할 수 있습니다. 검색 시스템 개발자는 이 과정을 통해 검색기의 효율성을 지속적으로 개선할 수 있습니다.

반응형