Используйте R & Prophet, чтобы создавать прогнозы для прогнозирования количества пассажиров поездов в Городе ветров.

Нажмите, чтобы найти: Блестящее приложение

Знаменитые надземные поезда «L», курсирующие по Чикаго, являются неотъемлемой частью общественного транспорта в городе. Цветные маршруты разветвляются на все районы, объединяясь в центральную петлю в центре города. Эта транспортная система не только полезна, но и предоставляет огромное количество данных для анализа и извлечения информации.

Как коренной чикагец, меня особенно интересуют данные, ориентированные на Чикаго. Таким образом, прогнозирование движения поездов на станциях по всему городу казалось идеальным проектом! Я использовал Prophet, пакет прогнозирования с открытым исходным кодом от Facebook. В последующих сообщениях я изменю свой рабочий процесс для использования в Shiny. Это позволит пользователям создавать несколько прогнозов в режиме реального времени в чистом и простом пользовательском интерфейсе.

Пророк + R =❤️

Используйте силу пророка.

Prophet был разработан в 2017 году исследователями Facebook с целью упрощения масштабного прогнозирования. Prophet имеет полностью открытый исходный код и доступен как для R, так и для Python. Это особенно полезно при работе со схемами даты и времени (ежедневно, ежечасно, ежемесячно, ежегодно), сезонными факторами и выбросами/отсутствующими данными.

Prophet — отличная отправная точка в мир прогнозирования, потому что он быстрый, интуитивно понятный, автоматический и настраиваемый. Последние 2 пункта важны. В то время как Prophet генерирует прогноз очень быстро, пользователи могут настраивать и изменять прогнозы на основе поведения. Это делает прогноз податливым для различных сценариев.

TL;DR Prophet: Behind the Hood.

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

  • g(t) = непериодические изменения значения временного ряда
  • s(t) = сезонность (ежедневно, ежечасно, еженедельно, ежегодно)
  • h(t) = шаблоны для праздников или особых событий.
  • e(t)= ошибка белого шума

Одной из основных проблем прогнозирования в нынешнюю эпоху является влияние COVID-19, особенно на данные, включая общедоступные. Крайняя нерегулярность COVID-19 затрудняет прогнозирование. Исторические данные содержат длительный период «отклоняющихся» данных (т. е. блокировки, сокращение услуг и т. д.) по сравнению с предыдущими долгосрочными тенденциями.

Пророк в R

Данные о пассажиропотоке CTA были получены из CTA Open Transit, которая предоставляет информацию об общем количестве пассажиров автобусов и поездов в день с 2001 г. по настоящее время.

Фрейм данных включает 5 столбцов: Идентификатор станции, Название станции, Дата, Тип дня и Поездки. Для этого прогноза мы будем использовать только название станции, дату и количество поездок.

  1. Подготовьте почву: Tidyverse, Lubridate и Prophet — это пакеты, которые необходимо загрузить в R перед любым программированием. Затем прочитайте данные из CTA Open Transit в виде CSV-файла в сценарий.
  2. Очистите данные: выберите только нужные столбцы и преобразуйте столбец даты в формат месяц-дата-год с помощью функции mdy(). Далее нам нужно отфильтровать весь набор данных только для 1 конкретной станции. Я выбрал Fullerton для этого примера.
  3. Подготовка к пророку. В этом примере мы будем использовать логистическую регрессию, указав минимальную (минимальную) и максимальную (конечную) границу. Это сохранит тенденцию роста между этими границами, предотвратив негативный прогноз гонщиков в любое время в будущем. Наконец, переименуйте столбцы даты и значения в «ds» и «y» соответственно, которые являются распознанными входными данными для функций Prophet.
library(tidyverse)
library(lubridate)
library(prophet)
library(ggthemes)
ridership <- read.csv('ridership.csv')
ridership_clean <- ridership %>%
  select(stationname, date, rides) %>%
  mutate(date = ymd(ridership$date)) %>%
  filter(stationname == "Fullerton") %>%
  mutate(cap = max(rides),
         floor = 0) %>%
  rename(ds = date, y = rides)

3. Создайте COVID «Праздник». Перед созданием прогноза нам нужно создать фрейм данных для представления праздников или праздничных периодов со столбцами «Дата и праздник». Два периода будут представлять сбои COVID в интервалах: блокировка и повторное открытие. (Несмотря на то, что это не на 100 % охватывает временную шкалу COVID, это окажет достаточное влияние на наш прогноз.)

