Днес ще разгледаме един вълнуващ подход за търсене в бази данни, наречен векторно търсене (vector search или similarity search). Ще се фокусираме върху използването на pgvector – мощно разширение за PostgreSQL, което добавя специализирани типове данни и индекси за ефективно векторно търсене. Ще обясним концепциите, ще покажем практически примери и ще обсъдим потенциалните приложения на тази техника. Нека да се гмурнем!

Какво е векторно търсене?

Векторното търсене, известно още като similarity search, е техника за намиране на най-подобните елементи на даден елемент в множество от елементи. За разлика от традиционното точно съвпадение (exact-match) търсене, където търсим елементи, които напълно съвпадат с даден критерий, при векторното търсене търсим елементи, които са най-близки или най-подобни на дадена заявка.

Основната идея е да представим елементите като многомерни вектори в някакво векторно пространство. Всяка размерност на вектора представлява определена характеристика или признак на елемента. Например, ако елементите са текстови документи, векторите могат да представляват честотата на срещане на различните думи в документа (т.нар. TF-IDF вектори).

След като имаме векторни представяния на елементите, можем да измерим подобието или разстоянието между тях, използвайки различни метрики като евклидово разстояние, косинусова прилика, Jaccard разстояние и др. Колкото по-малко е разстоянието (или по-голяма е приликата) между два вектора, толкова по-подобни са съответните елементи.

Векторното търсене има много приложения в области като информационно извличане, препоръчителни системи, откриване на аномалии, класификация на текст и изображения и др. То ни позволява да намираме подобни продукти, да предлагаме персонализирани препоръки, да групираме сходни документи и много други.

Въведение в pgvector

Традиционно, релационните бази данни не са особено подходящи за векторно търсене, тъй като техните индекси и заявки са оптимизирани за exact-match търсене. Но с навлизането на AI и машинното обучение, възниква необходимостта да съхраняваме и търсим ефективно векторни embeddings в бази данни.

Тук на помощ идва pgvector – разширение за PostgreSQL, което добавя специализирана функционалност за работа с вектори. То предоставя нови типове данни за съхранение на вектори (vector), индекси, оптимизирани за векторно търсене (ivfflat) и функции за изчисляване на разстояния и прилики.

С pgvector можем да съхраняваме многомерни вектори директно в PostgreSQL таблици, да индексираме тези вектори за бързо търсене и да изпълняваме заявки за намиране на най-подобните вектори на даден вектор. И всичко това с познатия и мощен SQL интерфейс на PostgreSQL.

Нека сега видим как можем да използваме pgvector на практика.

Инсталация и настройка на pgvector

Първо, трябва да инсталираме pgvector разширението в нашата PostgreSQL база данни. Pgvector е достъпен като самостоятелен пакет в повечето дистрибуции на PostgreSQL.

За Ubuntu/Debian:


# Install PostgreSQL
sudo apt install postgresql-15-vector

За macOS (използвайки Homebrew):


# Install
brew install pgvector

След като пакетът е инсталиран, трябва да активираме разширението в желаната база:


CREATE EXTENSION vector;

Сега сме готови да използваме функционалността на pgvector.

Съхранение и индексиране на вектори

Нека създадем таблица, която да съхранява текстови документи заедно с техните векторни представяния:


CREATE TABLE documents (
  id SERIAL PRIMARY KEY,
  content TEXT,
  embedding VECTOR(384)
);

Тук дефинираме колона embedding от тип vector с размерност 384 (може да използваме произволна размерност според нашите нужди).

За да ускорим векторното търсене, можем да създадем специализиран индекс върху embedding колоната:


# Creating the index
CREATE INDEX ON documents USING ivfflat (embedding vector_cosine_ops);

Индексът от тип ivfflat (Inverted File Flat) е оптимизиран за бързо търсене на най-близките съседи в многомерни векторни пространства. Параметърът vector_cosine_ops указва, че ще използваме косинусова прилика като метрика за разстояние.

