Использование модели ARIMA в BigQuery ML для прогнозирования спроса
Давайте сделаем 2-недельный прогноз количества прокатов велосипедов, которые начнутся на одной из велосипедных станций в Гайд-парке, на основе последних шести недель.
Соберите данные для обучения
Первый шаг, как и в случае с любой другой проблемой машинного обучения, - это собрать обучающие данные и изучить их. Предположим, что у нас есть данные об аренде до середины июня 2015 года, и мы хотим сделать прогнозы на оставшуюся часть месяца. Мы можем собрать данные за последние 6 недель, используя:
SELECT CAST(EXTRACT(date from start_date) AS TIMESTAMP) AS date , COUNT(*) AS numrentals FROM `bigquery-public-data`.london_bicycles.cycle_hire WHERE start_station_name LIKE '%Hyde%' -- all stations in Hyde Park GROUP BY date HAVING date BETWEEN '2015-05-01' AND '2015-06-15' ORDER BY date
На графике мы видим своего рода недельную тенденцию с повышением арендной платы по выходным:
Обучайте модель ARIMA
Мы можем использовать эти данные для обучения модели ARIMA, сообщая BigQuery, какой столбец является столбцом данных, а какой - столбцом с меткой времени:
CREATE OR REPLACE MODEL ch09eu.numrentals_forecast OPTIONS(model_type='ARIMA', time_series_data_col='numrentals', time_series_timestamp_col='date') AS SELECT CAST(EXTRACT(date from start_date) AS TIMESTAMP) AS date , COUNT(*) AS numrentals FROM `bigquery-public-data`.london_bicycles.cycle_hire WHERE start_station_name LIKE '%Hyde%' -- all stations in Hyde Park GROUP BY date HAVING date BETWEEN '2015-05-01' AND '2015-06-15'
После обучения модели мы можем оценить ее с помощью ML.EVALUATE () и просмотреть коэффициенты ARIMA с помощью ML.ARIMA_COEFFICIENTS ().
Прогнозирование
Мы можем спрогнозировать количество арендных плат на каждый из следующих 14 дней, а также получить 90-й процентиль доверительной вероятности, используя:
SELECT * FROM ML.FORECAST(MODEL ch09eu.numrentals_forecast, STRUCT(14 AS horizon, 0.9 AS confidence_level))
Границы истории, прогноза и достоверности могут быть построены с использованием:
import matplotlib.pyplot as plt import pandas as pd def plot_historical_and_forecast(input_timeseries, forecast_output, timestamp_col_name, data_col_name): plt.figure(figsize=(20,6)) plt.plot(input_timeseries[timestamp_col_name], input_timeseries[data_col_name], label = 'Historical') plt.xlabel(timestamp_col_name) plt.ylabel(data_col_name) forecast_output['forecast_timestamp'] = pd.to_datetime(forecast_output['forecast_timestamp']) x_data = forecast_output['forecast_timestamp'] y_data = forecast_output['forecast_value'] confidence_level = forecast_output['confidence_level'].iloc[0] * 100 low_CI = forecast_output['confidence_interval_lower_bound'] upper_CI = forecast_output['confidence_interval_upper_bound'] # Plot the data, set the linewidth, color and transparency of the # line, provide a label for the legend plt.plot(x_data, y_data, alpha = 1, label = 'Forecast', linestyle='--') # Shade the confidence interval plt.fill_between(x_data, low_CI, upper_CI, color = '#539caf', alpha = 0.4, label = str(confidence_level) + '% confidence interval') # Display legend plt.legend(loc = 'upper center', prop={'size': 16}) plot_historical_and_forecast(df, fcst, 'date', 'numrentals')
Это дает:
Но насколько это хорошо по сравнению с тем, что на самом деле произошло во второй половине июня? Мы можем извлечь данные за те дни и сравнить с временными рядами прогноза:
Довольно круто, а?
Прогнозирование ряда серий
Пока что я прогнозировал общий объем аренды для всех велосипедных станций в Гайд-парке. Как мы прогнозируем объем аренды для каждой отдельной станции? Используйте time_series_id_col:
CREATE OR REPLACE MODEL ch09eu.numrentals_forecast OPTIONS(model_type='ARIMA', time_series_data_col='numrentals', time_series_timestamp_col='date', time_series_id_col='start_station_name') AS SELECT start_station_name , CAST(EXTRACT(date from start_date) AS TIMESTAMP) AS date , COUNT(*) AS numrentals FROM `bigquery-public-data`.london_bicycles.cycle_hire WHERE start_station_name LIKE '%Hyde%' -- all stations in Hyde Park GROUP BY start_station_name, date HAVING date BETWEEN '2015-01-01' AND '2015-06-15'
Обратите внимание, что вместо того, чтобы тренировать серию по 45 дней (с 1 мая по 15 июня), я теперь тренируюсь в течение более длительного периода. Это связано с тем, что агрегированные временные ряды, как правило, будут более гладкими и предсказуемыми, чем временные ряды для отдельных станций. Итак, мы должны показать модели более длинную линию тренда.
Теперь это не одна модель ARIMA, а отдельная модель ARIMA для каждого имени станции. Действительно, делая:
SELECT * FROM ML.ARIMA_COEFFICIENTS(MODEL ch09eu.numrentals_forecast) ORDER BY start_station_name
дает нам отдельный набор коэффициентов для каждого start_station_name:
Обратите внимание на кое-что интересное - на каждой из станций есть модели ARIMA разной сложности! Под капотом BigQuery ML выполняет автоматическую настройку гиперпараметров. Хотя модель называется ARIMA, базовый алгоритм фактически включает в себя довольно много наворотов, включая обнаружение аномалий, моделирование эффекта праздника (пользователь должен указать регион праздника), обнаружение / моделирование сезонности и моделирование тенденций. Кроме того, разные временные ряды обучаются параллельно.
Когда мы делаем прогноз, мы получим прогноз для каждой станции и отметки времени:
SELECT start_station_name, forecast_timestamp, forecast_value FROM ML.FORECAST(MODEL ch09eu.numrentals_forecast, STRUCT(3 AS horizon, 0.9 AS confidence_level)) ORDER By start_station_name, forecast_timestamp
дает один прогноз временного ряда для каждой станции:
В полной записной книжке на GitHub есть графики прогнозов по станциям.
Оценка модели может помочь вам предугадать, на каких станциях модель будет лучше (чем ниже дисперсия с поправкой на сезонность, тем легче ее предсказать, и, следовательно, тем лучше должна быть модель - вы не можете использовать здесь AIC, потому что AIC разные временные ряды не сопоставимы):
SELECT * FROM ML.EVALUATE(MODEL ch09eu.numrentals_forecast) ORDER BY variance DESC
По результатам мы ожидаем, что прогнозы на Hyde Park Corner будут наихудшими, а на Knightsbridge - наилучшими:
Наслаждаться!
Следующие шаги
- Просмотрите полную записную книжку на GitHub.
- Чтобы узнать больше о BigQuery ML, прочтите главу 9 BigQuery: The Definitive Guide. Книга периодически пополняется этими сообщениями в блоге, так что она остается окончательной.
Спасибо Си Ченгу и Амиру Хормати за полезные предложения