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

Согласно опросу 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 можно решить множеством способов:

  1. При помощи 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.
  2. При помощи предыдущего Expectation, но с параметром вычисления. Подробнее об этом можно узнать из официальной документации.
  3. Сравнением двух таблиц при помощи UserConfigurableProfiler. О том, как это сделать, можно из официальной документации.
  4. Наконец, если вы хотите проверить целостность Change Data Capture, необходимо использовать Data Quality Gate. DQG позволяет за один щелчок развёртывать систему качества данных с GX в AWS. О нашем примере использования этого решения можно прочитать в техническом блоге AWS.

Заключение


В этой статье объясняется, как реализовать размерности качества данных при помощи библиотеки Great Expectations. Используя Expectation для валидации данных, можно гарантировать их соответствие требованиям множества размерностей качества данных, в том числе полноте, валидности, согласованности, уникальности и многим другим. Я рассмотрел лишь несколько примеров, но есть и множество других Expectation, которые можно использовать для собственных потребностей бизнеса.

Совершенствуя систему обеспечения качества данных, вы можете избежать дорогостоящих багов, повысить точность и надёжность данных и выводов на их основе.

Комментарии (0)