クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

トークン化とバイトペア符号化

このレッスンのあとで: 短い文章を、バイトペアの併合でトークンに分けることができる。

60分のレッスンコマンド2件JupyterLab データサイエンスラボ:pandas、Matplotlib、scikit-learn をブラウザーで

言語モデルは文章をどう読むか

トークン化とは、言語モデルが文章をトークンという小さな部品に切る作業です。バイトペア符号化は、その部品を決めるよく使われる方法です。チャットに打った言葉も、モデルに届く前に、この方法で切られます。

部品の決め方で、入る文章の量、めずらしい語の扱い、書ける語が決まります。

このレッスンのゴール

メモ

短い文章を、バイトペアの併合でトークンに分けることができる。

キーワード

ことばいみれい
トークンモデルがひとまとまりで扱う文章の部品さかな
語彙モデルが知っているトークンの一覧
ペア隣り合う2つのトークンか な
併合ペアを1つの新しいトークンにまとめること
バイトペア符号化いちばん多いペアの併合をくり返して、トークンを作る方法
トークンIDトークンを表す番号

学生が入力するセルは、このプレビューでは空白です。

単語で切るか、文字で切るか

前に学んだ自然言語処理では、文章を単語に切りました。言語モデルには決まった語彙が要りますが、単語ではそれが難しくなります。人の名前や打ち間違いのような新しい語は、知らない語になります。

文字で切れば、この問題はなくなります。かなと漢字があれば、どんな語も書けるからです。ただ、文が長くなり、長い入力ほど計算が増えます。

例: 同じ文章を2通りに切る

切り方例の文章のトークン数語彙「たなか」を書けるか
単語53: さかな、さかなや、たかないいえ、知らない語
文字175: さ、か、な、や、たはい、た・な・か で書ける

学生が入力するセルは、このプレビューでは空白です。

2種類のトークンを数える

コード: python
text = "さかな、さかなや、たかな、さかなや、さかな"
# 日本語には空白がないので、読点で語に分けます。
words = text.split("、")

chars = []
for word in words:
    for ch in word:
        chars.append(ch)

word_vocab = []
for word in words:
    if word not in word_vocab:
        word_vocab.append(word)

char_vocab = []
for ch in chars:
    if ch not in char_vocab:
        char_vocab.append(ch)

print("単語のトークン:", len(words), "語彙:", word_vocab)
print("文字のトークン:", len(chars), "語彙:", char_vocab)
print("たなか は知っている語ですか:", "たなか" in word_vocab)
# text の最後に「、たなか」を足して、実行してください。
# どちらの語彙が、いくつ増えますか。

いちばん多いペアを併合する

バイトペア符号化は、単語と文字の間にあります。日本語には空白がないので、まず1文字ずつに分けます。ここでは読点で語を区切り、1つの語の中で隣り合うペアを数えます。いちばん多いペアを1つのトークンにまとめ、語彙に加えます。

それから数えなおして、また併合します。よく出る語は短くなり、めずらしい語は小さな部品のまま残るので、知らない語は出ません。

例: ペアを数える

ペア出てくる語数
か なさかな、さかなや、たかな、さかなや、さかな5
さ かさかな、さかなや、さかなや、さかな4
な やさかなや、さかなや2
た かたかな1

学生が入力するセルは、このプレビューでは空白です。

ラボでペアを数える

コマンド
docker exec jupyter python3 -c "from collections import Counter; words = [w.split('-') for w in 'sa-ka-na sa-ka-na-ya ta-ka-na sa-ka-na-ya sa-ka-na'.split()]; print(Counter(t[i] + ' ' + t[i + 1] for t in words for i in range(len(t) - 1)).most_common(3))"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

例: 3回の併合

併合新しいトークンさかなさかなやたかな
始めなしさ か なさ か な やた か な
1: か な (5)かなさ かなさ かな やた かな
2: さ かな (4)さかなさかなさかな やた かな
3: さかな や (2)さかなやさかなさかなやた かな

学生が入力するセルは、このプレビューでは空白です。

1回目の併合をする

コード: python
text = "さかな、さかなや、たかな、さかなや、さかな"
words = []
for word in text.split("、"):
    words.append(list(word))

left = "か"
right = "な"
merged = []
for tokens in words:
    out = []
    i = 0
    while i < len(tokens):
        # ペアを1つのトークンにまとめ、2つ分先へ進みます。
        if i + 1 < len(tokens) and tokens[i] == left and tokens[i + 1] == right:
            out.append(left + right)
            i = i + 2
        else:
            out.append(tokens[i])
            i = i + 1
    merged.append(out)
print(merged)
# ペアを "さ" と "か" に変えて、実行してください。
# 「たかな」のトークンは、いくつになりますか。

よくある間違い

注意

トークンは1つの単語のことだと考えがちです。バイトペア符号化では、よく出る語は1トークンですが、めずらしい語は何トークンにもなります。モデルにどれだけ入るかを考えるときは、単語ではなくトークンを数えてください。

トークンは番号になる

モデルは文字を見ません。語彙のトークンにはそれぞれトークンIDがあり、一覧の中の位置を表します。3回の併合のあと、語彙は さ、か、な、や、た、かな、さかな、さかなや で、0から7の番号が付きます。

「さかなや、たかな、さかな」は さかなや、た、かな、さかな になり、IDは 7、4、5、6 です。10文字が4トークンになりました。

トークンをIDに変える

コマンド
docker exec jupyter python3 -c "vocab = ['sa', 'ka', 'na', 'ya', 'ta', 'kana', 'sakana', 'sakanaya']; print([vocab.index(t) for t in ['sakanaya', 'ta', 'kana', 'sakana']])"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

このラボとソースについて: JupyterLab データサイエンスラボ:pandas、Matplotlib、scikit-learn をブラウザーで

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。