Вмъкване и търсене на вектори

Сега можем да вмъкваме документи и техните векторни представяния в таблицата:


INSERT INTO documents (content, embedding)
VALUES
  ('The quick brown fox', '{0.1, 0.2, 0.3, ..., 0.384}'),
  ('The lazy dog', '{0.2, 0.3, 0.4, ..., 0.584}'),
  ('The quick brown cat', '{0.15, 0.25, 0.35, ..., 0.434}');

За да търсим най-подобните документи на даден заявка вектор, можем да използваме функцията cosine_distance на pgvector:


SELECT id, content
FROM documents
ORDER BY embedding <-> '{0.1, 0.2, 0.3, ..., 0.384}'::vector
LIMIT 5;

Тук <-> е операторът за изчисляване на косинусова разстояние между два вектора. Колкото по-малко е разстоянието, толкова по-подобни са векторите. Чрез ORDER BY и LIMIT клаузите получаваме топ-5 най-близки документи до заявката.

pgvector предлага и други полезни функции като cosine_similarity, l2_distance, inner_product и др. за работа с вектори и изчисляване на различни метрики за подобие.

Потенциални приложения и предизвикателства

Векторното търсене с pgvector отваря много възможности за приложения, които се нуждаят от ефективно намиране на подобия в големи набори от данни. Някои примери:

  • Препоръчващи системи (Recommendation systems):  Намиране на подобни продукти, филми, песни и т.н. на базата на поведението или профила на потребителя.
  • Семантично търсене: Търсене на документи, изображения или видеа, които са семантично близки до заявката, а не само точно съвпадение на ключови думи.
  • Откриване на дубликати: Идентифициране на почти дубликати в големи набори от данни като документи, изображения, записи в бази данни и др.
  • Класификация и клъстеризация: Групиране на подобни елементи в клъстери или категории въз основа на техните векторни представяния.

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

  • Векторните embeddings трябва да се генерират предварително от външни модели (напр. neural networks) и да се съхраняват в базата данни. Това може да изисква допълнителни стъпки на предварителна обработка и интеграция;
  • Размерът и плътността на векторите могат значително да повлияят на производителността на търсенето и изискванията за съхранение. Трябва внимателно да се избере подходяща размерност и представяне на векторите;
  • Подобието и разстоянието между вектори не винаги отразяват перфектно семантичната прилика между елементите. Резултатите от векторното търсене понякога може да са неинтуитивни или неточни и да изискват допълнително филтриране;
  • Поддържането на векторните индекси при чести промени (вмъквания и изтривания) в данните може да бъде скъпо. В някои случаи може да се наложи периодично възстановяване на индексите.

Въпреки тези предизвикателства, векторното търсене е мощна техника, която може значително да подобри възможностите и ефективността на много приложения, работещи с неструктурирани и полуструктурирани данни. И с инструменти като pgvector, интегрирането на векторно търсене в PostgreSQL бази данни става по-лесно от всякога.

Заключение

В тази статия разгледахме концепцията за векторно търсене и как тя може да се приложи в PostgreSQL бази данни с помощта на pgvector разширението. Видяхме как да съхраняваме и индексираме вектори, как да търсим най-подобните вектори с SQL заявки и обсъдихме потенциалните приложения и предизвикателства на този подход.

Векторното търсене е важна техника в съвременния свят на данните, която позволява ефективно намиране на прилики и връзки в големи и разнообразни набори от данни. С инструменти като pgvector, можем да използваме силата на векторното търсене директно в PostgreSQL, без да се налага да прибягваме до външни системи или сложни ETL процеси.

Надяваме се тази статия да ви е дала добро въведение в света на векторното търсене в бази данни и да е предизвикала интереса ви да експериментирате с pgvector. Ако имате интересен случай на използване на векторно търсене, споделете го с мен!

Last Update: май 3, 2024