4 аспекта, упущенных в большинстве программ по науке о данных.

Возможно, вы слышали или сталкивались с правилом 80/20 в науке о данных:

Лишь 20% времени дата-сайентистов уходит на анализ данных. Большая часть времени  —  80%  —  тратится на подготовку данных.

Думаю, в моем случае это соотношение составляет 90/10. Таковы реалии моей работы  —  мы имеем дело с очень сложными массивами данных.

Однако большинство программ, тренингов и курсов по науке о данных готовят совсем не к этому.

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

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

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

Именно этот курс вдохновил меня на размышления о некоторых из рассматриваемых здесь тем.

Это первая из серии статей о практических уроках, которые я получила (в основном), работая в блоке 80%. Цель  —  рассказать об инструментах, используемых для подготовки данных, и поделиться приобретенными мной успешными практиками.

Вот что мы рассмотрим:

  1. Станьте уверенным пользователем Linux.
  2. Старайтесь применять удаленные вычислительные системы.
  3. Используйте отдельную среду Python для каждого проекта.
  4. Научитесь отлаживать и профилировать код.

1. Станьте уверенным пользователем Linux

Даже если ваша операционная система  —  Windows, есть множество причин, по которым базовые знания Linux могут оказаться очень полезными.

Среды совместных вычислений, такие как AWS и GCP, обычно работают под управлением Linux. Linux также поставляется с командной оболочкой (shell)  —  мощным инструментом, позволяющим решать многие задачи с помощью нескольких простых команд.

Вот что говорит по этому поводу Software Carpentry, где практикумы обычно начинаются с курса основ командной оболочки:

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

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

  • Освоение файловой системы и механизмов ее обхода. Обратите внимание на такие понятия, как структура каталогов, домашний каталог, права доступа к файлам и каталогам, ссылки на файлы.
  • Переменная $PATH и переменные окружения.
  • Составление списка запущенных процессов, остановка и завершение процесса.
  • Основные команды оболочки для работы с файлами и каталогами, такие как cd, ls, cat, less, mkdir, mv, rm, grep и find.
  • Конвейеризация команд и перенаправление вывода команд.
  • Редактирование файла в терминале с помощью текстовых редакторов типа nano и vim.
  • Создание базового сценария оболочки, позволяющего сохранять команды и легко выполнять их повторно.

Этот список может показаться длинным, но, как только вы начнете регулярно использовать перечисленные в нем инструменты, они станут привычными.


2. Старайтесь применять удаленные вычислительные системы

Удаленные вычислительные среды, такие как AWS, GCP и Azure, полезны по двум основным причинам:

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

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

Если вы когда-нибудь сталкивались с потерей части результатов из-за кратковременного разрыва связи с интернетом, то понимаете, о чем я говорю.

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

Вот два ключевых действия, которые вы будете выполнять при работе с удаленными вычислительными системами.

  • Подключение по ssh и передача данных туда и обратно с помощью таких инструментов, как scp и rsync (rsync  —  важный инструмент, который необходимо иметь в своем арсенале, поскольку с помощью опции -P можно возобновить прерванную передачу, что удобно в случае больших файлов).
  • Управление длительными процессами с помощью таких инструментов, как nohup, screen и tmux, чтобы процессы не завершались при отключении от удаленного компьютера. 

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


3. Используйте отдельную среду Python для каждого проекта

На мой взгляд, это достаточно простая идея, но из личного опыта знаю, что на практике она реализуется крайне редко.

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

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

Настоятельно рекомендую использовать виртуальные среды Python (venv, conda, pipenv или любой другой предпочитаемый менеджер виртуальных сред) для каждого отдельного проекта, независимо от его масштаба.

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

Есть много причин, по которым этого делать не следует. Назовем две основные.

  • Вы рискуете столкнуться с проблемами, связанными с версиями библиотек в разных проектах. Вы когда-нибудь слышали об “аде зависимостей” (“dependency hell”)? Может показаться, что это крайний случай, но он более распространен, чем вы думаете.
  • Сложнее определить, какие библиотеки нужны для того или иного проекта. Это особенно проблематично, если вы работаете над совместным проектом и должны делить среду с остальными членами команды.

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


4. Научитесь отлаживать и профилировать код

Никто не способен написать идеальный код. Вы можете потратить несколько часов на проверку логики кода, не работающего должным образом, и обнаружить, что случайно поменяли местами переменные или забыли вызвать model.eval(). Это удручающая реальность для всех, кто зарабатывает на жизнь написанием кода.

Естественным первым шагом при возникновении странной ошибки является использование множества операторов вывода и итеративное тестирование кода. Часто этого бывает достаточно, чтобы выявить проблему, но не всегда находятся простые решения (вы когда-нибудь находили забытый отладочный оператор вывода в своем старом коде?).

Инструменты отладки приходят на помощь

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

Есть множество отладчиков, с которыми можно экспериментировать: pdb в Python, debugger в PyCharm, debugger в Visual Studio Code (мой любимый) и многие другие. Если написание кода  —  это то, чем вы занимаетесь ежедневно, то время, потраченное на освоение отладчиков, станет полезной инвестицией, которая в перспективе избавит от многих проблем.

Тайминг и профилирование кода

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

Именно здесь пригодятся тайминг и профилирование. Оба способа помогают сделать одно и то же  —  выявить узкие места и неэффективность в коде. При этом каждый из них использует свой подход.

Тайминг просто измеряет, сколько времени прошло между двумя точками в коде. С его помощью можно узнать, сколько времени заняло выполнение определенной функции (для модуля timeit в Python есть несколько полезных примеров).

Есть различные виды профилировщиков, но все они помогают делать одно и то же. Они позволяют измерить, сколько времени было потрачено на каждый вызов функции. В Python есть встроенный профилировщик cProfile, а также множество сторонних вариантов, таких как Palanteer и Yappi.

Независимо от того, какой вариант профилирования вы решите использовать, если когда-нибудь будете переписывать и оптимизировать код, вам следует подумать о добавлении профилировщика в свой инструментарий Python.

Замечание по отладке

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

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

Читайте также:

Читайте нас в Telegram, VK и Дзен


Перевод статьи Dasha Herrmannova, Ph.D.: 8 Things Most Data Science Programs Don’t Teach (But You Should Know) — Part 1

Предыдущая статьяИспользование стека навигации SwiftUI для идеального поведения TabView
Следующая статьяПринципы SOLID в инженерии данных. Часть 3