Как использовать базу данных векторов для поиска совпадений между пользователями?

У меня есть приложение, в котором пользователи могут зарегистрироваться и заполнить профиль. Этот профиль состоит из 16 вопросов, на которые можно ответить с помощью слайдера. Каждый «ответ» на вопрос может иметь значение от -3 до 3 (или от 0 до 7).

Пользователь должен иметь возможность находить похожих пользователей по результатам вопросов. Я думал, что использование векторной базы данных, такой как Weaviate или Pinecone, могло бы помочь мне найти эти совпадения по запросу, но, к сожалению, если я провожу простые эксперименты, сходство в основном равно нулю.

Вот что я делаю в Сосновой шишке:

Индексирование:

      const index = await initIndex()

const vectors = [
  {
    id: '1',
    values: [-3, -3, -3, -3, -3]
  },
  {
    id: '2',
    values: [-1, -1, -1, -1, -1]
  },
  {
    id: '3',
    values: [0, 0, 0, 0, 0]
  },
  {
    id: '4',
    values: [1, 1, 1, 1, 1]
  },
  {
    id: '5',
    values: [3, 3, 3, 3, 3]
  }
] as Vector[]

const upsertRequest: UpsertRequest = {
  vectors
}

await index.upsert({
  upsertRequest,
})

Идет поиск:

      const index = await initIndex()

const queryRequest = {
  topK: 10,
  vector: [0, 0, 0, 0, 0],
  includeValues: true
}

const queryResponse = await index.query({ queryRequest })

Результат:

      {
    "queryResponse": {
        "results": [],
        "matches": [
            {
                "id": "2",
                "score": 0,
                "values": [
                    -1,
                    -1,
                    -1,
                    -1,
                    -1
                ]
            },
            {
                "id": "1",
                "score": 0,
                "values": [
                    -3,
                    -3,
                    -3,
                    -3,
                    -3
                ]
            },
            {
                "id": "3",
                "score": 0,
                "values": [
                    0,
                    0,
                    0,
                    0,
                    0
                ]
            },
            {
                "id": "5",
                "score": 0,
                "values": [
                    3,
                    3,
                    3,
                    3,
                    3
                ]
            },
            {
                "id": "4",
                "score": 0,
                "values": [
                    1,
                    1,
                    1,
                    1,
                    1
                ]
            }
        ],
        "namespace": ""
    }
}

Почему счет всегда 0? Разве это не должно быть 0,5, исходя из векторов в моей базе данных?

1 ответ

Так что потребовалось немного усилий, но мне действительно удалось это воспроизвести. Я создал индекс на основе COSINE и добавил данные, которые вы упомянули выше. Затем я запросил вектор, соответствующий идентификатору № 3:

      {'id': '1', 'score': 0.0, 'values': [-3.0, -3.0, -3.0, -3.0, -3.0]},
{'id': '5', 'score': 0.0, 'values': [3.0, 3.0, 3.0, 3.0, 3.0]},
{'id': '3', 'score': 0.0, 'values': [0.0, 0.0, 0.0, 0.0, 0.0]},
{'id': '2', 'score': 0.0, 'values': [-1.0, -1.0, -1.0, -1.0, -1.0]},
{'id': '4', 'score': 0.0, 'values': [1.0, 1.0, 1.0, 1.0, 1.0]}],
 'namespace': ''}

Будучи сотрудником DataStax, я попробовал это на Astra DB , следующее:

      CREATE TABLE users (
    user_id INT PRIMARY KEY,
    survey_vector VECTOR<Float,5>);

CREATE CUSTOM INDEX users ON users(survey_vector) USING 'StorageAttachedIndex';

INSERT INTO users (user_id, survey_vector) VALUES (1,[-3, -3, -3, -3, -3]);
INSERT INTO users (user_id, survey_vector) VALUES (2,[-1, -1, -1, -1, -1]);
INSERT INTO users (user_id, survey_vector) VALUES (3,[0, 0, 0, 0, 0]);
INSERT INTO users (user_id, survey_vector) VALUES (4,[1, 1, 1, 1, 1]);
INSERT INTO users (user_id, survey_vector) VALUES (5,[3, 3, 3, 3, 3]);

Это не удалось на, где.

