Вы когда-нибудь задумывались, как эффективно тестировать данные и конвейеры данных, не настраивая комплексное решение для обеспечения качества данных корпоративного уровня?

Python предоставляет множество отличных пакетов для кода модульного тестирования. При этом вы можете проверить, работает ли код вашего конвейера. Вы, безусловно, используете фикстуры, чтобы изолировать модульные тесты и не делать модульные тесты зависимыми от изменения данных. Но как вы можете проверить, влияют ли ваши измененные преобразования данных на результат конвейера данных, ожидаемый от вашей модели машинного обучения?

Некоторое время назад я написал эту статью в блоге на Medium о ценности пакета Python с открытым исходным кодом Great Expectations.

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

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

Нам нужно быстрое исправление, чтобы эта проблема не повторилась снова. Поскольку мы были ребятами из Python, мы хотели дать шанс компании Great Expectations. Настройка минимального окружения была произведена за несколько дней. И мы не были разочарованы.

Сейчас у меня были похожие настройки, но я работаю с клиентами, настраивающими свои архитектуры машинного обучения в Azure. Из своего более раннего проекта я знал, что Great Expectations необходимо установить и настроить с помощью yaml-файла, а результирующие артефакты (наборы ожиданий, запуски проверки, DataDocs) также хранятся в файловой системе. Мне показалось немного неуклюжим настраивать облачные сервисы, такие как Azure Databricks и Azure Machine Learning, и я потратил некоторое время, чтобы изучить, как этого можно достичь в размещенных средах.

Замечательной особенностью Great Expectations являются документы DataDocs и возможности, которые эта функция открывает для команд.

DataDocs - это не только документация по используемым данным или отображение результатов проверки данных, но также их можно использовать в качестве контрактов на данные. Эксперты в предметной области, специалисты по обработке данных и инженеры по обработке данных могут работать на одной странице, чтобы убедиться, что данные полностью понятны и обеспечивается их качество.

На мой взгляд, это особенно интересно в конвейере MLOps, где помимо тестирования самого кода вам нужен код конвейера, дрейф данных и проверка данных, которые вы потребляете из других источников данных или поставщиков.

Хорошо, но прежде чем мы перейдем к мелочам, я хотел бы рассказать вам, как я использую этот пакет! Я рассматриваю «Большие надежды» как основу и выбираю то, что считаю полезным. Поэтому, когда я работаю с Spark, я настраиваю источники данных только для предоставления информации метаданных, которую я могу использовать позже. Обычно я загружаю пакет данных вручную и помещаю Spark DataFrame в batch_kwargs (или… в новый API).

💻 Найдите код в конце статьи в блоге.

Настроить проект «Большие надежды» можно двумя способами. Выберите один из вариантов, если вы работаете в системе, в которой у вас есть готовая файловая система. Начните с инициализации с большими ожиданиями, чтобы создать основу конфигурации и соответствующим образом сконфигурировать свой DataContext.

Когда вы работаете в размещенной системе, такой как PaaS, в облаке, у вас не всегда может быть доступный интерфейс командной строки или файловая система, в которой вы легко можете постоянно хранить папку. Используя Azure Databricks или машинное обучение Azure, теоретически у вас есть доступ к интерфейсу командной строки или файловым системам (например, DBFS в ADB или Linux в вычислительных экземплярах AML). Но это не кажется лучшим вариантом, потому что в облаке вам лучше использовать другие варианты, например, иметь более центральное место для хранения вашей конфигурации и артефактов.

Я начал с просмотра вебинара на YouTube и нашел много полезного материала в документации (как начать без файла YML, как запустить на Databricks).

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

Я использовал Azure Key Vault backed scope для управления своими секретами. Это довольно просто сделать в сочетании с Azure Databricks или AzureML. Так что это одно из преимуществ, которое пригодится мне при использовании конфигурации в качестве кода.

В случае использования yaml-файла для настройки DataContext вы можете либо использовать секретный конфигурационный файл, который не зарегистрирован в репозитории git, либо использовать тот же подход с использованием Azure Key Vault.

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

Я хочу хранить все свои артефакты (ожидания, проверки) в хранилище BLOB-объектов Azure.

Документы DataDocs также будут отправлены в хранилище BLOB-объектов Azure, но мы будем использовать контейнер \ $ web для размещения статического веб-сайта.

Создание пакета данных (Spark DataFrame) вручную…

… и здесь мы идем. Давайте создадим некоторые ожидания. Вы можете проверить документацию или просто попробовать. Это в значительной степени говорит само за себя. Итак, мы просто переходим к следующему этапу. После сохранения набора ожиданий мы можем запустить проверку или создать контрольную точку. Мы будем использовать run_validation_operator для проверки пакета данных на соответствие пакету данных. Он выполнит прогон проверки, отправит полученные артефакты в хранилища и обновит DataDocs.

Наконец, просмотрите DataDocs и посмотрите результаты проверки.

И последнее замечание: Cookiecutter очень помогает, когда у вас есть много источников данных и продуманный конвейер данных, где вам нужно проверять каждый отдельный шаг преобразования.

В следующей статье блога мы рассмотрим Delta Live Tables и увидим, как эта новая (предварительная) функция Databricks может быть полезна для конвейерного тестирования.