本文へスキップ
BecomeCoder

RAGコース · 第2章 文書を準備する ― チャンク分割 · レッスン7

オーバーラップ付きチャンク ― 境界の断絶を防ぐ

ブラウザで完結

導入

固定長チャンクには、境界をまたぐ情報が分断されるという弱点がありました。隣り合うチャンクどうしを少しだけ重ねて切ると、境界のせいで意味が途切れるのを防げます。この重なりを**オーバーラップ(overlap、のりしろ)**と呼びます。

説明

def chunk_overlap(text, size, overlap):
    step = size - overlap
    return [text[i:i+size] for i in range(0, len(text), step)]

text = "Retrieval augmented generation splits documents into chunks for search."
chunks = chunk_overlap(text, 20, 5)
print("Number of chunks:", len(chunks))
for i, c in enumerate(chunks):
    print(f"[{i}] {c!r}")

chunk_fixed との違いは1つだけです。先頭位置を進める幅を size ではなく step = size - overlap にしています。たとえば size=20, overlap=5 なら、次のチャンクの先頭は15文字先から始まる。つまり直前のチャンクの末尾5文字を、次のチャンクの先頭にもう一度含めているわけです。境界をまたぐ単語や文が、少なくともどちらか片方のチャンクには丸ごと収まりやすくなります。

トレードオフもあります。overlap を大きくするほど、チャンク同士の重複が増えてチャンクの総数が増え、索引のサイズや検索・保存のコストが上がります。その代わり、境界での情報の取りこぼしは減ります。逆に overlap=0 なら step = size となり、これは前のレッスンの固定長チャンクと完全に同じ動きになります。

やってみよう

overlap0510 と変えて chunk_overlap(text, 20, overlap) を呼び、チャンク数がどう増えるか比べてみましょう。

演習

chunk_overlap(text, 20, 0) の結果が、レッスン6の chunk_fixed(text, 20) の結果と完全に一致することを、== を使って確認し、print で表示してください(chunk_fixed 関数も自分で定義してから比べてください)。

ヒント1を見る

2つの関数をどちらも定義してから、chunk_overlap(text, 20, 0) == chunk_fixed(text, 20)print します。

ヒント2を見る

overlap=0 のとき step = size - 0 = size になるので、chunk_overlapchunk_fixed と同じ計算になります。

実際に動かしてみよう

下のエディタにPythonを書いて「実行」を押すと、scikit-learn(TF-IDF)とnumpyで本物の「検索」をその場で動かせます。RAGの検索フェーズ――文書のチャンク分割・ベクトル化・類似度計算・並べ替え――が実際に動きます。scikit-learn を使う回は初回の読み込みに数十秒かかることがあります。検索デモのサンプル文書は英語です(TF-IDFの既定トークナイザが日本語を分割できないため。日本語検索の対処は読み物で解説します)。LLMの生成や本物の埋め込みAPIは、APIキーが要るため読み物の回でコードを示します。

Python — ライブラリ付きで実行(Pyodide)

numpy / pandas / matplotlib が使える本物のPython(Pyodide)を読み込みます。初回のみ読み込みに少し時間がかかります(以降はブラウザにキャッシュされます)。
スクロールして表示された時点でも自動で読み込まれます。