sql >> Databáze >  >> RDS >> PostgreSQL

Postgres:index kosinové podobnosti plovoucích polí pro vyhledávání typu one-to-many

Zjistil jsem, že žádné rozšíření to nedělá, takže jsem našel omezené řešení:

Pokud jsou A i B normalizovány (délka 1), cos(A, B) = 1 - 0.5 * ||A - B||^2 . ||A - B|| je euklidovská vzdálenost a cos(A, B) je kosinusová podobnost. Takže větší euklidovská vzdálenost <=> menší kosinusová podobnost (dává smysl intuitivně, pokud si představíte jednotkovou kružnici), a pokud máte nenormální vektory, změna jejich velikosti bez změny jejich směru neovlivní jejich kosinovou podobnost. Skvělé, takže mohu normalizovat své vektory a porovnat jejich euklidovské vzdálenosti...

Je tu hezká odpověď zde o Cube , který podporuje n-rozměrné body a GiST indexy na euklidovském vzdálenost, ale podporuje pouze 100 nebo méně rozměrů (lze hacknout vyšší, ale měl jsem problémy kolem 135 a vyšší, takže se teď bojím). Vyžaduje také Postgres 9.6 nebo novější.

Takže:

  1. Ujistěte se, že mi nezáleží na tom, abych měl maximálně 100 dimenzí. Upgradujte na Postgres 9.6 nebo novější.
  2. Vyplňte mou tabulku poli, která budou reprezentovat vektory.
  3. Normalizací vektorů vytvořte další sloupec cube body. Vytvořte v tomto sloupci index GiST.
  4. Řazení podle euklidovské vzdálenosti vzestupně pro získání kosinové podobnosti sestupně:EXPLAIN SELECT * FROM mytable ORDER BY normalized <-> cube(array[1,2,3,4,5,6,7,8,9,0]) LIMIT 10;

Pokud potřebuji více než 100 dimenzí, mohl bych toho dosáhnout pomocí více indexovaných sloupců. V takovém případě aktualizuje odpověď.

Aktualizace: Jsem si jistý, že s rozdělením vektoru> 100 dimenzí do více sloupců nemohu nic dělat. Nakonec musím naskenovat celou tabulku.



  1. vyberte dotaz ve wordpressu

  2. Služba nebyla po ServiceController.Stop() zcela zastavena

  3. sql dotaz pro vyhledání a nahrazení textu ve všech řádcích

  4. Převeďte řádek SQL na sloupce