Последовательность дней с 15.03.2020 по 29.05.2020 с соответствующей меткой «Блокировка» была создана во фрейме данных. (Даты соответствуют местным ограничениям в Чикаго). Вторая последовательность была создана с 30 мая 2020 г. по 01 октября 2020 г. с пометкой "Повторное открытие". Оба фрейма данных затем связываются вместе по строке, чтобы создать 1 полный фрейм данных с 15.03 по 01.10. model1 ‹- пророк(наездник_чистый, рост = 'логистика', праздники = праздник)

lockdown_dates <- seq(as_date('2020-03-15'), as_date('2020-05-29'), by  = 1)
lockdown <- data.frame(ds = lockdown_dates, holiday = "Lockdown")
reopening_1_dates <- seq(as_date('2020-05-30'), as_date('2020-10-1'), by  = 1)
reopening_1 <- data.frame(ds = reopening_1_dates, holiday = "Reopening")
holiday <- rbind(lockdown, reopening_1)

4. Готово, настроено, прогноз! Используя функцию prophet(), введите фрейм данных о пассажирах. Это создаст предварительно обработанный экземпляр для подачи в нашу функцию прогнозирования. Укажите термин роста как «логистический», который будет учитывать предельные и минимальные границы. Третий аргумент, праздники, будет принимать в качестве входных данных интервалы праздников COVID-19. Затем нам нужно создать фрейм данных прошлых и будущих дат для прогнозирования.

Укажите, сколько периодов вы хотите прогнозировать в будущем, я выбрал 1 год или 365 дней. Это создаст фрейм данных всех исторических дат + 365 дней в будущем. Затем добавьте 2 новых столбца, указав те же границы, что и исходный фрейм данных. Установите максимальное значение = 0 (нет отрицательного количества пассажиров)и установите максимальное значение = max(поездки) (максимальное значение количества пассажиров, наблюдаемое в прошлом)

Наконец, введите модель и фрейм данных будущей даты в функцию predict(), применяя модель пророка к указанному диапазону дат.

model1 <- prophet(ridership_clean, growth = 'logistic', holidays = holiday)
future1 <- make_future_dataframe(model1, periods = 365) %>%
  mutate(cap = max(ridership_clean$y),
         floor = 0)
forecast <- predict(model1, future1)

5. Визуализируйте результаты:

Чтобы создать простой график для визуализации, используйте функцию plot() и введите модель пророка и предсказанные прогнозы. Это создаст быструю визуализацию прогноза, очень высокий уровень (и не слишком красивый).

plot(model1, forecast)

6. Анализ компонентов и точек изменения

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

plot(model1, forecast) + 
   add_changepoints_to_plot(model1)

Вывод из сюжета: Уменьшение числа пассажиров на станции Фуллертон началось *до* пандемии COVID-19.

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

prophet_plot_components(model1, forecast)

7. Окончательный результат:

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

Из результатов нашей модели «ds» и «yhat» — это основные ценности: дата и количество пассажиров. Чтобы отобразить очищенный результат, я создал столбец скользящего среднего (roll), чтобы сгладить любые существенные ежедневные колебания, которые могут исказить наши графики. Это будет отображаться в виде линии во всех точках данных.

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

Я не буду объяснять все стили, сделанные ниже, однако обрисую в общих чертах их основные компоненты. Окончательный ggplot начинается с создания столбцов скользящего среднего и проверки прогноза, о которых говорилось выше. Затем мы строим наш ggplot, который включает точечный график (geom_point), расположенный под линейным графиком (geom_line).

forecast %>% 
  select(ds, yhat) %>%
  mutate(roll = rollmean(yhat, k  = 50, fill = NA)) %>%
  mutate(prediction = case_when(ds > '2022-02-01' ~ 1,
                                             TRUE ~ 0)) %>%
  ggplot(aes(ds, yhat, color = prediction)) + geom_point(size = 0.05) + 
  geom_line(aes(ds, roll)) +
  scale_y_continuous(label = scales::comma_format(), limits = c(-1000, 18000)) + 
  theme_fivethirtyeight() + 
  labs(y = "Ridership", x = "Date") +
  ggtitle("L Ridership Prediction at Fullerton") + 
  theme(legend.position = "none", 
        axis.title.x = element_text(),
        axis.title.y = element_text(angle = 0, vjust = 0.5)