自然言語処理において、テキストを最小単位に分解するプロセスは最も重要な前処理ステップです。この分解された最小単位をトークンと呼び、後続の処理に利用されます。テキストからトークンへの変換には複数のアプローチが存在し、一般的には語彙辞書を構築してマッピングを行う方法が採用されています。適切な語彙辞書をどのように構築するかについて、粒度の観点から説明します。
1. 語彙単位の分割
欧米言語では語彙単位の分割が比較的容易で、スペースなどの自然な区切りがあります。中国語では語彙分割ツール(例:jieba)の使用が必要です。以下の例をご覧ください:
中国語文:私は映画鑑賞と読書が好きです。
分割結果:私 | は | 映画 | 鑑賞 | と | 読書 | が | 好き | です
英語文:I like watching movies and reading books.
分割結果:I | like | watching | movies | and | reading | books
利点:
- 意味の明確性:語彙単位での分割により、各語彙の意味情報をより良く保持し、後続処理での正確な表現が可能になります。
- 文脈の維持:語彙レベルの分割は語間の関連性と文脈情報を保持するのに役立ち、意味解析時に文の意図をより正確に捉えることができます。
欠点:
- ロングテール効果と希少語問題:語彙辞書が巨大になり、頻出しない語彙を含むため、記憶容量と学習コストが増加します。希少語の学習データが限られているため、正確な表現獲得が困難です。
- 語彙外語問題(OOV):語彙単位モデルは語彙辞書内の語彙のみ処理可能で、辞書外語彙に対応できません。
- 形態素関係の欠如:同一語の異なる形態を捉えられず、接頭辞・接尾辞の共通性を効果的に学習できません。例えば「love」と「loves」は語彙レベルでは別個の語彙として扱われます。
2. 文字単位の分割
文字単位での分割は、テキストを個々の文字に分解し、最小単位として扱う方法です。このアプローチは英語、中国語、その他の言語すべてに適用可能で、英語は26文字のアルファベットと記号、中国語は約6000常用漢字で構成されています。
中国語文:私は映画鑑賞と読書が好きです。
分割結果:我 | 喜 | 欢 | 看 | 电 | 影 | 和 | 读 | 书 | 。
英語文:I like watching movies and reading books.
分割結果:I | 空白 | l | i | k | e | 空白 | w | a | t | c | h | i | n | g | 空白 | ...
利点:
- 一貫性のある処理:文字単位分割は多言語対応が可能で、言語ごとの特別なルールやツール設計が不要です。
- OOV問題の解決:文字単位処理は語彙辞書を必要としないため、新語や固有名詞にも対応可能です。
欠点:
- 意味情報の不明確さ:文字単位では語彙の意味情報を直接表現できず、意味解析タスクで性能が低下する可能性があります。
- 処理効率の低さ:テキストが細かい単位に分割されるため、計算コストと処理時間が増加します。
3. サブワード単位の分割
多くの場合、語彙単位(大きすぎる)でも文字単位(小さすぎる)でもなく、語彙と文字の中間的なサブワード単位が望ましいです。このようなニーズに対応するのがサブワード単位の分割です。
BERT時代にはWordPiece分割法が広く使われました。BERT、DistilBERTなどが該当します。WordPieceはサブワード単位分割の代表的手法です。
3.1 WordPiece法
WordPieceの基本概念は、単語を複数のプレフィックス記号(BERTの##など)を持つ最小単位に分解し、サブワード結合ルールによって最小単位を結合してサブワードレベルを形成することです。例えば「word」は以下のように分解されます:
w ##o ##r ##d
結合ルールによって結合を繰り返し、語彙辞書を構築します。主な手順は以下の通りです:
(1)初期語彙の計算:学習コーパスから取得するか、英語の26文字アルファベットと各種記号、中国語の常用文字などを初期語彙とします。
(2)結合スコアの計算:学習コーパス中の複数サブワード単位に対して結合ルールによるスコアを計算します。
(3)最高スコアのサブワードペア結合:最も高いスコアを持つサブワードペアを選択し、新しいサブワード単位として結合して語彙辞書を更新します。
(4)結合ステップの繰り返し:ステップ(2)と(3)を反復し、所定の語彙サイズ、結合回数、または有意義な結合がなくなるまで続けます。
(5)分割処理:最終的に得られた語彙辞書を使ってテキストを分割します。
例えば以下の学習コーパスのサンプル(カッコ内は出現頻度)があるとします:
("cat", 8), ("dog", 6), ("cats", 4), ("dogs", 7), ("hat", 9)
これをプレフィックス形式に分解すると:
("c" "##a" "##t", 8), ("d" "##o" "##g", 6), ("c" "##a" "##t" "##s", 4),
("d" "##o" "##g" "##s", 7), ("h" "##a" "##t", 9)
したがって初期語彙は以下のようになります:
["c", "d", "h", "##a", "##g", "##s", "##t", "##o"]
次に結合スコアを計算します(相互情報量に基づく)。
スコア = ペア候補の頻度 / (最初の要素の頻度 × 2番目の要素の頻度)
上記例ではペア("##a", "##t")の出現頻度は21回ですが、"##a"は21回、"##t"は21回出現するため、このペアのスコアは21/(21×21)=1/21です。同様にペア("##o", "##g")のスコアは13/(13×13)=1/13となり、最初に結合されるのは("##o", "##g")→("##og")です。このとき語彙と分解後の頻度は以下のようになります:
語彙:["c", "d", "h", "##a", "##g", "##s", "##t", "##o", "##og"]
コーパス:("c" "##a" "##t", 8), ("d" "##og", 6), ("c" "##a" "##t" "##s", 4),
("d" "##og" "##s", 7), ("h" "##a" "##t", 9)
この操作を繰り返し、目的の語彙サイズに達するまで続けます。
語彙:["c", "d", "h", "##a", "##g", "##s", "##t", "##o", "##og", "ca", "cat"]
コーパス:("cat", 8), ("d" "##og", 6), ("cat" "##s", 4), ("d" "##og" "##s", 7),
("ha" "##t", 9)
通常、最終的に語彙に特殊トークンやアルファベット、記号などを追加します:
complete_vocab = vocab + ["[PAD]", "[UNK]", "[CLS]", "[SEP]", "[MASK]"] + additional_chars
**大規模言語モデル時代には、Byte-Pair Encoding(BPE)とByte-level BPE(BBPE)が最も一般的な分割方法です。**BPEは当初テキスト圧縮アルゴリズムでしたが、2015年にNLP分割に導入され、GPT、RoBERTaなどのモデルで採用されました。BBPEは2019年にBPEベースでバイトレベルの分割方法として提案されました。現在、GPT2、BLOOM、Llama、Falconなどがこの方法を採用しています。
3.2 Byte-Pair Encoding(BPE)
BPEの基本概念は、WordPieceのスコア計算ではなく、出現頻度が最も高いサブワードペアを段階的に結合して語彙辞書を構築することです。主要な手順は以下の通り:
(1)初期語彙の計算:学習コーパスから取得するか、アルファベットと記号などを初期語彙とします。
(2)頻度統計の構築:テキスト中のすべてのサブワードペア(連続する2つのサブワード)の出現頻度を統計します。
(3)最高頻度のサブワードペア結合:最も頻繁に出現するサブワードペアを結合し、新しいサブワード単位として語彙辞書を更新します。
(4)結合ステップの繰り返し:ステップ(2)と(3)を反復し、所定の語彙サイズ、結合回数、または有意義な結合がなくなるまで続けます。
(5)分割処理:最終的な語彙辞書を使ってテキストを分割します。
理論上、語彙サイズが制限されている場合、BPEは依然としてOOV問題を引き起こす可能性がありますが、BBPEは理論的にはこの問題が発生しません。
3.3 Byte-level BPE(BBPE)
**Unicode:**Unicodeは地球上のほぼすべての書記体系と文字を網羅することを目指した文字セットです。各文字に一意のコードポイントを割り当てて識別します。Unicodeはコンピュータ内部での具体的な表現方法には関与せず、文字からコードポイントへのマッピングを提供します。Unicodeの登場により、文字セットの断片化問題が解決され、異なる言語と文字が共通基準の下で共存できるようになりました。
**UTF-8:**UTF-8は可変長の文字エンコーディング方式で、Unicodeのコードポイントをバイト列に変換します。重要な特徴はASCIIとの後方互換性で、標準的なASCII文字はUTF-8でも同じバイト表現を使用します。UTF-8では文字の表現長は1〜4バイトで、異なる範囲のUnicodeコードポイントは異なる長さのバイト列で表現されます。
例えば、英字"A"のUnicodeコードポイントはU+0041で、UTF-8では0x41(ASCIIと同じ)、中国語の"你"のコードポイントはU+4F60で、UTF-8では0xE4 0xBD 0xA0の3バイト列になります。つまり:
Unicodeは文字セットで、各文字に一意のコードポイントを割り当てます。 UTF-8はUnicodeに基づく文字エンコーディング方式で、コンピュータでの保存と伝送に使用されます。
コンピュータがデータを保存・処理する際、バイトが最小単位です。1バイトは8ビットのバイナリで、各ビットは0または1であり、異なる配置で異なるデータを表現できます。したがって、1バイトで表現可能な範囲は256です。
以上より、BBPEとBPEの違いは:BPEは文字レベルの最小単位であるのに対し、BBPEはバイトレベルです。UTF-8エンコーディングによる256のバイト範囲で、理論上は世界中のすべての文字を表現可能です。実装手順はBPEと同様で、実装粒度が異なるだけです。
(1)初期語彙の計算:学習コーパスから取得するか、アルファベットと記号などを初期語彙とします。
(2)頻度統計の構築:テキスト中のすべてのサブワードペアの出現確率を統計します。
(3)最高頻度のサブワードペア結合:最も頻繁に出現するサブワードペアを結合し、語彙辞書を更新します。
(4)結合ステップの繰り返し:所定の語彙サイズになるまで繰り返します。
(5)分割処理:最終語彙辞書を使ってテキストを分割します。