7.8. トークナイザー

7.8.1. 概要

Groongaにはテキストをトークナイズするトークナイザーモージュールがあります。次のケースのときにトークナイザーを使います。

  • テキストのインデックスを構築するとき

    ../_images/used-when-indexing.png

    テキストのインデックスを構築するときにトークナイザーを使います。

  • クエリーで検索するとき

    ../_images/used-when-searching.png

    クエリーで検索するときにトークナイザーを使います。

全文検索ではトークナイザーは重要なモジュールです。トークナイザーを変えることで 適合率と再現率 のトレードオフを調整することができます。

一般的に TokenBigram が適切なトークナイザーです。トークナイザーについてよく知らない場合は TokenBigram を使うことをオススメします。

tokenize コマンドと table_tokenize コマンドを使うことでトークナイザーを試すことができます。 tokenize コマンドを使って TokenBigram トークナイザーを試す例を以下に示します。

実行例:

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

7.8.2. 「トークナイズ」とはなにか

「トークナイズ」はテキストから0個以上のトークンを抽出する処理です。「トークナイズ」する方法はいくつかあります。

例えば、バイグラムというトークナイズ方法では Hello World は次のトークンにトークナイズされます。

  • He
  • el
  • ll
  • lo
  • o__ は空白文字という意味)

  • _W_ は空白文字という意味)

  • Wo
  • or
  • rl
  • ld

上記の例では、 Hello World から10個のトークンを抽出しました。

例えば、空白区切りのトークナイズ方法では Hello World は次のトークンにトークナイズされます。

  • Hello
  • World

上記の例では、Hello World から2つのトークンを抽出しました。

トークンは検索時のキーとして使われます。使用したトークナイズ方法で抽出したトークンでしかインデックス化されたドキュメントを探すことはできません。例えば、トークナイズ方法としてバイグラムを使った場合は llHello World を見つけることができます。しかし、空白区切りのトークナイズ方法を使ったときは llHello World を見つけることはできません。なぜなら、空白区切りのトークナイズ方法は ll というトークンを抽出していないからです。空白区切りのトークナイズ方法は Hello というトークンと World というトークンしか抽出していません。

一般的に、小さいトークンを生成するトークナイズ方法は再現率が高い代わりに適合率が低くなりがちです。一方、大きいトークンを生成するトークナイズ方法は適合率が高い代わりに再現率が低くなりがちです。

例えば、バイグラムというトークナイズ方法では orHello WorldA or B を検索できます。しかし、「論理和」を検索したい人にとっては Hello World は不要な結果です。これは、適合率が下がったということです。しかし、再現率は上がっています。

空白区切りのトークナイズ方法を使った場合は orA or B だけが見つかります。なぜなら、空白区切りのトークナイズ方法では WorldWorld という1つのトークンだけにトークナイズされるからです。これは、「論理和」を探したい人にとっては適合率が挙がっています。しかし、 Hello Worldor を含んでいるのに見つかっていないので再現率が下がっています。

7.8.3. 組み込みトークナイザー

以下は組み込みのトークナイザーのリストです。

  • TokenBigram
  • TokenBigramSplitSymbol
  • TokenBigramSplitSymbolAlpha
  • TokenBigramSplitSymbolAlphaDigit
  • TokenBigramIgnoreBlank
  • TokenBigramIgnoreBlankSplitSymbol
  • TokenBigramIgnoreBlankSplitSymbolAlpha
  • TokenBigramIgnoreBlankSplitSymbolAlphaDigit
  • TokenUnigram
  • TokenTrigram
  • TokenDelimit
  • TokenDelimitNull
  • TokenMecab
  • TokenRegexp

7.8.3.1. TokenBigram

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

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

  • He
  • el
  • ll
  • lo

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

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

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

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

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

実行例:

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

ノーマライザーを使っている場合は 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
#   ],
#   [
#     {
#       "position": 0,
#       "force_prefix": false,
#       "value": "hello"
#     },
#     {
#       "position": 1,
#       "force_prefix": false,
#       "value": "world"
#     }
#   ]
# ]

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

  • アルファベット

  • 数字

  • 記号(たとえば ()! など)

  • ひらがな

  • カタカナ

  • 漢字

  • その他

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

  • 100 (数字)と cents (アルファベット)の間のところ

  • cents (アルファベット)と !!! (記号)の間のところ

実行例:

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

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

実行例:

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

7.8.3.2. TokenBigramSplitSymbol

TokenBigramSplitSymbolTokenBigram と似ています。違いは記号の扱いです。 TokenBigramSplitSymbol は記号のトークナイズ方法にバイグラムを使います。

