- PVSM.RU - https://www.pvsm.ru -
Представьте, что управляете онлайн-магазином, предлагающим тысячи товаров.
Чтобы помочь пользователям находить нужные позиции, вы добавили строку поиска. Теперь посетители могут вводить интересующие их запросы, на что вы будете показывать им подходящие результаты.
Например, когда пользователь вводит «лето», вы можете показывать предметы вроде шортов, платьев, панам и пляжных зонтов.
Как бы вы реализовали такую систему?
Если вы используете реляционную базу данных вроде Postgres или MySQL, то можете выполнять запрос, который путём сопоставления будет находить товары, содержащие введённые пользователем слова.
Но здесь есть подвох: если пользователь ищет «лето», то БД будет исключать товары, не содержащие это слово, и вы упустите такие позиции, как «панама» или «пляжный зонт».
Чтобы более наглядно представить проблему, предположим, что у вас есть следующая таблица товаров:
ID | Название |
1 | Летнее платье |
2 | Панама |
3 | Пляжный зонт |
... | ... |
999 | Зимний плащ |
Теперь выполним запрос для поиска позиций, в названии которых содержится «лето» (в оригинале summer — прим. пер.):
SELECT * FROM products WHERE name LIKE '%summer%';
=> Found 1 result
=> Product(id=1 name="Summer dress")
Всё верно, был найден 1 результат — «Летнее платье». Но как же «Панама» и «Пляжный зонт»? Возможно, именно эти вещи ищет пользователь, а в результатах поиска они отсутствуют.
И здесь нет ошибок в написании, поэтому нечёткий поиск (fuzzy search) не поможет. База данных не находит эти товары, потому что не понимает, что они в более общем смысле относятся к «лету».
Вот здесь и приходят на выручку векторные базы данных.
В нашем случае вектор — это просто список чисел. Он подобен координатам в многомерном пространстве, где каждое измерение представляет отдельный признак элемента.
Вектор может выражать что угодно: слово, продукт, изображение и даже прошлые взаимодействия пользователя с вашим приложением.
Например, если вы будете рекомендовать посетителям товары, то можете использовать для их представления вектор с сотнями измерений, каждое из которых будет выражать отдельный аспект того или иного товара (цвет, размер, цену, сезонность и так далее).
В этом случае вы можете сравнивать такие векторы для поиска схожих товаров, даже если они не будут содержать одинаковые ключевые слова.
Векторная база данных — это простая база данных, оптимизированная под хранение и поиск векторов, даже таких, которые состоят из сотен и тысяч измерений.
Когда вы запрашиваете вектор, вместо поиска точных совпадений, он находит элементы на основе их приближённости к запросу.
Например, в нашем сценарии векторы «лето» и «панама» окажутся рядом, а вектор «зимний плащ» будет отдалён.
Векторные базы данных можно использовать в очень разных ситуациях. Вот несколько примеров:
По сути, всякий раз, когда вам нужно найти элементы на основе сходства или контекста, это можно сделать с помощью векторной базы данных.
В общем виде схема работы векторных баз данных выглядит так:
На первом этапе вы преобразуете данные (текст, изображения и так далее) в векторы, используя подходящую модель вроде OpenAI [13] или Cohere [14], либо библиотеку вроде SentenceTransformers [15].
База данных будет сохранять векторы удобным для их последующего запроса способом. Зачастую это делается с помощью техники, называемой «приближенный поиск ближайших соседей» (approximate nearest neighbors, ANN), чтобы БД не приходилось сравнивать между собой все векторы в датасете.
Можно представить этот механизм в виде гигантской карты, на которой, чем ближе находятся две точки, тем больше между ними сходство. База данных делит такие карты на области, чтобы быстро находить точки, наиболее приближенные к конкретному запросу.
При выполнении запроса ваш ввод преобразуется в вектор, и база данных ищет область карты, к которой полученный вектор относится. Обнаружив искомую область, она сможет быстро найти векторы, находящиеся рядом с вашим.
Это очень упрощённое представление, но оно позволяет понять внутренний принцип работы векторных баз данных.
А теперь взглянем чуть уже. Если ваш датасет достаточно невелик, то поначалу векторную базу данных использовать не обязательно. Вы можете просто перебирать все имеющиеся векторы и вычислять показатель их сходства с запросом вручную.
В качестве примера я приведу скрипт Python, который ищет самые близкие к запросу векторы, используя коэффициент Отиаи:
import math
# Пример вектора запроса
QUERY_VECTOR = [0.2, 0.3, 0.8]
# Пример базы данных
VECTOR_DATABASE = [
[0.1, 0.2, 0.9],
[0.8, 0.7, 0.3],
[0.4, 0.1, 0.5]
]
def cosine_similarity(vec1, vec2):
dot_product = sum(a * b for a, b in zip(vec1, vec2))
magnitude1 = math.sqrt(sum(a * a for a in vec1))
magnitude2 = math.sqrt(sum(b * b for b in vec2))
return dot_product / (magnitude1 * magnitude2)
# Поиск самого близкого к запросу вектора
similarities = [cosine_similarity(QUERY_VECTOR, vec) for vec in VECTOR_DATABASE]
most_similar_index = max(range(len(similarities)), key=lambda i: similarities[i])
# Вывод самого близкого вектора
print(f"Most similar vector: {VECTOR_DATABASE[most_similar_index]}")
print(f"Similarity score: {similarities[most_similar_index]}")
Этот скрипт демонстрирует принцип работы механизма поиска векторов. На практике по мере роста набора данных вам потребуется более эффективный способ их поиска и сравнения. В этом случае подходит выделенная векторная база данных.
Далее речь пойдёт о том, как векторные базы данных измеряют сходство. Вот два популярных способа:
Но существует и много других метрик расстояния. Итоговый выбор будет зависеть от ваших данных и решаемой задачи.
Ниже я вкратце опишу типичную проблему векторных баз данных, называемую «проклятие размерности».
Когда вы работаете с векторами высокой размерности, бывает сложно эффективно реализовать их поиск и сравнение. Вдобавок к этому, вы можете сталкиваться с проблемами переобучения и шума.
Справиться с подобными сложностями можно при помощи техник уменьшения размерности, таких как метод главных компонент (principal component analysis, PCA [18]) или t-SNE [19]. Их применение позволит сократить число измерений, сохранив наиболее важную информацию.
К примеру, вы можете сократить 1000-мерный вектор до 100-мерного так:
from sklearn.decomposition import PCA
# Пример эмбеддингов с 1000 измерений.
vectors = [
[0.1, 0.2, ...],
[0.8, 0.7, ...],
[0.4, 0.1, ...]
]
# Сокращение векторов до 100 измерений.
pca = PCA(n_components=100)
reduced_vectors = pca.fit_transform(vectors)
print(reduced_vectors)
Это типичная техника, используемая в машинном обучении и анализе данных для упрощения их обработки. Есть и другие техники, которые в этой статье я разбирать не стану, но вам для изучения рекомендую: автокодировщик, отбор признаков и регуляризация.
Завершим же мы эту тему списком доступных для ознакомления векторных баз данных. Отмечу, что список этот далеко не исчерпывающий, но послужит хорошей отправной точкой:
Автор: Bright_Translate
Источник [28]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/python/404462
Ссылки в тексте:
[1] Начнём с основ — что такое вектор?: #anchorid1
[2] Что такое векторная база данных?: #anchorid2
[3] Примеры использования: #anchorid3
[4] Принцип работы векторных баз данных: #anchorid4
[5] Создание эмбеддингов: #anchorid5
[6] Индексация векторов: #anchorid6
[7] Векторный поиск: #anchorid7
[8] Простейший векторный поиск на чистом Python: #anchorid8
[9] Поиск сходств и метрики расстояния: #anchorid9
[10] Уменьшение размерности: #anchorid10
[11] Список векторных баз данных: #anchorid11
[12] здесь: https://huggingface.co/docs/transformers/model_doc/rag
[13] OpenAI: https://platform.openai.com/docs/guides/embeddings
[14] Cohere: https://cohere.com/embeddings
[15] SentenceTransformers: https://www.sbert.net/
[16] Евклидова метрика: https://en.wikipedia.org/wiki/Euclidean_distance
[17] Коэффициент Отиаи: https://en.wikipedia.org/wiki/Cosine_similarity
[18] principal component analysis, PCA: https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html
[19] t-SNE: https://scikit-learn.org/stable/modules/generated/sklearn.manifold.TSNE.html
[20] Qdrant: https://qdrant.com/
[21] pgvector: https://github.com/pgvector/pgvector
[22] sqlite-vec: https://github.com/asg017/sqlite-vec
[23] Pinecone: http://pinecone.io/
[24] Convex: https://docs.convex.dev/search/vector-search
[25] Faiss: https://faiss.ai/
[26] MeiliSearch: https://www.meilisearch.com/solutions/vector-search
[27] Chroma: https://www.trychroma.com/
[28] Источник: https://habr.com/ru/companies/ruvds/articles/863704/?utm_source=habrahabr&utm_medium=rss&utm_campaign=863704
Нажмите здесь для печати.