Выполнение векторного поиска по текстовым данным с использованием векторной базы данных

В последнее время вокруг ChatGPT и генеративного ИИ было много шума, поэтому я решил немного повозиться с API OpenAI. Во время экспериментов я обнаружил, что API-интерфейс OpenAI Embeddings великолепен, но ChatGPT как бы затмевает его.

Когда мы говорим о векторах в контексте ИИ, они используются для представления неструктурированных данных, таких как изображения или текст. Вы можете использовать векторы для задач машинного обучения, таких как классификация.

В этой статье я расскажу, как вы можете использовать API встраивания OpenAI для простого создания векторов и выполнения векторного поиска по текстовым данным с помощью векторной базы данных Weaviate с открытым исходным кодом. Давайте начнем!

Предпосылки

Если вы хотите следовать этому руководству, вам понадобится учетная запись разработчика OpenAI (вам нужен ключ API). Вам также понадобится докер, чтобы вы могли запускать Weaviate локально. Python версии 3.8 или более поздней версии должен подойти для этого руководства.

Вы можете найти полный код и данные для этой статьи здесь:



Шаг 1: Настройка Weaviate

В этом руководстве мы будем использовать версию Weaviate с открытым исходным кодом, которую мы можем запустить с помощью docker-compose.

Во-первых, вам нужно скачать файл YAML с помощью команды curl ниже:

curl -o docker-compose.yml "https://configuration.weaviate.io/v2/docker-compose/docker-compose.yml?modules=standalone&runtime=docker-compose&weaviate_version=v1.18.0"

По умолчанию Weaviate не сохраняет данные при локальном запуске. Мы хотим убедиться, что наши данные не будут потеряны даже после закрытия экземпляра базы данных, поэтому мы запустим экземпляр Weaviate с томом. Откройте файл docker-compse.yml и добавьте том, как показано ниже. Сохраните файл yml после изменений.

image: semitechnologies/weaviate:1.18.0
volumes:
  - /var/weaviate:/var/lib/weaviate

Затем просто запустите:

docker-compose up -d

Шаг 2: Установка пакета Python

Вам понадобятся следующие пакеты Python, установленные в вашей виртуальной среде Python:

pip install openai
pip install pandas
pip install weaviate-client

Шаг 3: Чтение текстового файла

Для этого урока я создал образец файла JSON, содержащий текст из учебника истории. Получить данные можно по этой ссылке.

Эта функция просто читает файл JSON и преобразует его во фрейм данных pandas. Есть только один столбец под названием «текст».

Шаг 4: Работа с вложениями OpenAI

Чтобы выполнить векторный поиск по нашим текстовым данным, нам сначала нужно преобразовать наш текст в векторное представление. Вот где API встраивания OpenAI пригодится. Мы создадим новый столбец в нашем фрейме данных под названием «встраивание», который будет содержать векторное представление текста в этой строке.

Примечание. OpenAI имеет ограничитель скорости на своих конечных точках API. API встраивания имеет ограничение в 50 запросов в минуту. Если вы превысите этот предел, вы получите сообщение об ошибке, и вам придется подождать минуту, прежде чем вы сможете отправить больше запросов.

Шаг 5: Создайте схему Weaviate

Weaviate хранит данные в виде объектов JSON внутри коллекции, которую они называют «классами». Weaviate может хранить не только сам объект JSON, но и векторное представление этого объекта JSON.

Например, если ваш объект JSON таков:

{
    "name": "Alice Munro",
    "age": 91,
    "born": "1931-07-10T00:00:00.0Z",
    "wonNobelPrize": true,
    "description": "Alice Ann Munro is a Canadian short story writer who won the Nobel Prize in Literature in 2013. Munro's work has been described as revolutionizing the architecture of short stories, especially in its tendency to move forward and backward in time."
}

Weaviate сохранит это:

{
    "id": "dedd462a-23c8-32d0-9412-6fcf9c1e8149",
    "class": "Author",
    "properties": {
        "name": "Alice Munro",
        "age": 91,
        "born": "1931-07-10T00:00:00.0Z",
        "wonNobelPrize": true,
        "description": "Alice Ann Munro is a Canadian short story writer who won the Nobel Prize in Literature in 2013. Munro's work has been described as revolutionizing the architecture of short stories, especially in its tendency to move forward and backward in time."
    },
    "vector": [
        -0.16147631,
        -0.065765485,
        -0.06546908
    ]
}