実行例:

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

7.8.3.3. TokenBigramSplitSymbolAlpha

TokenBigramSplitSymbolAlphaTokenBigram と似ています。違いは記号とアルファベットの扱いです。 TokenBigramSplitSymbolAlpha は記号とアルファベットのトークナイズ方法にバイグラムを使います。

実行例:

tokenize TokenBigramSplitSymbolAlpha "100cents!!!" NormalizerAuto
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     {
#       "position": 0,
#       "force_prefix": false,
#       "value": "100"
#     },
#     {
#       "position": 1,
#       "force_prefix": false,
#       "value": "ce"
#     },
#     {
#       "position": 2,
#       "force_prefix": false,
#       "value": "en"
#     },
#     {
#       "position": 3,
#       "force_prefix": false,
#       "value": "nt"
#     },
#     {
#       "position": 4,
#       "force_prefix": false,
#       "value": "ts"
#     },
#     {
#       "position": 5,
#       "force_prefix": false,
#       "value": "s!"
#     },
#     {
#       "position": 6,
#       "force_prefix": false,
#       "value": "!!"
#     },
#     {
#       "position": 7,
#       "force_prefix": false,
#       "value": "!!"
#     },
#     {
#       "position": 8,
#       "force_prefix": false,
#       "value": "!"
#     }
#   ]
# ]

7.8.3.4. TokenBigramSplitSymbolAlphaDigit

TokenBigramSplitSymbolAlphaDigitTokenBigram と似ています。違いは記号とアルファベットと数字の扱いです。 TokenBigramSplitSymbolAlphaDigit は記号とアルファベット数字のトークナイズ方法にバイグラムを使います。つまり、すべての文字をバイグラムでトークナイズします。

実行例:

tokenize TokenBigramSplitSymbolAlphaDigit "100cents!!!" NormalizerAuto
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     {
#       "position": 0,
#       "force_prefix": false,
#       "value": "10"
#     },
#     {
#       "position": 1,
#       "force_prefix": false,
#       "value": "00"
#     },
#     {
#       "position": 2,
#       "force_prefix": false,
#       "value": "0c"
#     },
#     {
#       "position": 3,
#       "force_prefix": false,
#       "value": "ce"
#     },
#     {
#       "position": 4,
#       "force_prefix": false,
#       "value": "en"
#     },
#     {
#       "position": 5,
#       "force_prefix": false,
#       "value": "nt"
#     },
#     {
#       "position": 6,
#       "force_prefix": false,
#       "value": "ts"
#     },
#     {
#       "position": 7,
#       "force_prefix": false,
#       "value": "s!"
#     },
#     {
#       "position": 8,
#       "force_prefix": false,
#       "value": "!!"
#     },
#     {
#       "position": 9,
#       "force_prefix": false,
#       "value": "!!"
#     },
#     {
#       "position": 10,
#       "force_prefix": false,
#       "value": "!"
#     }
#   ]
# ]

7.8.3.5. TokenBigramIgnoreBlank

TokenBigramIgnoreBlankTokenBigram と似ています。違いは空白文字の扱いです。 TokenBigramIgnoreBlank は連続する記号と非ASCII文字の間にある空白文字を無視します。

! ! ! というテキストを使うと違いがわかります。なぜならこのテキストは記号と非ASCII文字を両方含んでいるからです。

TokenBigram での実行結果です。

実行例:

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

TokenBigramIgnoreBlank での実行結果です。

実行例:

tokenize TokenBigramIgnoreBlank "日 本 語 ! ! !" NormalizerAuto
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     {
#       "position": 0,
#       "force_prefix": false,
#       "value": "日本"
#     },
#     {
#       "position": 1,
#       "force_prefix": false,
#       "value": "本語"
#     },
#     {
#       "position": 2,
#       "force_prefix": false,
#       "value": "語"
#     },
#     {
#       "position": 3,
#       "force_prefix": false,
#       "value": "!!!"
#     }
#   ]
# ]

7.8.3.6. TokenBigramIgnoreBlankSplitSymbol

TokenBigramIgnoreBlankSplitSymbolTokenBigram と似ています。違いは次の通りです。

  • 空白文字の扱い

  • 記号の扱い

TokenBigramIgnoreBlankSplitSymbol は連続した記号と非ASCII文字の間の空白文字を無視します。

TokenBigramIgnoreBlankSplitSymbol は記号をバイグラムでトークナイズします。

! ! ! というテキストを使うと違いがわかります。なぜならこのテキストは記号と非ASCII文字を両方含んでいるからです。

TokenBigram での実行結果です。

実行例:

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

TokenBigramIgnoreBlankSplitSymbol の実行結果です。

実行例:

tokenize TokenBigramIgnoreBlankSplitSymbol "日 本 語 ! ! !" NormalizerAuto
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     {
#       "position": 0,
#       "force_prefix": false,
#       "value": "日本"
#     },
#     {
#       "position": 1,
#       "force_prefix": false,
#       "value": "本語"
#     },
#     {
#       "position": 2,
#       "force_prefix": false,
#       "value": "語!"
#     },
#     {
#       "position": 3,
#       "force_prefix": false,
#       "value": "!!"
#     },
#     {
#       "position": 4,
#       "force_prefix": false,
#       "value": "!!"
#     },
#     {
#       "position": 5,
#       "force_prefix": false,
#       "value": "!"
#     }
#   ]
# ]

7.8.3.7. TokenBigramIgnoreBlankSplitSymbolAlpha

TokenBigramIgnoreBlankSplitSymbolAlphaTokenBigram と似ています。違いは次の通りです。

  • 空白文字の扱い

  • 記号とアルファベットの扱い

TokenBigramIgnoreBlankSplitSymbolAlpha は連続した記号と非ASCII文字の間の空白文字を無視します。

TokenBigramIgnoreBlankSplitSymbolAlpha は記号とアルファベットをバイグラムでトークナイズします。

Hello ! ! ! というテキストを使うと違いがわかります。なぜなら空白文字入りの記号と非ASCII文字だけでなく、アルファベットも含んでいるからです。

TokenBigram での実行結果です。

実行例:

tokenize TokenBigram "Hello 日 本 語 ! ! !" NormalizerAuto
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     {
#       "position": 0,
#       "force_prefix": false,
#       "value": "hello"
#     },
#     {
#       "position": 1,
#       "force_prefix": false,
#       "value": "日"
#     },
#     {
#       "position": 2,
#       "force_prefix": false,
#       "value": "本"
#     },
#     {
#       "position": 3,
#       "force_prefix": false,
#       "value": "語"
#     },
#     {
#       "position": 4,
#       "force_prefix": false,
#       "value": "!"
#     },
#     {
#       "position": 5,
#       "force_prefix": false,
#       "value": "!"
#     },
#     {
#       "position": 6,
#       "force_prefix": false,
#       "value": "!"
#     }
#   ]
# ]

TokenBigramIgnoreBlankSplitSymbolAlpha の実行結果です。

実行例:

tokenize TokenBigramIgnoreBlankSplitSymbolAlpha "Hello 日 本 語 ! ! !" NormalizerAuto
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     {
#       "position": 0,
#       "force_prefix": false,
#       "value": "he"
#     },
#     {
#       "position": 1,
#       "force_prefix": false,
#       "value": "el"
#     },
#     {
#       "position": 2,
#       "force_prefix": false,
#       "value": "ll"
#     },
#     {
#       "position": 3,
#       "force_prefix": false,
#       "value": "lo"
#     },
#     {
#       "position": 4,
#       "force_prefix": false,
#       "value": "o日"
#     },
#     {
#       "position": 5,
#       "force_prefix": false,
#       "value": "日本"
#     },
#     {
#       "position": 6,
#       "force_prefix": false,
#       "value": "本語"
#     },
#     {
#       "position": 7,
#       "force_prefix": false,
#       "value": "語!"
#     },
#     {
#       "position": 8,
#       "force_prefix": false,
#       "value": "!!"
#     },
#     {
#       "position": 9,
#       "force_prefix": false,
#       "value": "!!"
#     },
#     {
#       "position": 10,
#       "force_prefix": false,
#       "value": "!"
#     }
#   ]
# ]

7.8.3.8. TokenBigramIgnoreBlankSplitSymbolAlphaDigit

TokenBigramIgnoreBlankSplitSymbolAlphaDigitTokenBigram と似ています。違いは次の通りです。

  • 空白文字の扱い

  • 記号とアルファベットと数字の扱い

TokenBigramIgnoreBlankSplitSymbolAlphaDigit は連続した記号と非ASCII文字の間の空白文字を無視します。

TokenBigramIgnoreBlankSplitSymbolAlphaDigit は記号、アルファベット、数字をバイグラムでトークナイズします。つまり、すべての文字をバイグラムでトークナイズします。

Hello ! ! ! 777 というテキストを使うと違いがわかります。なぜなら、このテキストは空白文字入りの記号と非ASCII文字だけでなく、アルファベットと数字も含んでいるからです。

TokenBigram での実行結果です。

実行例:

tokenize TokenBigram "Hello 日 本 語 ! ! ! 777" NormalizerAuto
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     {
#       "position": 0,
#       "force_prefix": false,
#       "value": "hello"
#     },
#     {
#       "position": 1,
#       "force_prefix": false,
#       "value": "日"
#     },
#     {
#       "position": 2,
#       "force_prefix": false,
#       "value": "本"
#     },
#     {
#       "position": 3,
#       "force_prefix": false,
#       "value": "語"
#     },
#     {
#       "position": 4,
#       "force_prefix": false,
#       "value": "!"
#     },
#     {
#       "position": 5,
#       "force_prefix": false,
#       "value": "!"
#     },
#     {
#       "position": 6,
#       "force_prefix": false,
#       "value": "!"
#     },
#     {
#       "position": 7,
#       "force_prefix": false,
#       "value": "777"
#     }
#   ]
# ]

TokenBigramIgnoreBlankSplitSymbolAlphaDigit の実行結果です。

実行例:

tokenize TokenBigramIgnoreBlankSplitSymbolAlphaDigit "Hello 日 本 語 ! ! ! 777" NormalizerAuto
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     {
#       "position": 0,
#       "force_prefix": false,
#       "value": "he"
#     },
#     {
#       "position": 1,
#       "force_prefix": false,
#       "value": "el"
#     },
#     {
#       "position": 2,
#       "force_prefix": false,
#       "value": "ll"
#     },
#     {
#       "position": 3,
#       "force_prefix": false,
#       "value": "lo"
#     },
#     {
#       "position": 4,
#       "force_prefix": false,
#       "value": "o日"
#     },
#     {
#       "position": 5,
#       "force_prefix": false,
#       "value": "日本"
#     },
#     {
#       "position": 6,
#       "force_prefix": false,
#       "value": "本語"
#     },
#     {
#       "position": 7,
#       "force_prefix": false,
#       "value": "語!"
#     },
#     {
#       "position": 8,
#       "force_prefix": false,
#       "value": "!!"
#     },
#     {
#       "position": 9,
#       "force_prefix": false,
#       "value": "!!"
#     },
#     {
#       "position": 10,
#       "force_prefix": false,
#       "value": "!7"
#     },
#     {
#       "position": 11,
#       "force_prefix": false,
#       "value": "77"
#     },
#     {
#       "position": 12,
#       "force_prefix": false,
#       "value": "77"
#     },
#     {
#       "position": 13,
#       "force_prefix": false,
#       "value": "7"
#     }
#   ]
# ]

7.8.3.9. TokenUnigram

TokenUnigramTokenBigram に似ています。違いはトークンの単位です。 TokenBigram は各トークンが2文字ですが、 TokenUnigram は各トークンが1文字です。

実行例:

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

7.8.3.10. TokenTrigram

TokenTrigramTokenBigram に似ています。違いはトークンの単位です。 TokenBigram は各トークンが2文字ですが、 TokenTrigram は各トークンが3文字です。

実行例:

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

7.8.3.11. TokenDelimit

TokenDelimit は1つ以上の空白文字( U+0020 )で分割してトークンを抽出します。たとえば、 Hello WorldHelloWorld にトークナイズされます。

TokenDelimit はタグテキストに適切です。 groonga full-text-search http というテキストから groongafull-text-searchhttp を抽出します。

以下は TokenDelimit の例です。

実行例:

tokenize TokenDelimit "Groonga full-text-search HTTP" NormalizerAuto
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     {
#       "position": 0,
#       "force_prefix": false,
#       "value": "groonga"
#     },
#     {
#       "position": 1,
#       "force_prefix": false,
#       "value": "full-text-search"
#     },
#     {
#       "position": 2,
#       "force_prefix": false,
#       "value": "http"
#     }
#   ]
# ]

7.8.3.12. TokenDelimitNull

TokenDelimitNullTokenDelimit に似ています。違いは区切り文字です。 TokenDelimit は空白文字( U+0020 )を使いますが、 TokenDelimitNull はNUL文字( U+0000 )を使います。

TokenDelimitNull もタグテキストに適切です。

以下は TokenDelimitNull の例です。

実行例:

tokenize TokenDelimitNull "Groonga\u0000full-text-search\u0000HTTP" NormalizerAuto
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     {
#       "position": 0,
#       "force_prefix": false,
#       "value": "groongau0000full-text-searchu0000http"
#     }
#   ]
# ]

7.8.3.13. TokenMecab

TokenMecabMeCab 形態素解析器をベースにしたトークナイザーです。

MeCabは日本語に依存していません。その言語用の辞書を用意すれば日本語以外でもMeCabを使えます。日本語用の辞書には NAIST Japanese Dictionary を使えます。

TokenMecab は再現率より適合率に優れています。 TokenBigram では 京都 というクエリーで 東京都京都 も見つかりますが、この場合は 東京都 は期待した結果ではありません。 TokenMecab を使うと 京都 というクエリーで 京都 だけを見つけられます。

新語をサポートしたい場合は、MeCabの辞書を更新し続ける必要があります。これはメンテナンスコストがかかります。( TokenBigram には辞書のメンテナンスコストはありません。なぜなら、 TokenBigram は辞書を使っていないからです。)新語への対応に mecab-ipadic-NEologd : Neologism dictionary for MeCab が役に立つかもしれません。

以下は TokenMeCab の例です。 東京都東京 にトークナイズされています。 京都 というトークンはありません。

実行例:

tokenize TokenMecab "東京都"
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     {
#       "position": 0,
#       "force_prefix": false,
#       "value": "東京"
#     },
#     {
#       "position": 1,
#       "force_prefix": false,
#       "value": "都"
#     }
#   ]
# ]

7.8.3.14. TokenRegexp

バージョン 5.0.1 で追加.

ご用心

このトークナイザーは実験的です。仕様が変わる可能性があります。

ご用心

このトークナイザーはUTF-8でしか使えません。EUC-JPやShift_JISなどと一緒には使えません。

TokenRegexp はインデックスを使った正規表現検索をサポートするトークナイザーです。

一般的に、正規表現検索は逐次検索で実行します。しかし、次のケースはインデックスを使って検索できます。

  • hello のようにリテラルしかないケース

  • \A/home/alice のようにテキストの最初でのマッチとリテラルのみのケース

  • \.txt\z のようにテキストの最後でのマッチとリテラルのみのケース

多くのケースでは、逐次検索よりもインデックスを使った検索の方が高速です。

TokenRegexp はベースはバイグラムを使います。 TokenRegexp は、インデックス時に、テキストの先頭にテキストの先頭であるというマーク( U+FFEF )を入れ、テキストの最後にテキストの最後であるというマーク( U+FFF0 )を入れます。

実行例:

tokenize TokenRegexp "/home/alice/test.txt" NormalizerAuto --mode ADD
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     {
#       "position": 0,
#       "force_prefix": false,
#       "value": "￯"
#     },
#     {
#       "position": 1,
#       "force_prefix": false,
#       "value": "/h"
#     },
#     {
#       "position": 2,
#       "force_prefix": false,
#       "value": "ho"
#     },
#     {
#       "position": 3,
#       "force_prefix": false,
#       "value": "om"
#     },
#     {
#       "position": 4,
#       "force_prefix": false,
#       "value": "me"
#     },
#     {
#       "position": 5,
#       "force_prefix": false,
#       "value": "e/"
#     },
#     {
#       "position": 6,
#       "force_prefix": false,
#       "value": "/a"
#     },
#     {
#       "position": 7,
#       "force_prefix": false,
#       "value": "al"
#     },
#     {
#       "position": 8,
#       "force_prefix": false,
#       "value": "li"
#     },
#     {
#       "position": 9,
#       "force_prefix": false,
#       "value": "ic"
#     },
#     {
#       "position": 10,
#       "force_prefix": false,
#       "value": "ce"
#     },
#     {
#       "position": 11,
#       "force_prefix": false,
#       "value": "e/"
#     },
#     {
#       "position": 12,
#       "force_prefix": false,
#       "value": "/t"
#     },
#     {
#       "position": 13,
#       "force_prefix": false,
#       "value": "te"
#     },
#     {
#       "position": 14,
#       "force_prefix": false,
#       "value": "es"
#     },
#     {
#       "position": 15,
#       "force_prefix": false,
#       "value": "st"
#     },
#     {
#       "position": 16,
#       "force_prefix": false,
#       "value": "t."
#     },
#     {
#       "position": 17,
#       "force_prefix": false,
#       "value": ".t"
#     },
#     {
#       "position": 18,
#       "force_prefix": false,
#       "value": "tx"
#     },
#     {
#       "position": 19,
#       "force_prefix": false,
#       "value": "xt"
#     },
#     {
#       "position": 20,
#       "force_prefix": false,
#       "value": "t"
#     },
#     {
#       "position": 21,
#       "force_prefix": false,
#       "value": "￰"
#     }
#   ]
# ]