EmbeddingBasedDocumentSplitter

EmbeddingBasedDocumentSplitter

연속된 문장 그룹 사이의 코사인 거리를 사용한 임베딩 유사도에 따라 문서를 분할하는 컴포넌트예요.

출처: 문서

본문

  • 파이프라인에서의 일반적인 위치: 인덱싱 파이프라인에서 Converters와 DocumentCleaner 뒤에 사용해요.
  • 필수 실행 변수: documents(임베딩 유사도에 따라 각각 더 작은 문서로 분할할 문서 리스트)
  • 출력 변수: documents(문서 리스트)

개요 (Overview)

이 컴포넌트는 연속된 문장 그룹 사이의 코사인 거리를 사용한 임베딩 유사도에 따라 문서를 분할해요.

먼저 텍스트를 문장으로 나누고, 선택적으로 그룹으로 묶은 뒤 각 그룹의 임베딩을 계산해요. 그런 다음 연속된 임베딩 사이의 코사인 거리로 분할 지점을 결정해요. 지정된 백분위수(percentile)를 초과하는 거리는 분할 지점으로 간주돼요. 이 컴포넌트는 원본 문서의 폼 피드 문자(\f)를 기반으로 페이지 번호도 추적해요.

이 컴포넌트는 Greg Kamradt의 "5 Levels of Text Splitting"에서 영감을 받았어요.

사용법 (Usage)

단독 사용 (On its own)

이 페이지의 예시는 sentence-transformers-haystack 패키지의 Sentence Transformers 임베더를 사용해요. 예시를 실행하려면 설치하세요.

pip install sentence-transformers-haystack
from haystack import Document
from haystack_integrations.components.embedders.sentence_transformers import (
    SentenceTransformersDocumentEmbedder,
)
from haystack.components.preprocessors import EmbeddingBasedDocumentSplitter

# Create a document with content that has a clear topic shift
doc = Document(
    content="This is a first sentence. This is a second sentence. This is a third sentence. "
    "Completely different topic. The same completely different topic.",
)

# Initialize the embedder to calculate semantic similarities
embedder = SentenceTransformersDocumentEmbedder()

# Configure the splitter with parameters that control splitting behavior
splitter = EmbeddingBasedDocumentSplitter(
    document_embedder=embedder,
    sentences_per_group=2,  # Group 2 sentences before calculating embeddings
    percentile=0.95,  # Split when cosine distance exceeds 95th percentile
    min_length=50,  # Merge splits shorter than 50 characters
    max_length=1000,  # Further split chunks longer than 1000 characters
)
result = splitter.run(documents=[doc])

# The result contains a list of Document objects, each representing a semantic chunk
# Each split document includes metadata: source_id, split_id, and page_number
print(f"Original document split into {len(result['documents'])} chunks")
for i, split_doc in enumerate(result["documents"]):
    print(f"Chunk {i}: {split_doc.content[:50]}...")

파이프라인에서 사용 (In a pipeline)

from pathlib import Path

from haystack import Document
from haystack import Pipeline
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.converters.txt import TextFileToDocument
from haystack.components.preprocessors import DocumentCleaner
from haystack.components.preprocessors import EmbeddingBasedDocumentSplitter
from haystack.components.writers import DocumentWriter
from haystack_integrations.components.embedders.sentence_transformers import (
    SentenceTransformersDocumentEmbedder,
)

document_store = InMemoryDocumentStore()

pipeline = Pipeline()
pipeline.add_component(instance=TextFileToDocument(), name="text_file_converter")
pipeline.add_component(instance=DocumentCleaner(), name="cleaner")
pipeline.add_component(
    instance=EmbeddingBasedDocumentSplitter(
        document_embedder=SentenceTransformersDocumentEmbedder(),
        sentences_per_group=2,
        percentile=0.95,
        min_length=50,
        max_length=1000,
    ),
    name="splitter",
)
pipeline.add_component(
    instance=DocumentWriter(document_store=document_store), name="writer"
)
pipeline.connect("text_file_converter.documents", "cleaner.documents")
pipeline.connect("cleaner.documents", "splitter.documents")
pipeline.connect("splitter.documents", "writer.documents")

path = "path/to/your/files"
files = list(Path(path).glob("*.md"))
pipeline.run({"text_file_converter": {"sources": files}})

더 알아보기 (Learn more)