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

# 7.16.16. `language_model_knn`

Added in version 15.1.8.

注釈

これは実験的な機能です。現時点ではまだ安定しきっていません。

## 7.16.16.1. 概要

`language_model_knn`はセマンティックサーチ用の関数です。

セマンティックサーチはk近傍法（k-Nearest Neighbors）を使います。

TokenLanguageModelKNNと合わせて使う必要があります。

`--filter`の条件と`--sort_keys`のソートキーとして使えます。

この関数を有効にするには次のコマンドで`language_model/knn`プラグインを有効にしてください。

    plugin_register language_model/knn

## 7.16.16.2. 構文

`language_model_knn`には必須の引数が2つあります。

    language_model_knn(column, query)

`column`は検索対象のカラムです。インデックスを設定したカラムでなければなりません。

`query`は検索クエリです。

## 7.16.16.3. 必要条件

Faissを有効にしたGroongaが必要です。公式パッケージでは有効になっています。

## 7.16.16.4. 使い方

最初に`language_model/knn`プラグインを登録する必要があります。

実行例：

    plugin_register language_model/knn
    # [[0,1337566253.89858,0.000355720520019531],true]

スキーマ定義とサンプルデータは次のとおりです。

サンプルスキーマ：

実行例：

    table_create --name Memos --flags TABLE_NO_KEY
    # [[0,1337566253.89858,0.000355720520019531],true]
    column_create \
      --table Memos \
      --name content \
      --flags COLUMN_SCALAR \
      --type ShortText
    # [[0,1337566253.89858,0.000355720520019531],true]

サンプルデータ：

実行例：

    load --table Memos
    [
    {"content": "I am a boy."},
    {"content": "This is an apple."},
    {"content": "Groonga is a full text search engine."}
    ]
    # [[0,1337566253.89858,0.000355720520019531],3]

各レコードごとにエンべディングの情報を保存しておく必要があります。そのカラムの作成は次のとおりです。

実行例：

    column_create Memos embedding_code COLUMN_SCALAR ShortBinary
    # [[0,1337566253.89858,0.000355720520019531],true]

セマンティックサーチ用のインデックスを作成します。

トークナイザーにはTokenLanguageModelKNNを指定します。トークナイザーの引数は`model`と`code_column`です。`model`には利用するモデルを指定し、`code_column`には生成したエンベディングの情報を保存するカラムを指定します。

実行例：

    table_create Centroids TABLE_HASH_KEY ShortBinary \
      --default_tokenizer \
        'TokenLanguageModelKNN("model", "hf:///groonga/all-MiniLM-L6-v2-Q4_K_M-GGUF", \
                               "code_column", "embedding_code")'
    # [[0,1337566253.89858,0.000355720520019531],true]
    column_create Centroids data_content COLUMN_INDEX Memos content
    # [[0,1337566253.89858,0.000355720520019531],true]

これでセマンティックサーチができるようになります。`Memos.content`にデータを`load`するとGroongaが自動でエンべディングを生成します。ユーザがエンべディングを生成する必要はありません。

以下はセマンティックサーチをする例です。

実行例：

    select Memos \
      --filter 'language_model_knn(content, "male child")' \
      --output_columns content
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         3
    #       ],
    #       [
    #         [
    #           "content",
    #           "ShortText"
    #         ]
    #       ],
    #       [
    #         "I am a boy."
    #       ],
    #       [
    #         "This is an apple."
    #       ],
    #       [
    #         "Groonga is a full text search engine."
    #       ]
    #     ]
    #   ]
    # ]

`language_model_knn` 関数はソートのキーとしても利用できます。`--sort_keys`に`language_model_knn`を指定します。類似度の高い順に結果を取得したいので、先頭に`-`を付けて降順で取得しています。

`_id`で絞り込んだ後に、類似度でソートする例は次のとおりです。

実行例：

    select Memos \
      --filter '_id < 3' \
      --sort_keys '-language_model_knn(content, "male child")' \
      --output_columns content
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         2
    #       ],
    #       [
    #         [
    #           "content",
    #           "ShortText"
    #         ]
    #       ],
    #       [
    #         "I am a boy."
    #       ],
    #       [
    #         "This is an apple."
    #       ]
    #     ]
    #   ]
    # ]

## 7.16.16.5. 引数

必須の引数が2つあります。

### 7.16.16.5.1. `column`

`column`は検索対象のカラムです。インデックスを設定したカラムでなければなりません。

### 7.16.16.5.2. `query`

`query`は検索クエリです。

### 7.16.16.5.3. `k`

Added in version 15.2.1.

返すレコード数を指定します。このオプションを設定しない場合、返すレコード数の上限は`10`になります。

負の値を指定することもできます。負の値の場合は、最大でマッチしたレコード数 + k + 1件のレコードを出力するという意味になります。例えば、`"{ "k" : -1 }"`はすべてのレコードを出力します。これはすべてのレコードを表示する場合にとても便利です。

以下は負の値を使った`k`の簡単な使用例です。

サンプルデータ：

実行例：

    load --table Memos
    [
    {"content": "I am a boy."},
    {"content": "This is an apple."},
    {"content": "Groonga is a full text search engine."},
    {"content": "This is an orange."},
    {"content": "This is a banana."},
    {"content": "This is a tomato."},
    {"content": "This is a carrot."},
    {"content": "This is a cucumber."},
    {"content": "This is a pepper."},
    {"content": "This is a potato."},
    {"content": "This is an onion."}
    ]
    # [[0,1337566253.89858,0.000355720520019531],11]

実行例：

    select Memos \
      --filter 'language_model_knn(text, "male child", { "k" : -1 })' \
      --output_columns content
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         11
    #       ],
    #       [
    #         [
    #           "content",
    #           "ShortText"
    #         ]
    #       ],
    #       [
    #         "I am a boy."
    #       ],
    #       [
    #         "This is a pepper."
    #       ],
    #       [
    #         "This is a cucumber."
    #       ],
    #       [
    #         "This is a carrot."
    #       ],
    #       [
    #         "This is a potato."
    #       ],
    #       [
    #         "This is an apple."
    #       ],
    #       [
    #         "This is a banana."
    #       ],
    #       [
    #         "This is a tomato."
    #       ],
    #       [
    #         "This is an orange."
    #       ],
    #       [
    #         "This is an onion."
    #       ]
    #     ]
    #   ]
    # ]

## 7.16.16.6. 戻り値

この関数はセレクターとして動きます。つまり、効率的に実行できるということです。

## 7.16.16.7. 参考

- TokenLanguageModelKNN