これを行う拡張機能がないことを確認したので、限られた回避策を見つけました:
AとBの両方が正規化されている場合(長さ1)、cos(A, B) = 1 - 0.5 * ||A - B||^2
。 ||A - B||
はユークリッド距離であり、cos(A, B)
コサイン類似度です。したがって、ユークリッド距離が大きいほど<=>余弦の類似性は低くなり(単位円を想像すると直感的に理解できます)、非正規ベクトルがある場合、方向を変えずに大きさを変更しても、余弦の類似性には影響しません。すばらしいので、ベクトルを正規化してユークリッド距離を比較できます...
ありますここでいい答え キューブ について 、ユークリッドでn次元の点とGiSTインデックスをサポートします 距離が、100以下の次元しかサポートしていません(より高くハッキングすることができますが、135以上の問題があったので、今は怖いです)。 Postgres9.6以降も必要です。
だから:
- 最大100個のディメンションを使用する必要がないことを確認してください。 Postgres9.6以降にアップグレードします。
- ベクトルを表す配列をテーブルに入力します。
- ベクトルを正規化して、
cube
の追加の列を作成します ポイント。この列にGiSTインデックスを作成します。 - ユークリッド距離の昇順でコサイン類似度の降順を取得:
EXPLAIN SELECT * FROM mytable ORDER BY normalized <-> cube(array[1,2,3,4,5,6,7,8,9,0]) LIMIT 10;
100を超えるディメンションが必要な場合は、複数のインデックス付き列を使用してこれを実現できる可能性があります。その場合、回答を更新します。
更新: 100次元を超えるベクトルを複数の列に分割することで私ができることは何もないことは間違いありません。テーブル全体をスキャンする必要があります。