本文へスキップ
`Ctrl`+`K`

# 7.9.2. `TokenBigram`

## 7.9.2.1. 概要

`TokenBigram` はバイグラムベースのトークナイザーです。多くのケースでは、このトークナイザーを使うことをオススメします。

バイグラムというトークナイズ方法は、隣り合った2つの文字を1つのトークンとしてテキストをトークナイズします。例えば、 `Hello` は次のトークンにトークナイズします。

> - `He`

> - `el`

> - `ll`

> - `lo`

バイグラムというトークナイズ方法は再現性に優れています。なぜなら、2文字以上の文字のクエリーに対してはすべてのテキストを見つけることができるからです。

一般的に、1文字のクエリーではすべてのテキストを見つけることはできません。なぜなら、1つの文字のトークンが存在しないからです。しかし、Groongaでは1文字のクエリーでもすべてのテキストを見つけることができます。なぜなら、Groongaは前方一致検索によりクエリーで指定した文字で始まるトークンをすべて見つけることができるからです。例えば、Groongaは `l` というクエリーから `ll` というトークンと `lo` というトークンを見つけることができます。

バイグラムというトークナイズ方法は適合率はそれほど優れていません。なぜなら、単語の一部にクエリーが含まれていればすべてのテキストが見つかってしまうからです。例えば、 `or` で `world` が見つかります。これは非ASCIIを使う言語よりASCIIのみを使う言語で顕著です。以降の説明で触れる通り、 `TokenBigram` はこの問題を解決しています。

## 7.9.2.2. 構文

`TokenBigram` には、引数がありません。

    TokenBigram

## 7.9.2.3. 使い方

`TokenBigram` の挙動は ノーマライザー を使うかどうかで変わります。

ノーマライザーを使っていない場合は `TokenBigram` は純粋なバイグラム（最後のトークンをのぞいてすべてのトークンを2文字にする）のトークナイズ方法を使います。

実行例:

    tokenize TokenBigram "Hello World"
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     {
    #       "value": "He",
    #       "position": 0,
    #       "force_prefix": false,
    #       "force_prefix_search": false
    #     },
    #     {
    #       "value": "el",
    #       "position": 1,
    #       "force_prefix": false,
    #       "force_prefix_search": false
    #     },
    #     {
    #       "value": "ll",
    #       "position": 2,
    #       "force_prefix": false,
    #       "force_prefix_search": false
    #     },
    #     {
    #       "value": "lo",
    #       "position": 3,
    #       "force_prefix": false,
    #       "force_prefix_search": false
    #     },
    #     {
    #       "value": "o ",
    #       "position": 4,
    #       "force_prefix": false,
    #       "force_prefix_search": false
    #     },
    #     {
    #       "value": " W",
    #       "position": 5,
    #       "force_prefix": false,
    #       "force_prefix_search": false
    #     },
    #     {
    #       "value": "Wo",
    #       "position": 6,
    #       "force_prefix": false,
    #       "force_prefix_search": false
    #     },
    #     {
    #       "value": "or",
    #       "position": 7,
    #       "force_prefix": false,
    #       "force_prefix_search": false
    #     },
    #     {
    #       "value": "rl",
    #       "position": 8,
    #       "force_prefix": false,
    #       "force_prefix_search": false
    #     },
    #     {
    #       "value": "ld",
    #       "position": 9,
    #       "force_prefix": false,
    #       "force_prefix_search": false
    #     },
    #     {
    #       "value": "d",
    #       "position": 10,
    #       "force_prefix": false,
    #       "force_prefix_search": false
    #     }
    #   ]
    # ]

ノーマライザーを使っている場合は `TokenBigram` はASCIIの文字には空白区切りのようなトークナイズ方法を使います。非ASCII文字にはバイグラムのトークナイズ方法を使います。

もしかしたら、複数の方法が混ざったこの挙動はわかりにくいかもしれません。しかし、英語のテキスト（ASCII文字列のみ）や日本語テキスト（ASCII文字列と非ASCII文字列が混ざっている）ような多くのユースケースでは合理的な方法です。

ASCII文字しか使わない多くの言語は単語の区切りに空白文字を使っています。このようなケースに空白区切りのトークナイズ方法は適切です。

非ASCII文字を使う言語では単語の区切りに空白文字を使いません。このケースにはバイグラムなトークナイズ方法は適切です。

複数の言語が混ざっている場合は、複数の方法を組み合わせたトークナイズ方法が適切です。

ASCII文字にバイグラムなトークナイズ方法を使いたい場合は TokenBigramSplitSymbolAlpha のような `TokenBigramSplitXXX` というトークナイザーを参照してください。

例を使いながら `TokenBigram` の挙動を確認しましょう。

`TokenBigram` はASCII文字には1つ以上の空白文字をトークンの区切りとして使います。

実行例:

    tokenize TokenBigram "Hello World" NormalizerAuto
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     {
    #       "value": "hello",
    #       "position": 0,
    #       "force_prefix": false,
    #       "force_prefix_search": false
    #     },
    #     {
    #       "value": "world",
    #       "position": 1,
    #       "force_prefix": false,
    #       "force_prefix_search": false
    #     }
    #   ]
    # ]

`TokenBigram` はASCII文字には文字の種類が変わったところをトークンの区切りとします。文字の種類は次のどれかです。

> - アルファベット

> - 数字

> - 記号（たとえば `(` 、 `)` 、 `!` など）

> - ひらがな

> - カタカナ

> - 漢字

> - その他

次の例は2つのトークン区切りを示しています。

> - `100` （数字）と `cents` （アルファベット）の間のところ

> - `cents` （アルファベット）と `!!!` （記号）の間のところ

実行例:

    tokenize TokenBigram "100cents!!!" NormalizerAuto
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     {
    #       "value": "100",
    #       "position": 0,
    #       "force_prefix": false,
    #       "force_prefix_search": false
    #     },
    #     {
    #       "value": "cents",
    #       "position": 1,
    #       "force_prefix": false,
    #       "force_prefix_search": false
    #     },
    #     {
    #       "value": "!!!",
    #       "position": 2,
    #       "force_prefix": false,
    #       "force_prefix_search": false
    #     }
    #   ]
    # ]

以下は `TokenBigram` が非ASCII文字にはトークナイズ方法としてバイグラムを使う例です。

実行例:

    tokenize TokenBigram "日本語の勉強" NormalizerAuto
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     {
    #       "value": "日本",
    #       "position": 0,
    #       "force_prefix": false,
    #       "force_prefix_search": false
    #     },
    #     {
    #       "value": "本語",
    #       "position": 1,
    #       "force_prefix": false,
    #       "force_prefix_search": false
    #     },
    #     {
    #       "value": "語の",
    #       "position": 2,
    #       "force_prefix": false,
    #       "force_prefix_search": false
    #     },
    #     {
    #       "value": "の勉",
    #       "position": 3,
    #       "force_prefix": false,
    #       "force_prefix_search": false
    #     },
    #     {
    #       "value": "勉強",
    #       "position": 4,
    #       "force_prefix": false,
    #       "force_prefix_search": false
    #     },
    #     {
    #       "value": "強",
    #       "position": 5,
    #       "force_prefix": false,
    #       "force_prefix_search": false
    #     }
    #   ]
    # ]