# groonga - オープンソースのカラムストア機能付き全文検索エンジン

- English

# 7.20.3. 補正

このセクションでは以下の補正機能について説明します。:

- どのように動作するか
- 使い方
- 学習方法

## 7.20.3.1. どのように動作するか

補正機能は補正した語を計算するために3種類の検索を使います。:

> 1. 学習したデータを共起検索。
> 2. 登録されている語を類似検索。（実行しないこともある）

### 7.20.3.1.1. 共起検索

共起検索はユーザの間違って入力した文字列から登録済みの語を検索します。共起検索ではユーザがどのように検索を実行したかを使います。ユーザがどのように検索したかはクエリログやアクセスログから学習します。

例えば、ユーザが以下のように検索を実行したとします。:

query | 時刻
--- | ---
serach （入力ミス！） | 2011-08-10T22:20:50+09:00
search （修正！） | 2011-08-10T22:20:52+09:00

上記の検索実行ログから以下のような補正ペアを作ります。

入力 | 補正された語
--- | ---
serach | search

1分以内の連続して実行された検索をユーザが入力を補正したものとみなします。検索を実行した間の入力途中の入力シーケンスは、補正用の学習データとしては利用しません。

ユーザが"serach"と入力した場合、共起検索は"saerch"を返します。なぜなら、"serach"が「入力」カラムにあり、対応する「補正される語」カラムの値が"search"だからです。

### 7.20.3.1.2. 類似文書検索

類似検索はユーザの入力をトークナイズし、同じトークンを含んだ登録済みの語を検索します。トークナイズにはTokenBigramトークナイザーを使います。これは groonga-suggest-create-dataset が作るサジェストデータセットスキーマではデフォルトトークナイザーとしてTokenBigramトークナイザーを使っているからです。

例えば、"search engine"という語が登録されているとします。ユーザが"web search service"や"sound engine"などで検索すると"search engine"が補正候補になります。なぜなら、"search engine"と"web search engine"は"search"という同じトークンを持つからです。また、"search engine"と"sound engine"は"engine"という同じトークンを持っています。

"search engine"は"search"トークンと"engine"トークンにトークナイズされます。（GroongaのTokenBigramトークナイザーは連続するアルファベットと数字を2文字にトークナイズしません。これは検索ノイズを減らす為です。確実に2文字でトークナイズするためにはTokenBigramSplitSymbolAlphaDigitを使います。）"web search service"は"web"トークンと"search"トークンと"service"トークンにトークナイズされます。"sound engine"は"sound"トークンと"engine"トークンにトークナイズされます。

## 7.20.3.2. 使い方

Groongaは補正機能を使うために suggest コマンドを用意しています。 --type correct オプションを使うと補正機能を利用できます。

例えば、"saerch"と入力した時の補正結果取得するコマンドは以下のようになります。:

実行例:

    suggest --table item_query --column kana --types correction --frequency_threshold 1 --query saerch
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   {
    #     "correct": [
    #       [
    #         1
    #       ],
    #       [
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "_score",
    #           "Int32"
    #         ]
    #       ],
    #       [
    #         "search",
    #         1
    #       ]
    #     ]
    #   }
    # ]

## 7.20.3.3. 学習方法

共起検索は学習データを使います。学習データはクエリログやアクセスログから作ります。学習データを作るためにはユーザが検索を実行したときの検索クエリとタイムスタンプが必要です。

例えば、ユーザが"search"で検索したかったとします。しかし、ユーザは正しい"search"というクエリで検索を実行する前に間違って"saerch"で検索してしまいました。このユーザの入力シーケンスは以下のようになります。:

> 1. 2011-08-10T13:33:23+09:00: s
> 2. 2011-08-10T13:33:23+09:00: sa
> 3. 2011-08-10T13:33:24+09:00: sae
> 4. 2011-08-10T13:33:24+09:00: saer
> 5. 2011-08-10T13:33:24+09:00: saerc
> 6. 2011-08-10T13:33:25+09:00: saerch （検索実行！）
> 7. 2011-08-10T13:33:29+09:00: serch （修正中…）
> 8. 2011-08-10T13:33:30+09:00: search （検索実行！）

以下のコマンドでこの入力シーケンスから学習できます。:

    load --table event_query --each 'suggest_preparer(_id, type, item, sequence, time, pair_query)'
    [
    {"sequence": "1", "time": 1312950803.86057, "item": "s"},
    {"sequence": "1", "time": 1312950803.96857, "item": "sa"},
    {"sequence": "1", "time": 1312950804.26057, "item": "sae"},
    {"sequence": "1", "time": 1312950804.56057, "item": "saer"},
    {"sequence": "1", "time": 1312950804.76057, "item": "saerc"},
    {"sequence": "1", "time": 1312950805.76057, "item": "saerch", "type": "submit"},
    {"sequence": "1", "time": 1312950809.76057, "item": "serch"},
    {"sequence": "1", "time": 1312950810.86057, "item": "search", "type": "submit"}
    ]