PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Postgres:индекс на косинус подобие на плаващи масиви за търсене "един към много".

Разбирам, че няма разширение, което да прави това, така че намерих ограничено решение:

Ако A и B са нормализирани (дължина 1), cos(A, B) = 1 - 0.5 * ||A - B||^2 . ||A - B|| е евклидовото разстояние и cos(A, B) е косинусното подобие. Така че по-голямо евклидово разстояние <=> по-малко косинусово подобие (има смисъл интуитивно, ако си представите единична окръжност) и ако имате ненормални вектори, промяната на техните величини без промяна на посоките им не влияе на техните косинусови подобия. Страхотно, така че мога да нормализирам моите вектори и да сравня техните евклидови разстояния...

Има хубав отговор тук относно Cube , който поддържа n-измерни точки и GiST индекси на Евклидов разстояние, но поддържа само 100 или по-малко измерения (може да бъде хакнат по-високо, но имах проблеми около 135 и по-високи, така че сега се страхувам). Също така изисква Postgres 9.6 или по-нова версия.

И така:

  1. Уверете се, че не ми пука да имам най-много 100 измерения. Надстройте до Postgres 9.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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Разбиране на типовете дата и функциите на PostgreSQL (по примери)

  2. Laravel eloquent - Има ли начин да добавите подсказка преди SELECT?

  3. Multi-DC PostgreSQL:Настройка на възел в режим на готовност на различно географско местоположение през VPN

  4. Postgres на високо ниво работи със скорост INSERT/UPDATE?

  5. Изтриването на ред от основната таблица влияе ли върху изгледа на тази таблица?