WriteFailure: Ошибка сервера: код =1500 [Не удалось выполнить запись реплики] message="Операция не удалась - получено 0 ответов и 3 ошибки: НЕИЗВЕСТНО от 16.10.22.38:7000, НЕИЗВЕСТНО от 16.10.12.4:7000, НЕИЗВЕСТНО от 10.16.8.4:7000" info = {'consistency': 'LOCAL_QUORUM', 'required_responses': 2, 'received_responses': 0, 'failures': 3}

Astra DB выдала аналогичную ошибку, когда я попробовал выполнить запрос ANN.

ТЛ;ДР;

Вы не можете запустить векторный поиск на основе косинуса с вектором, полным нулей (также известным как нулевой вектор), поскольку это приводит к ошибке деления на ноль.Astra DB правильно выдала ошибку (ошибка согласованности, но тем не менее ошибка).

Сосновая шишка это скрывает. Не уверен, что он терпит неудачу, но он все равно возвращает вам результаты. Хотя со счетом он ничего не может поделать, поэтому все они нули.

В любом случае, поиск по нулевому вектору работает с евклидовым индексом/поиском. Восстановите свой индекс как «EUCLIDEAN», потому что с ним вы можете иметь нулевой вектор:

Сосновая шишка с евклидовым индексом:

      {'matches': [
    {'id': '3', 'score': 0.0, 'values': [0.0, 0.0, 0.0, 0.0, 0.0]},
    {'id': '4', 'score': 5.0, 'values': [1.0, 1.0, 1.0, 1.0, 1.0]},
    {'id': '2', 'score': 5.0, 'values': [-1.0, -1.0, -1.0, -1.0, -1.0]},
    {'id': '1', 'score': 45.0,'values': [-3.0, -3.0, -3.0, -3.0, -3.0]},
    {'id': '5', 'score': 45.0,'values': [3.0, 3.0, 3.0, 3.0, 3.0]}],
     'namespace': ''}

Астра БД с евклидовым индексом:

      > CREATE CUSTOM INDEX users_survey_vector_idx ON
  stackoverflow.users (survey_vector)
  USING 'StorageAttachedIndex'
  WITH OPTIONS = {'similarity_function': 'EUCLIDEAN'};

> SELECT user_id, similarity_euclidean(survey_vector,[0,0,0,0,0])
  AS similarity FROM users
  ORDER BY survey_vector
  ANN OF [0,0,0,0,0] LIMIT 5;

 user_id | similarity | survey_vector
---------+------------+----------------------
       3 |          1 |      [0, 0, 0, 0, 0]
       2 |   0.166667 | [-1, -1, -1, -1, -1]
       4 |   0.166667 |      [1, 1, 1, 1, 1]
       5 |   0.021739 |      [3, 3, 3, 3, 3]
       1 |   0.021739 | [-3, -3, -3, -3, -3]

(5 rows)

Редактировать для скалярного продукта

Почему счет всегда 0? Разве это не должно быть 0,5, исходя из векторов в моей базе данных?

Внес изменения, чтобы охватить мои базы, на случай, если вы изначально использовали индекс на основе скалярного произведения. При запуске с Pinecone я получаю тот же результат, что и приведенный выше вывод с индексом на основе косинуса; тот же порядок, баллы = ноль.

Однако с Astra DB:

      > CREATE CUSTOM INDEX users_survey_vector_idx ON
  stackoverflow.users (survey_vector)
  USING 'StorageAttachedIndex'
  WITH OPTIONS = {'similarity_function': 'DOT_PRODUCT'};

> SELECT user_id, similarity_dot_product(survey_vector,[0,0,0,0,0])
  AS similarity FROM users
  ORDER BY survey_vector
  ANN OF [0,0,0,0,0] LIMIT 5;

 user_id | similarity | survey_vector
---------+------------+----------------------
       5 |        0.5 |      [3, 3, 3, 3, 3]
       1 |        0.5 | [-3, -3, -3, -3, -3]
       2 |        0.5 | [-1, -1, -1, -1, -1]
       4 |        0.5 |      [1, 1, 1, 1, 1]
       3 |        0.5 |      [0, 0, 0, 0, 0]

(5 rows)

Я не понимаю, почему Pinecone не вычисляет баллы для скалярного произведения. Но Astra DB, похоже, справилась с этой задачей, получив оценки, соответствующие вашим ожиданиям.

Другие вопросы по тегам