Йорг Шницбауэр и Лукаш Боликовски

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

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

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

А в 2018 году, если вы не можете регулярно использовать расширенную аналитику, чтобы оказать финансовое влияние на свой бизнес, вы можете быть уверены, что это делают ваши конкуренты.

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

Ориентация на данные

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

Мы обнаружили, что проекты в области Data Science часто больше управляются данными, чем алгоритмами. Следовательно, обычно полезно отразить эту ориентированность на данные в нашей структуре кода. Алгоритмы важны, но не менее важны попытки определить природу (или, что еще лучше, схему) входных, выходных и промежуточных данных. Перед разработкой алгоритмов важно разбить поток обработки данных на управляемые блоки и определить API-интерфейсы между ними.

Хотя схема входных данных часто известна и фиксирована, необходимо определить промежуточные и выходные данные. Даже при четком видении бизнес-проблемы очень важно в самом начале проекта детально определить выходные данные (конкретную цель проекта). Это помогает не только структурировать кодовую базу, но также гарантирует, что те, кто работает над проектом, управляемым данными, будут иметь еще более четкое представление о бизнес-проблеме. Опыт научил нас, что при предложении и тестировании выходных данных всегда полезно на ранней стадии взаимодействовать с заинтересованными сторонами.

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

Разделяй и властвуй

После определения схемы выходных данных следующим шагом является размышление о том, как мы перейдем от A (вход) к B (выход). Другими словами, определение промежуточных данных. Это может показаться сложной задачей, но ее можно сделать более управляемой, разбив поток данных на части, установив иерархическое представление. Возможно, мы еще не знаем, как написать алгоритм, который доставит нас от A к B, но, возможно, это поможет создать промежуточный набор данных по пути, который мы назовем C. Или если переход от A к C все еще не позволяет нам писать понятный фрагмент кода, мы добавляем еще один промежуточный набор данных: D (таким образом, A - ›D -› C - ›B). Конечно, реальный поток данных может иметь ответвления и более сложные зависимости. Но если повторить этот процесс добавления промежуточных наборов данных, появится четкое представление об алгоритмах, которые помогут нам преобразовать один набор данных в другой. Повторение этого процесса будет означать достижение состояния, в котором шаги между промежуточными наборами данных настолько малы, что любой, кто участвует в проекте, может легко определить задачи, которые преобразуют один промежуточный набор данных в другой. В этих «атомарных» задачах теперь вступают в дело наш код и алгоритмы. Если сложно описать задачу преобразования данных простым предложением, вероятно, неплохо было бы разбить ее на более мелкие детали.

Зависимости как направленный ациклический граф

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

Наборы данных и задачи - это узлы графа. Связи между ними представляют собой входные и выходные соединения. На рисунке 1 ниже ссылки, указывающие из набора данных (представленные кружками) на задачу (представленную квадратами), показывают входные данные задачи. Ссылки, указывающие от задачи к набору данных, показывают выходные данные задачи. Если мы проделали правильную работу, мы не должны найти циклических зависимостей внутри графа - отсюда и термин «ациклический».

РИСУНОК ПЕРВЫЙ

Преимущества

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

Это понимание дает огромные преимущества:

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

● Командное сотрудничество простое и управляемое. Когда мы запускаем проект, мы определяем DAG и распределяем код каждой задачи (рабочих пакетов) среди членов команды. Если нам нужно одновременно обновить бизнес-логику нескольких задач, члены группы могут работать с разными разделами DAG одновременно с минимальной координацией, потому что они могут полагаться на схему данных, входящую в задачу, над которой они работают. Все это работает - до тех пор, пока рабочие пакеты (задачи, назначенные каждому члену команды) не приводят к конфликтной реструктуризации DAG. Даже в этом случае при необходимости реструктуризация группы DAG все еще возможна при условии адекватной координации между членами команды.

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

● Вместо того, чтобы запускать весь рабочий процесс каждый раз (что может занять много времени), мы можем выбрать быстрый запуск только нужных нам разделов. Это особенно полезно при разработке новой логики для конкретной задачи, поскольку мы можем вычислить необходимые наборы данных один раз и «заморозить» их в качестве входных данных для раздела, над которым мы работаем.