Данные, которые мы будем хранить, будут выглядеть так:

{
    "id": "some-random-id",
    "class": "HistoryText",
    "properties": {
        "content": "History text sentence or paragraph"
    },
    "vector": [
        0.7477373,
        -94720943,
        0.1234567
    ]
}

Нам нужно сообщить Weaviate, как выглядят наши данные, предоставив схему. Эта база данных векторов имеет множество функций и может автоматически векторизовать данные. Однако мы хотим предоставить собственные вложения OpenAI. В этом случае важно, чтобы мы установили для «векторизатора» значение «нет», иначе Weaviate будет использовать один из своих векторизаторов для создания встраивания.

Шаг 6: Добавление данных в нашу базу данных векторов

Клиент Weaviate Python предоставляет различные способы добавления данных в базу данных. На момент написания этой статьи одним из новых способов добавления данных является использование автоматических пакетов. Weaviate автоматически создаст наши объекты данных, когда будет достигнут указанный размер пакета.

Шаг 7: Запрос данных

Наша цель состояла в том, чтобы найти тексты, похожие на наш входной текст. Текст в нашей векторной базе данных хранится в виде вложений. Чтобы выполнить векторный поиск, наш входной текст также необходимо преобразовать во вложение. Второй параметр этой функции «k» — это количество объектов, которые мы хотим вернуть, ближайших к нашему вводу.

Мы хотим найти ближайшие векторы к нашему входному вектору, поэтому мы связываем функцию .with_near_vector(). Внутри функции get мы запрашиваем как «контент», который является нашим необработанным текстом, так и «_additional {certainty}». «Определенность», по сути, говорит нам, насколько близок возвращаемый вектор к нашему входному вектору.

Шаг 8: Запускаем все вместе!

Если вы поместите все вышеперечисленные функции в файл Python, все, что вам нужно сделать, это запустить их в этом порядке, чтобы увидеть результат:

Предостережение: конечная точка встраивания OpenAI является платной. Это может стоить всего несколько центов, но, тем не менее, вы не должны вызывать их API без необходимости. Если вы недавно создали учетную запись разработчика OpenAI, у вас будет 18 долларов бесплатных кредитов, чего более чем достаточно для экспериментов. Функция «generate_data_embeddings» вызывает API, поэтому будьте осторожны при ее использовании. Вам нужно будет запустить строки 2–5 только один раз, чтобы проанализировать данные и добавить их в базу данных векторов. Как только вы заполните базу данных, ЗАКОММЕНТИРУЙТЕ эти строки!

Запуск приведенного выше кода с input_text как «американское расширение» привел к следующему:

Then, during the 1840s, many citizens embraced an ideology of expansion and proclaimed a God-given duty to extend American republicanism to the Pacific Ocean.
As expansionists developed continental ambitions, the term Manifest Destiny captured those dreams. John L. O’Sullivan, editor of the Democratic Review, coined the phrase in 1845: “Our manifest destiny is to over- spread the continent allotted by Providence for the free development of our yearly multiplying millions.” 
Fertile land seemed abundant, and grain exports to Europe and the West Indies financed the colonies’ rapid settlement.

Изменение input_text на «мировая война» дало следующее:

To fight the war, the government mobilized tens of millions of soldiers, civilians, and workers— coordinated on a scale unprecedented in U.S. history. During World War II, the armed forces of the United States enlisted more than fifteen million men and women.
For Hitler, this pact was crucial, as it meant that Germany would not have to wage a two- front war against Britain and France in the west and the Soviet Union in the east. On September 1, 1939, Hitler launched a blitzkrieg against Poland. Two days later, Britain and France declared war on Germany. World War II had officially begun.
Encouraged by the weak worldwide response to the invasions of China, Ethiopia, and the Rhineland, and emboldened by British and French neutrality during the Spanish Civil War, Hitler grew more aggressive in 1938.

Вы можете поиграть с входным текстом и параметром k_vectors, чтобы увидеть, какие результаты вы можете получить.

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

docker-compose down

Обратите внимание, что при закрытии экземпляра базы данных наши векторные данные внутри базы данных не теряются. Эти данные останутся, если вы перезапустите экземпляр базы данных. Поэтому, если вы перезапустите базу данных после ее закрытия, вам не нужно повторно заполнять базу данных векторами.

Что ж, это все для этого урока. Надеюсь, вы нашли что-то ценное в этой статье.

Мир вне.