sql >> データベース >  >> RDS >> PostgreSQL

Postgres:1対多の検索のためのfloat配列のコサイン類似性のインデックス

    これを行う拡張機能がないことを確認したので、限られた回避策を見つけました:

    AとBの両方が正規化されている場合(長さ1)、cos(A, B) = 1 - 0.5 * ||A - B||^2||A - B|| はユークリッド距離であり、cos(A, B) コサイン類似度です。したがって、ユークリッド距離が大きいほど<=>余弦の類似性は低くなり(単位円を想像すると直感的に理解できます)、非正規ベクトルがある場合、方向を変えずに大きさを変更しても、余弦の類似性には影響しません。すばらしいので、ベクトルを正規化してユークリッド距離を比較できます...

    ありますここでいい答え キューブ について 、ユークリッドでn次元の点とGiSTインデックスをサポートします 距離が、100以下の次元しかサポートしていません(より高くハッキングすることができますが、135以上の問題があったので、今は怖いです)。 Postgres9.6以降も必要です。

    だから:

    1. 最大100個のディメンションを使用する必要がないことを確認してください。 Postgres9.6以降にアップグレードします。
    2. ベクトルを表す配列をテーブルに入力します。
    3. ベクトルを正規化して、cubeの追加の列を作成します ポイント。この列にGiSTインデックスを作成します。
    4. ユークリッド距離の昇順でコサイン類似度の降順を取得:EXPLAIN SELECT * FROM mytable ORDER BY normalized <-> cube(array[1,2,3,4,5,6,7,8,9,0]) LIMIT 10;

    100を超えるディメンションが必要な場合は、複数のインデックス付き列を使用してこれを実現できる可能性があります。その場合、回答を更新します。

    更新: 100次元を超えるベクトルを複数の列に分割することで私ができることは何もないことは間違いありません。テーブル全体をスキャンする必要があります。



    1. mysqlの部分的な単語検索

    2. PDO見積もり方法

    3. ネストされたクラス-CustomRowMapper!!もう問題ありません!! - パート2

    4. 2番目の列から最大の日付値を持つ列に基づいて個別の値を選択します