● Повышенная прозрачность, особенно для нетехнических заинтересованных сторон. Необязательно быть разработчиком программного обеспечения или специалистом по обработке данных, чтобы понимать используемый конвейер и алгоритмы. В GAMMA специалисты по обработке данных ежедневно работают бок о бок с консультантами по менеджменту и другими специалистами широкого профиля. Разделив код на элементарные задачи с четко определенными входами и выходами, легче сообщить о масштабах нашей работы специалистам, не занимающимся данными. Более того, когда, например, промежуточные файлы находятся в формате CSV, наши коллеги могут проверить их в Excel и получить более глубокое понимание модели - или помочь отладить проблемы, не читая ни единой строчки кода!

Полезные фреймворки

Ряд первопроходцев взяли на себя обременительные усилия, связанные с ручным кодированием конвейеров, путем создания сред программирования. Различные фреймворки стали зрелыми, особенно в средах Извлечение, преобразование, загрузка (ETL). В частности, мы хотим обратить ваше внимание на два очень популярных фреймворка, Luigi и Airflow, а также бессовестно подставить две более легкие альтернативы собственного творчества: elkhound и dalymi.

Флагманы: Луиджи и Airflow

Группы DAG написаны на Python как в Luigi, так и в Airflow, но задачи могут быть не связанными с Python операциями, такими как сценарии bash, запросы Hive, задания Spark и т. Д. Luigi предоставляет информативный пользовательский интерфейс, который позволяет легко визуализировать DAG и следить за его выполнением, если он настроен с помощью веб-сервера, поставляемого с пакетом. Airflow продвигает этот подход еще на один шаг. Его веб-сервер предоставляет не только информативный интерфейс, но и интерактивный, который позволяет пользователям запускать DAG, контролировать выполнение определенных задач, просматривать журналы и т. Д.

Система запуска задач, которую использует каждый, - это ключевое различие между Luigi и Airflow. Луиджи использует модель зависимостей в стиле «GNU-Make». Это означает, что каждая задача имеет одну или несколько определенных целей вывода (в простейшем случае - локальный файл), и задача считается «выполненной», когда эти цели вывода созданы. Следовательно, Луиджи планирует задачи для выполнения только в том случае, если требуемые задачи дали свой результат. Airflow, с другой стороны, записывает DAG и выполнение задач в базу данных. Это упрощает изучение журналов прошлых выполнений конвейера, но также требует дополнительных усилий для настройки и обслуживания.

Легковесы: лосось и далими

Airflow и Luigi - рекомендуемые решения для проблем ETL и выполнения зрелых конвейеров обработки данных. Тем не менее, несмотря на то, что они отлично работают в производственных условиях, в GAMMA мы часто быстро перебираем альтернативные модели и настройки тестирования, особенно на этапах проверки концепции. В результате наших специализированных требований пара легких фреймворков возникла независимо как проекты с открытым исходным кодом изнутри GAMMA: elkhound и dalymi (данные, как вы имеете в виду). Оба они все еще находятся на ранних стадиях разработки, но они уже решают проблемы рабочего процесса, обеспечивая быструю разработку моделей и одновременно продвигая здоровые методы кодирования. Такая среда делает нашу работу гибкой и динамичной, не создавая большого технического долга, который в противном случае возник бы при переходе в производство.

Резюме

Независимо от того, какую структуру вы выберете, любому специалисту по данным будет выгодно структурировать свою работу в форме атомарных задач с четко определенными входами, выходами и зависимостями. Наш совет: используйте рабочие процессы с данными и будьте победителем в эпоху цифровых технологий. Не будьте нетерпеливы и опрометчиво погружайтесь в программирование и разработку алгоритмов, иначе вы рискуете создать неподдерживаемый код и не ответите на главный бизнес-вопрос. Не бойтесь изучать и использовать фреймворки; они помогут сократить количество технических деталей, чтобы вы могли сосредоточиться на том, что действительно важно: на бизнес-логике. Структура - ваш друг: примите ее.

Удачного кодирования!