トークナイザ入門 — 文章をコンピュータが『かみ砕く』最初のステップ
2025-04-28
🔍 トークナイザとは?
一言でいうと
人間にとっての「単語の区切り」を、コンピュータが理解できる 数字の並び に変換するプログラム。
人間にとっての「単語の区切り」を、コンピュータが理解できる 数字の並び に変換するプログラム。
📝 入力
I love sushi 🍣!
→
🔢 出力
[73, 602, 18934, 195, 0]
📝 入力
私は寿司が好きです。
→
🔢 出力
[178, 4521, 19, 421, 6]
数値は語彙(Vocabulary)の ID。モデルは数字でしか計算できないため、まず文章→ID列に変える必要がある。
"単語"だけじゃない
- 📄 文字(char)
- 📝 サブワード(sub-word)
- 📑 文(sentence)
日本語のように 空白がない言語 では "どこで切るか" が特に重要。
❓ なぜトークナイズが必要?
目的 | 説明 |
---|---|
計算しやすくする | 文字列は長さがバラバラ。固定長 or 可変長の ID 列に変えると GPU で効率的に並列計算できる |
未知語を減らす | "iPhone 17" のような新語も、サブワードなら分割&理解可 |
意味保持 | "playing" → "play + ing" のように語幹・接尾辞を保存 |
文章
→
ID 列
→
ベクトル
トークナイズは自然言語処理の"最初の一歩"。ここを押さえれば、次は埋め込み (Embedding) やモデル構築へスムーズに進めます。
🧩 トークナイズの方法いろいろ
粒度 | 例 | 長所 | 短所 |
---|---|---|---|
ホワイトスペース単位 | I / like / NLP | 実装が簡単 | 日本語× / 新語× |
単語辞書ベース | 私は / 寿司 / が / 好き | 意味を保ちやすい | 辞書外 (OOV) 発生 |
文字単位 | 私 / は / 寿 / 司 | OOV なし | 列が長くモデル肥大 |
サブワード (BPE/WordPiece/SentencePiece) |
寿/司 ##が 好き | OOV 少+列長短 | 実装がやや複雑 |
サブワードとは?
頻出の文字列を"パズルのピース"として再利用する方式。
- "スシ"は頻出だから 1 ピース
- "ピザ"は稀なので ピ + ザ に分ける
頻出の文字列を"パズルのピース"として再利用する方式。
- "スシ"は頻出だから 1 ピース
- "ピザ"は稀なので ピ + ザ に分ける
🔄 主要アルゴリズムをざっくり比較
BPE (Byte Pair Encoding)
頻出ペアを逐次で結合。語彙サイズを自在に調整。
GPT-2
RoBERTa
WordPiece
対数確率を最大化するペア結合。未知語に ## 接頭辞を付ける。
BERT
ALBERT
SentencePiece (Unigram/BPE)
文頭・文末も考慮し、空白を扱わず文字列全体で学習。
T5
Llama
多言語モデル
トークナイザ比較イラスト
BPE の分割例
寿司
が
好き
↓
頻出ペアを統合
WordPiece の分割例
寿
司
##が
好き
↓
未知語に##接頭辞
SentencePiece の分割例
寿司
が
好き
↓
空白を特別扱いしない
🔍 どれを選べばいい?
ニーズ | おすすめ |
---|---|
英語中心 & GPU 学習 | WordPiece or BPE(実装が豊富) |
日本語・多言語 & 小さなデバイス | SentencePiece(Unigram) — 空白不要・語彙圧縮 |
組み込み開発でメモリ極少 | 文字ベース(実装最小) |
リアルタイム × 高精度 | サブワード+Dropout で未知語耐性を強化 |
💻 Python で試してみよう(Hugging Face)
from transformers import AutoTokenizer
tok = AutoTokenizer.from_pretrained("cl-tohoku/bert-base-japanese-v3")
text = "私は寿司が好きです。"
ids = tok.encode(text, add_special_tokens=True)
print("ID 列:", ids)
print("トークン:", tok.convert_ids_to_tokens(ids))
🔢 出力結果
ID 列: [2, 178, 4521, 19, 421, 6, 3] トークン: ['[CLS]', '私', 'は', '寿司', 'が', '好き', 'です', '。', '[SEP]']
[CLS], [SEP] は BERT 系モデル用の特別トークン
寿司 が辞書にあるので 1 トークン。一方で珍しい地名などは分割される。
寿司 が辞書にあるので 1 トークン。一方で珍しい地名などは分割される。
❓ よくある疑問
Q1. 語彙サイズは大きいほどいいの?
大きいほど未知語が減るが メモリ・計算量が増加。実務では 2k〜50k が一般的。
Q2. 絵文字や記号は?
最近のトークナイザは絵文字も一意の ID を付与。未定義の場合はサブワード or 文字単位で分割。
Q3. 日本語の "。「" はどう処理する?
SentencePiece では記号もトークン化、WordPiece は辞書次第。文章分割(Sentence Split)とは別処理。
📝 まとめ
トークナイザの重要ポイント
トークナイザ=文章を数字に翻訳する門番
方式は 単語・文字・サブワード に大別。日本語はサブワードが主流
用途とリソースに応じて 語彙サイズとアルゴリズムを選択
Hugging Face なら 3 行で実験可能。まず動かしながら学ぼう!
文章
→
ID 列
→
ベクトル