Наука о данных в реальном мире

10 советов, как сделать код для анализа данных чище и эффективнее

Большинство курсов Moocs и университетов не учит вас профессиональному программированию на Python, эта статья даст вам несколько советов, как это сделать.

[Примечание: эта статья регулярно обновляется, следуя вашим отзывам. Не стесняйтесь оставлять свои замечания в комментариях.]

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

  • Мой опыт работы над проектами в области науки о данных, выполнения анализа кода и разработки конвейеров машинного обучения, в которых было задействовано множество специалистов по данным (специалист по данным / соучредитель Modeo.ai, технический директор Pronoo.ai, внештатный специалист по данным и руководитель AiLab в GarageISEP) .
  • Моя работа над AWS DeepRacer, чемпионатом по автономным автомобилям, организованным Amazon Web Services, где я выиграл французскую версию и участвовал в мировом финале в Лас-Вегасе в декабре 2019 года (см .: https://medium.com/@matthieurousseau_16015/ what-is-the-aws-deepracer-league-and-how-did-we-win-the-french-edition-facae656680c )
  • Книги, которые я прочитал по этой теме (очень рекомендую):
  1. Роберт С. Мартин. Чистый код: руководство по созданию гибкого программного обеспечения. Пирсон, 2009.
  2. Орелиен Жерон. Практическое машинное обучение с помощью Scikit-Learn и TensorFlow: концепции, инструменты и методы для создания интеллектуальных систем. О’Рейли, 2017.
  3. Уэс МакКинни. Python для анализа данных. О’Рейли, 2017.
  4. Роберт С. Мартин. Чистая архитектура: руководство по структуре и дизайну программного обеспечения. Пирсон, 2017.

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

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

1. Один уровень абстракции для каждой функции

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

Что такое уровень абстракции? Цель этой функции - получить данные из базы данных и затем применить к ним предварительную обработку.

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

Вот что мы можем сделать, чтобы сделать этот код более читабельным:

2. Используйте подсказки по типу, чтобы улучшить читаемость.

Поскольку наша цель - манипулировать данными, наши функции обычно принимают различные типы данных в качестве аргументов (список, кортежи, dict, Pandas DataFrame, Numpy Array и т. Д.…). Поэтому обязательно указывать тип каждого аргумента, а также тип возвращаемых объектов.

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

См. Https://www.bernat.tech/the-state-of-type-hints-in-python/

3. Аргументы

Аргументы следует максимально ограничить. Удивительно, правда? Позвольте мне рассказать вам, почему.

Существует несколько типов функций: ниладические (0 аргументов), монадические (1 аргумент), диадические (2 аргумента), триадические (3 аргумента) и полиадические (более 3 аргументов). Монадические приемлемы, диадических следует избегать, а более трех аргументов - это слишком.

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

4. Блоки и отступы

Функции должны быть небольшими. Никто не хочет искать ошибку в функции из 2000 строк. Чтобы функция была удобочитаемой, постарайтесь иметь минимум строк для каждого оператора (if, else, while…).

В идеале старайтесь оставлять только одну строку для каждого утверждения. Чтобы быть максимально понятным, эту строку можно использовать для вызова функции с явным именем. Если у вас нет выбора, постарайтесь ограничиться максимум двумя уровнями отступа, чтобы не повлиять на читабельность кода.

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

5. Обработка ошибок

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

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

Еще один способ максимально использовать исключения - разработать собственное.

Представьте, что вы получаете данные через API. Скорее всего, у вас нет контроля над тем, что вам возвращает API, что может повлиять на правильное выполнение вашей программы.

См .: https://jeffknupp.com/blog/2013/02/06/write-cleaner-python-use-exceptions/

6. Используйте регистратор, а не печатайте

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

Отпечатки сложнее форматировать, они менее читабельны и, прежде всего, содержат мало информации. С другой стороны, регистраторы содержат больше информации, напрямую отформатированы и имеют уровень информации, позволяющий определить важность информации (ИНФОРМАЦИЯ, ПРЕДУПРЕЖДЕНИЕ, ОШИБКА и т. Д.).

На изображении ниже вы можете увидеть отображение выполнения обучающего скрипта. См. Https://docs.python.org/3/howto/logging.html для получения дополнительных сведений о входе в систему в Python.

7. Строка документации

Строка документации - важный элемент Python. Он должен появляться в любом объявлении оператора (определение функции, класса или метода). Они делают код более явным и служат документацией для объекта.

«Универсальное соглашение обеспечивает всю ремонтопригодность, ясность, последовательность, а также основу для хороших навыков программирования. Чего он не делает, так это настаивает на том, чтобы вы следовали ему против своей воли. Это Python! »

- Тим Питерс на comp.lang.python, 2001–06–16

Существует два типа строк документации: однострочная строка документа и многострочная строка документа.

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

  • Тройные кавычки используются, даже если строка умещается на одной строке. Это упрощает его дальнейшее расширение.
  • Котировки закрытия находятся на той же строке, что и котировки открытия. Это выглядит лучше для однострочных.
  • Ни перед, ни после строки документации нет пустых строк.
  • Строка документации - это фраза, оканчивающаяся точкой. Он предписывает эффект функции или метода как команду («Сделай это», «Верни то»), а не как описание; например не пишите «Возвращает путь…».
  • Однострочная строка документации НЕ должна быть «подписью», повторяющей параметры функции / метода (которые могут быть получены путем самоанализа).

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

См .: https://www.python.org/dev/peps/pep-0257/#abstract

8. Модульный тест

Тестирование Python - это очень обширная тема и может быть очень сложной, но они необходимы для того, чтобы сделать ваш код Python более чистым и надежным.

В компьютерном программировании модульное тестирование - это метод тестирования программного обеспечения, при котором отдельные единицы исходного кода, наборы из одного или нескольких компьютерных программных модулей вместе со связанными данными управления, процедурами использования и рабочими процедурами , проходят испытания на предмет пригодности для использования . Колава, Адам, Хейзинга, Дорота (2007). Автоматическое предотвращение дефектов: передовой опыт управления программным обеспечением. Пресса компьютерного общества Wiley-IEEE. п. 75.

Хороший совет для эффективного тестирования - использовать три закона TDD и принцип F.I.RS.T (которые применимы как к Python, так и к другим языкам программирования).

Три закона TDD:

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

F.I.R.S.T

  1. Быстро. Тестирование должно быть быстрым и выполняться быстро, так как вам придется часто тестировать их. В противном случае вы не сможете использовать их в полной мере, поскольку они будут зря тратить ваше время.
  2. Независимые: тесты не должны зависеть друг от друга, они не должны создавать условия для следующего теста. Вы должны иметь возможность запускать их в том порядке, в котором хотите.
  3. Повторяемость: тесты должны иметь возможность запускаться в любой среде, будь то на этапе производства или создания прототипа, на любой машине. Таким образом, используемая среда не влияет на успех тестов.
  4. Самостоятельная проверка: результат теста должен быть логическим. Тест либо пройден, либо не пройден, но посредника нет. В противном случае сдача тестов становится субъективной.
  5. Своевременно. Модульные тесты должны разрабатываться в нужное время, то есть на этапе тестирования, а не в рабочей среде.

См .: https://docs.python.org/3/library/unittest.html

9. Комментарии

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

Есть несколько типов хороших комментариев:

  1. Юридические комментарии: Авторские права, лицензия и т. д.
  2. Информативные комментарии: когда вам нужно указать формат даты, которую вы анализируете.
  3. Объяснение намерения. Отступы часто отражают сложную логику, их можно использовать, чтобы кратко объяснить, что они делают.
  4. Уточнение. Ваш код может быть трудным для понимания. Иногда полезно уточнить использование возвращаемого аргумента или переменной.
  5. Предупреждение о последствиях. Выполнение определенных блоков кода может иметь важные последствия. Комментарии могут использоваться для предупреждения другого пользователя кода.
  6. Усиление. Их можно использовать для усиления важности кода, который может остаться незамеченным.

Но есть и несколько типов плохих комментариев:

  1. Неясно: когда вам лень писать хорошо, а комментарий не содержит четкой информации.
  2. Избыточный: когда вы повторяете то, что сказано в строке документации или в предыдущих комментариях.
  3. Шумовая информация: вам не нужно все комментировать, иначе это означает, что ваш код непонятен.
  4. Закомментированный код: лучше удалить старый неиспользуемый код, чем закомментировать его.

10. Инструменты для переформатирования кода

Что касается форматирования кода, структура Python требует от нас очень дотошности, чтобы правильно отформатировать наш код. Действительно, количество пропускаемых строк зависит от того, что объявлено в коде (объявляем ли мы класс, метод, переменную?).

Списки не должны быть слишком длинными, в противном случае вам придется вернуться к строке, то же самое касается длины строки, правил пробелов и т. Д. Короче говоря, есть много правил, которым нужно следовать, и слишком долго, чтобы им тщательно следовать вручную (см. https://www.python.org/dev/peps/pep-0008/).

К счастью, некоторые библиотеки автоматически форматируют ваш код, и это значительно экономит время. Самые известные библиотеки - Black и Yapf, и я их очень рекомендую. Они легко интегрируются в IDE, такую ​​как PyCharm, и результат действительно хорош.

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

В приведенном ниже коде показано, как преобразовать плохо отформатированный некрасивый код в хорошо отформатированный некрасивый код.

См .: https://opensource.com/article/18/7/7-python-libraries-more-maintainable-code

Заключение

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

Я также рекомендую вам взглянуть на этот репозиторий GitHub, который включает концепции, упомянутые в этой статье, с другими примерами кода: https://github.com/davified/clean-code-ml.

Если у вас есть какие-либо комментарии по поводу упомянутых советов, пожалуйста, оставьте комментарий к этой статье или отправьте их мне по электронной почте: [email protected].