-
[Faiss] 파이스를 이용한 문서 검색 시스템 만들기Python/자연어처리 2024. 6. 28. 12:57반응형
Faiss를 이용한 문서 검색 시스템 만들기
Faiss(Facebook AI Similarity Search)란 데이터의 유사도 검색 및 벡터 클러스터링을 위한 라이브러리라고 합니다. 간단히 말해, 자연어 유사도를 기반으로 문서 검색을 구현할 수 있다는 말이지요. 유사도 검색이라고 하면, 예전에도 이와 같은 기능을 구현하는 라이브러리가 없었던건 아니지만, 파이스를 이용할 경우 성능이 제법 좋고, 옵션을 자유자재로 설정할 수 있기 때문에 문서 검색 시스템을 구현할 때 이만한 선택이 없어 보입니다.
프로그램 구성
이번에는 파이썬(Python)을 이용한 문서 검색 시스템을 만들어 보겠습니다, 구현 방법은 간단한데요, 원하는 문서를 읽은 뒤, 적당한 크기로 자르고 임베딩을 한 다음 Faiss 데이터베이스를 만들어 줍니다. 다음에는 자연어를 이용해 해당 DB를 쿼리하면 끝이지요.
이 프로그램을 만들기 위해서 파이썬은 기본이고, 🦜️🔗랭체인(Langchain) 커뮤니티와 파이스를 설치해 주셔야 합니다. 모두 pip 패키지 관리자를 이용해 설치할 수 있으며, 내 컴퓨터의 GPU 상태에 따라
faiss-cpu
또는faiss-gpu
중 하나를 설치해 주시면 됩니다.검색용 문서
이번 파이썬 문서 검색 시스템에서 검색 대상으로 삼을 문서는 mdn web docs에서 제공하는 HTML 기본 한국어 문서입니다. mdn 깃허브에 방문하면 해당 문서를 마크다운 파일로 다운로드할 수 있는데, 저는 이 파일에서 별도 편집은 거치지 않고 그대로 이용했습니다.
이제, 이 문서를 300자 단위로 자르고, 임베딩을 통해 데이터를 벡터화한 다음 이를 Faiss 데이터베이스로 만드는 작업입니다. 아래 코드를 참고해 주세요.
# Import Package from langchain_community.document_loaders import TextLoader from langchain_community.vectorstores import FAISS from langchain.embeddings import HuggingFaceBgeEmbeddings from langchain_text_splitters import CharacterTextSplitter from IPython.display import display_markdown embeddings = HuggingFaceBgeEmbeddings()
# Load Data documents = TextLoader("./html_basics.md", encoding='utf8').load() # Text Split text_splitter = CharacterTextSplitter(chunk_size=300, chunk_overlap=0) docs = text_splitter.split_documents(documents) # Create DB db = FAISS.from_documents(docs, embeddings)
Created a chunk of size 438, which is longer than the specified 300 Created a chunk of size 1402, which is longer than the specified 300 Created a chunk of size 330, which is longer than the specified 300
Faiss 데이터 쿼리
이번에는 Faiss를 이용해 만든 데이터베이스를 쿼리해 보도록 하겠습니다. 해당 작업은
FAISS.similarity_search()
함수를 이용해서 수행할 수 있는데요, 이 때 쿼리 내용은 일반적인 자연어를 그대로 입력해 주시면 됩니다. 예를 들어, 해당 문서에서 HTML의 정의를 알고 싶다면 'HTML은 무엇일까' 라는 말을 적으면 되겠지요.# Query query = "HTML은 무엇일까" answer = db.similarity_search(query)
display_markdown(answer[0].page_content, raw=True)
HTML은 콘텐츠의 구조를 정의하는 마크업 언어 입니다. HTML은 콘텐츠의 서로 다른 부분들을 씌우거나 감싸서 다른 형식으로 보이게하거나 특정한 방식으로 동작하도록 하는 일련의 {{Glossary("element", "요소")}} 로 이루어져 있습니다. {{Glossary("tag", "태그")}}로 감싸는 것으로 단어나 이미지를 다른 어딘가로 하이퍼링크하거나 단어들을 이탤릭체로 표시하고 글씨체를 크게 또는 작게 만드는 등의 일을 할 수 있습니다. 아래에 나오는 줄의 내용과 같이 예를 들 수 있습니다.
쿼리 결과 유사도 확인하기
만약, 해당 쿼리 결과의 유사도가 궁금하거나, 2순위 이하의 결과가 궁금하다면
FAISS.similarity_search_with_score()
함수를 이용해 보시는걸 추천드립니다. 해당 결과는 유사도 점수를 기반으로 상위 몇 가지의 답변을 리스트로 리턴해 주기 때문에, 원하는 답변을 선택하거나 어느정도 이상의 유사도를 걸러내기 위해 추가 작업을 할 때 도움이 됩니다.db.similarity_search_with_score(query)
[(Document(page_content='HTML은 콘텐츠의 구조를 정의하는 _마크업 언어_ 입니다. HTML은 콘텐츠의 서로 다른 부분들을 씌우거나 감싸서 다른 형식으로 보이게하거나 특정한 방식으로 동작하도록 하는 일련의 **{{Glossary("element", "요소")}}** 로 이루어져 있습니다. {{Glossary("tag", "태그")}}로 감싸는 것으로 단어나 이미지를 다른 어딘가로 하이퍼링크하거나 단어들을 이탤릭체로 표시하고 글씨체를 크게 또는 작게 만드는 등의 일을 할 수 있습니다. 아래에 나오는 줄의 내용과 같이 예를 들 수 있습니다.', metadata={'source': './html_basics.md'}), 0.16946973), (Document(page_content='여기서 우리는 HTML 맛보기를 하였습니다. 더 알아보기 위해, [HTML 배우기](/ko/docs/Learn/HTML) 페이지로 가보세요.\n\n{{PreviousMenuNext("Learn/Getting_started_with_the_web/Dealing_with_files", "Learn/Getting_started_with_the_web/CSS_basics", "Learn/Getting_started_with_the_web")}}', metadata={'source': './html_basics.md'}), 0.1735438), (Document(page_content='많은 웹의 내용은 목록이기 때문에, HTML은 이것을 위한 특별한 요소를 가지고 있습니다. 목록을 나타내는 것은 항상 최소 두 개의 요소로 구성됩니다. 가장 일반적인 목록의 종류는 순서가 있는 것과 순서 없는 것이 있습니다.', metadata={'source': './html_basics.md'}), 0.17826173), (Document(page_content='### 문단\n\n위에서 설명했듯이, {{htmlelement("p")}} 요소는 문자의 문단을 포함하기 위한 것입니다. 일반적인 문자 내용을 나타낼 때 많이 사용하게 될 것입니다.\n\n```html\n<p>This is a single paragraph</p>\n```', metadata={'source': './html_basics.md'}), 0.17929386)]
반응형'Python > 자연어처리' 카테고리의 다른 글
[customized KoNLPy] 한국어 사용자 지정 품사 태깅 및 N-gram 분석하기 (0) 2024.09.23 [KoNLPy] 파이썬에서 한국어 토큰화 하는 방법 알아보기 (1) 2024.09.20 [KoNLPy] No JVM shared library file found 문제 해결하기 (1) 2024.09.19