Добро пожаловать во вторую серию сериала! Раньше мы выбрали набор данных, определили нашу исследовательскую задачу и провели предварительное изучение данных.

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

Даты разбора

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

Теперь у нас есть час дня и четверти часа в течение дня (00:14 quarter_of_hour равно 0, 02:16 9 и т. Д.). Мы используем и то, и другое, так как сможем определить, какая степень детализации достаточна для эффективного обучения нашей модели машинного обучения.

Хорошо, мы создали дополнительные атрибуты в зависимости от времени суток, но как насчет даты? Давайте применим тот же процесс, который мы только что использовали:

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

Обратите внимание, что мы создали два поля для сезона: season и season_numeric. Второй - это то, что будет использовать наш алгоритм машинного обучения, первый - просто для удобства чтения человеком.

Создание синтетики

Мы еще можем сделать больше! Давайте подумаем, что еще влияет на городской трафик. Один из низко висящих фруктов - праздники. Опять же, поскольку мы экспериментируем, мы создадим два атрибута: один для проверки того, был ли вывоз такси в праздничный день, а другой - для того, чтобы забрать такси в течение определенного количества дней от праздничный день.

Что именно это за число? Обычно для этого нужно добавить еще один уровень метаанализа: мы проверяем статистику путешествий по Нью-Йорку или, за исключением этого, по штату Нью-Йорк. Исходя из этого, мы могли бы оценить средний (или медианный, или некоторый центильный порог) интервал поездок в отпуск. К сожалению, затем мы бы расширили этот и без того значительный эпизод еще больше, поэтому вместо этого мы просто воспользуемся здравым смыслом. Допустим, большинство праздничных мероприятий происходит в течение примерно трех дней с самой даты.

По поводу того, какие именно праздники здесь актуальны: к счастью, это США, так что их не так много. Мы просто скопируем их вручную, а затем создадим два атрибута is_holiday и is_near_holiday:

Обратите внимание, что мы преобразовали логические значения (False и True) в целые числа (0 и 1). Опять же, это связано с требованиями к числовым данным.

Теперь у нас есть несколько дополнительных атрибутов, но как насчет нашего фактического значения, которое предстоит спрогнозировать? Атрибут intensity отсутствует. Но это нормально - мы можем сделать его, используя оператор pandas ' groupby:

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

Чтобы проиллюстрировать, к чему мы пришли, давайте снова запустим head() в DataFrame:

Для каждой поездки в наборе данных мы скопировали количество поездок в соответствующем квартале.

Теперь мы почти готовы начать обучение. Однако нам все еще предстоит немного очистить - нам нужно удалить неопределенные значения, удалить атрибуты, которые мы не будем использовать, и преобразовать номинальные атрибуты (например, Borough) в числовые.

Причины удаления следующие:

  • Pickup_date уже выделен в несколько синтетических атрибутов, которые несут достаточный объем информации;
  • season является избыточным, поскольку у нас есть season_numeric, который уже является числовым атрибутом;
  • Zone и Borough были там только для нашего удобства - наш основной источник данных для местоположения - locationID, который, как мы знаем, содержит однозначную информацию (в противном случае используемая нами таблица поиска не существовала бы);
  • удаление Dispatching_base_num и Affiliated_base_num - совершенно произвольный выбор для простоты - вы можете попробовать оставить их, если хотите.

Затем давайте очистим все отсутствующие значения, сначала проверив, присутствуют ли они вообще:

Посмотрите на результат - нам здесь повезло!

Не только это, но и от изучения текущей формы набора данных:

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

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

Парные графики seaborn объединяют попарные диаграммы разброса с гистограммами (последняя по диагонали). Глядя на этот конкретный, мы можем сделать несколько наблюдений:

  • мы можем подтвердить, что мы правильно закодировали quarter_of_hour, поскольку он линейно коррелирован с hour (образуя характеристику «стремянка»);
  • мы видим из гистограмм, что количество поездок в целом несбалансировано по отношению практически ко всем атрибутам: этого следовало ожидать и указывает на то, что набор данных, вероятно, не был (существенно) отфильтрован для определенных точек данных;
  • глядя на отношения атрибутов со значением, которое будет предсказано (последняя строка), мы можем сказать, что большинство атрибутов имеют какое-то влияние на значение intensity. Более того, hour и quarter_of_hour демонстрируют явное сходство в своих парных графиках, что указывает на высокую вероятность того, что они взаимно излишни.

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

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

Мы сделаем это в следующей серии.

Примечание: ни автор этого сообщения, ни SoftwareMill никоим образом не связаны с Uber.