Качество данных играет критически важную роль в любом процессе управления данными. Организации используют данные для принятия решений и улучшения различных бизнес-показателей. Однако если данные усеяны неточностями, ошибками или несогласованностями, то они могут нанести больше вреда, чем пользы.
Согласно опросу Gartner за 2020 год, в среднем потери из-за низкого качества данных составляют примерно $12,8 миллиона за год. Как сообщается в последнем отчёте State of Data Quality, задержки продакшена (задержки с выпуском продукта) — характерный симптом низкого качества данных. Высококачественные и безошибочные данные повышают надёжность и верность полученных из них выводов.
Для повышения качества данных необходима система его оценки. В достижении этой цели вам помогут размерности качества данных. Размерности позволяют измерять покрытие и выявлять компоненты, требующие тестирования качества данных.
В этой статье рассматриваются шесть размерностей качества данных: полнота, согласованность, целостность, вневременная актуальность, уникальность и валидность. Определив их, вы сможете обеспечить исчерпывающее понимание качества данных и выявить аспекты, требующие совершенствования. И здесь нам на помощь приходит Great Expectation (GX).
Great Expectations
Great Expectations (GX) — это опенсорсный инструмент на основе Python для управления качеством данных. Он предоставляет командам дата-саентистов возможность профилировать и тестировать данные, а также составлять по ним отчёты. Этот инструмент имеет удобный интерфейс командной строки (CLI), что упрощает подготовку новых тестов и модификацию готовых отчётов.
Great Expectations может быть интегрирован с широким спектром инструментов Extract, Transform and Load (ETL), например, с Airflow и базами данных. Исчерпывающий список интеграций и официальную документацию можно найти на веб-сайте Great Expectations.
В репозитории GX есть множество expectation. В этой статье мы покажем, как использовать одно expectation для реализации размерностей качества данных при помощи GX.
Данные
Прежде чем начать реализацию, нам нужно больше узнать о данных, которые мы будем использовать для демонстрации работы размерностей.
Допустим, мне нужно создать анализ киоска данных (Data Mart), чтобы узнать, сколько заказов отдел продаж принял для каждого региона за последние три года.
У нас есть сырые данные заказов:
ID заказа | Дата заказа | Продажи | Имя клиента | |
5955 | 2021-05-27 | 314.6217 | Ann Chong | |
21870 | 2022-08-28 | 996.9088 | Doug Bickford | |
3 | 2019-03-04 | 6025.7924 | Beth Paige | |
19162 | 2021-04-11 | 403.5025 | Carlos Soltero | |
12008 | 2022-11-29 | 4863.0199 | Fred Wasserman | |
18630 | 201-09-16 | 4.9900 | Neola Schneider | |
18378 | 2022-01-03 | 1566.3223 | Doug Bickford | |
15149 | 2020-03-12 | 1212.7117 | Michelle Lonsdale | |
9829 | 2022-06-27 | 695.7497 | Eugene Barchas | |
5188 | 2020-08-15 | 16426.6293 | Doug Bickford |
И сырые данные клиентов:
Имя клиента | Провинция | Регион | Клиентский сегмент |
Andrew Allen | Saskatchewan | Nunavut | Потребитель |
Trudy Brown | Nova Scotia | Nunavut | Корпоративный |
Dionis Lloyd | Nunavut | West | Корпоративный |
Cynthia Arntzen | Northwest Territories | Atlantic | Корпоративный |
Brooke Gillingham | Ontario | Ontario | Мелкий бизнес |
Alejandro Savely | Nova Scotia | Nunavut | Потребитель |
Harold Pawlan | Newfoundland | Prairie | Корпоративный |
Peter Fuller | Manitoba | Quebec | Потребитель |
Ionia McGrath | Quebec | Quebec | Домашний офис |
Fred Wasserman | Ontario | Atlantic | Потребитель |
Для проведения анализа киоска данных я использую таблицу на основании имени клиента (customer_regional_sales):
Реализация проверок качества данных в Great Expectations
В целях этой статьи использовался следующий подход:
- Данные хранятся в трёх файлах CSV
- Для чтения CSV используется Pandas
- Используется метод Great Expectations из from_pandas для преобразования кадра данных Pandas.
import great_expectations as gx
import pandas as pd
df = pd.read_csv('./data/customer_regional_sales.csv',dtype={'Order ID': 'Int32'})
df_ge = gx.from_pandas(df)
Это хорошая демонстрация Expectation для каждой размерности.
Great Expectations оценивает данные при помощи Expectation. Expectation — это конструкции, выражаемые в декларативной форме, которую может оценивать компьютер, но в то же время имеющей значение для интерпретации человеком. В GX есть 309 Expectation и существует возможность реализации собственных expectation. Все expectation перечислены здесь.
Полнота
Полнота (Completeness) — это размерность качества данных, являющаяся показателем того, все ли ожидаемые данные присутствуют в датасете. Иными словами, полнота показывает, есть ли все нужные точки или значения в датасете, и если это не так, какая их часть отсутствует. Также важно проверять, существует ли вообще столбец.
В Great Expectations есть специальное Expectation для проверки полноты:
expect_column_values_to_not_be_null
— ожидание того, что значения столбца ненулевые.Чтобы значения считались исключениями, они должны быть чётко null или отсутствовать. Например, NULL в PostgreSQL или np.NaN в Pandas. Если строка просто пустая, то этого недостаточно, чтобы считать её null, если только она не преобразована в нулевой тип.
Это Expectation можно применить для нашего случая:
df_ge.expect_column_values_to_not_be_null(
column = 'Customer Name',
meta = {
"dimension": "Completeness"
}
)
Уникальность
Уникальность (Uniqueness) — это размерность качества данных, связанная со степенью того, насколько каждая запись в датасете представляет уникальную и отдельную сущность или событие. Она показывает, нет ли в данных дубликатов или избыточных записей.
expect_column_values_to_be_unique
— ожидание того, что значение каждого столбца уникально.df_ge.expect_column_values_to_be_unique(
column = 'Order ID',
meta = {
"dimension": 'Uniqueness'
}
)
Представленные ниже размерности требуют больше бизнес-контекста.
Вневременная актуальность
Вневременная актуальность (Timelessness) — это размерность качества данных, определяющая релевантность и точность данных с течением времени. Она определяет своевременность данных. Например, мне нужно, чтобы в датасете были записи за последние четыре года. Если в датасете есть более старые записи, то я должен получить ошибку.
Для тестирования вневременной актуальности я использую следующее Expectation:
expect_column_values_to_be_between
Оно подходит, потому что я могу парсить данные и сравнивать их.
import datetime
# Получаем текущую дату, я использую начало текущего года.
now = datetime.datetime(2023, 1, 1)
# Определяем столбец для валидации и ожидаемую минимальную дату
min_date = now - datetime.timedelta(days=365*4)
# Создаём expectation
df_ge.expect_column_values_to_be_between(
"Order Date"
min_value = min_date,
parse_strings_as_datetimes=True,
meta = {
"dimension": 'Timelessness'
}
)
Валидность
Валидность (Validity) — это размерность качества данных, определяющая точность данных и их соответствие ожидаемому формату или структуре. Так как невалидные данные могут нарушить обучение алгоритмов ИИ на датасете, организациям следует установить методические бизнес-правила оценки валидности данных.
Например, в США даты рождения обычно имеют формат «месяц, день, год», а номера социального страхования состоят из десяти цифр. Телефонные номера в США состоят из трёхзначного кода области. Поэтому может быть сложнее определить конкретный формат даты рождения.
В моём датасете столбец данных «Order Date» имеет формат ГГГГ-ММ-ДД, поэтому я должен проверить его для всех значений в столбце.
В GX есть Expectation для даты —
expect_column_values_to_be_valid_date
. Это Expectation основано на методе parse из dateutil.Если нужно проверить длину строки, то следует использовать Expectation
expect_column_value_lengths_to_equal
.Универсальная практика заключается в использовании regex для моего формата данных:
df_ge.expect_column_values_to_match_regex(
column = 'Order Date',
regex = '\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])',
meta = {
"dimension": "Validity"
}
)
На мой взгляд, большинство Expectations в репозитории GX можно использовать для проверки размерности «валидность».
Согласованность
Согласованность (Consistency) — это размерность качества данных, обозначающая степень равномерности и точности данных по всему датасету. Она является показателем логической когерентности данных и их соответствия ожидаемым значениям, диапазонам и правилам. Для оценки согласованности я обычно сравниваю значения данных с известными стандартами или значениями, и проверяю наличие расхождений или отклонений. Кроме того, я использую статические методы для выявления и корректирования несогласованностей в данных.
В качестве примера для своего датасета я создал правило, по которому столбец «Sales», обозначающий прибыль от каждого заказа, не может быть отрицательным. Кроме того, я знаю, что максимальная сумма равна 25000.
В Great Expectations есть подходящее Expectation
expect_column_values_to_be_between
.df_ge.expect_column_values_to_be_between(
column = 'Sales',
min_value = 0,
max_value = 25000,
meta = {
"dimension": 'Consistency'
}
)
Кроме того, можно использовать expectation со статистическими проверками:
expect_column_mean_to_be_between
expect_column_stdev_to_be_between
Целостность
Целостность (Integrity) гарантирует корректность и валидность данных, особенно когда эта метрика используется в нескольких местах. Она заключается в проверке точности и согласованности данных с точки зрения связей между разными датасетами, и в отслеживании того, что они соответствуют установленным бизнесом правилам.
У меня есть два источника и один датасет, связанный с этими двумя датасетами. Это означает, что мне нужно проверять, не утеряны данные после выполнения преобразований. Самый важный для меня параметр — это Order ID. Мне нужно быть уверенным, что все заказы размещены в customer_regional_sales
Эту задачу в Great Expectations можно решить множеством способов:
- При помощи Expectation
expect_column_values_to_be_in_set
. Оно ожидает, что каждое значение столбца находится в заданном множестве. В данном случае мне нужно сравнить Order ID из датасета «orders» с Order ID в customer_regional_sales:df_expectations = pd.read_csv('./data/orders.csv', usecols=['Order ID'], squeeze = True ) df_ge.expect_column_values_to_be_in_set( "Order ID", value_set = df_expectations.tolist(), meta = { "dimension": 'Integrity' } )
Это Expectation будет ошибочным, если customer_regional_sales.order_id столбца не равно orders.order_id. - При помощи предыдущего Expectation, но с параметром вычисления. Подробнее об этом можно узнать из официальной документации.
- Сравнением двух таблиц при помощи UserConfigurableProfiler. О том, как это сделать, можно из официальной документации.
- Наконец, если вы хотите проверить целостность Change Data Capture, необходимо использовать Data Quality Gate. DQG позволяет за один щелчок развёртывать систему качества данных с GX в AWS. О нашем примере использования этого решения можно прочитать в техническом блоге AWS.
Заключение
В этой статье объясняется, как реализовать размерности качества данных при помощи библиотеки Great Expectations. Используя Expectation для валидации данных, можно гарантировать их соответствие требованиям множества размерностей качества данных, в том числе полноте, валидности, согласованности, уникальности и многим другим. Я рассмотрел лишь несколько примеров, но есть и множество других Expectation, которые можно использовать для собственных потребностей бизнеса.
Совершенствуя систему обеспечения качества данных, вы можете избежать дорогостоящих багов, повысить точность и надёжность данных и выводов на их основе.