Prévisions évolutives avec des millions de séries temporelles dans BigQuery


Dans ce tutoriel, vous allez apprendre à accélérer de manière significative l'entraînement d'un ensemble de modèles de série temporelle afin d'effectuer plusieurs prévisions de séries temporelles dans une seule et même requête. Vous apprendrez également à évaluer la précision des prévisions.

Pour toutes les étapes, à l'exception de la dernière, vous utiliserez les données new_york.citibike_trips. Ces données contiennent des informations sur les trajets Citi Bike effectués dans la ville de New York. Cet ensemble de données ne contient que quelques centaines de séries temporelles. Il permet d'illustrer diverses stratégies pour accélérer l'entraînement des modèles. Pour la dernière étape, vous utiliserez les données iowa_liquor_sales.sales pour prévoir plus d'un million de séries temporelles.

Avant de lire ce tutoriel, consultez la page Effectuer plusieurs prévisions de séries temporelles à l'aide d'une seule requête à partir des données des trajets Citi Bike effectués dans la ville de New York. Nous vous recommandons également de consulter les bonnes pratiques de prévision de séries temporelles à grande échelle.

Objectifs

Dans ce tutoriel, vous allez utiliser :

Par souci de simplicité, ce tutoriel n'explique pas comment générer des prévisions (explicables) à l'aide de ML.FORECAST ou ML.EXPLAIN_FORECAST. Pour découvrir comment utiliser ces fonctions, consultez la page Prévoir plusieurs séries temporelles à l'aide d'une seule requête pour les trajets Citi Bike effectués dans la ville de New York.

Coûts

Ce tutoriel utilise des composants facturables de Google Cloud, dont :

  • BigQuery
  • BigQuery ML

Pour en savoir plus sur les coûts, consultez les pages Tarifs de BigQuery et Tarifs de BigQuery ML.

Avant de commencer

  1. Connectez-vous à votre compte Google Cloud. Si vous débutez sur Google Cloud, créez un compte pour évaluer les performances de nos produits en conditions réelles. Les nouveaux clients bénéficient également de 300 $ de crédits gratuits pour exécuter, tester et déployer des charges de travail.
  2. Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.

    Accéder au sélecteur de projet

  3. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  4. Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.

    Accéder au sélecteur de projet

  5. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  6. BigQuery est automatiquement activé dans les nouveaux projets. Pour activer BigQuery dans un projet préexistant, accédez à

    Activez l'API BigQuery

    Activer l'API

Étape 1 : Créer un ensemble de données

Vous allez créer un ensemble de données BigQuery pour stocker votre modèle de ML :

  1. Dans la console Google Cloud, accédez à la page "BigQuery".

    Accéder à la page "BigQuery"

  2. Dans le volet Explorateur, cliquez sur le nom de votre projet.

  3. Cliquez sur Afficher les actions > Créer un ensemble de données.

    Créer l'ensemble de données

  4. Sur la page Créer un ensemble de données, procédez comme suit :

    • Dans le champ ID de l'ensemble de données, saisissez bqml_tutorial.

    • Pour Type d'emplacement, sélectionnez Multirégional, puis sélectionnez US (plusieurs régions aux États-Unis).

      Les ensembles de données publics sont stockés dans l'emplacement multirégional US. Par souci de simplicité, stockez votre ensemble de données dans le même emplacement.

    • Conservez les autres paramètres par défaut, puis cliquez sur Créer un ensemble de données.

      Créer une page d'ensemble de données

Étape 2 : Créer la série temporelle pour prévoir

Dans la requête suivante, la clause FROM bigquery-public-data.new_york.citibike_trips indique que vous interrogez la table citibike_trips dans l'ensemble de données new_york.

CREATE OR REPLACE TABLE
  `bqml_tutorial.nyc_citibike_time_series` AS
WITH input_time_series AS
(
  SELECT
    start_station_name,
    EXTRACT(DATE FROM starttime) AS date,
    COUNT(*) AS num_trips
  FROM
    `bigquery-public-data.new_york.citibike_trips`
  GROUP BY
    start_station_name, date
)
SELECT table_1.*
FROM input_time_series AS table_1
INNER JOIN (
  SELECT start_station_name,  COUNT(*) AS num_points
  FROM input_time_series
  GROUP BY start_station_name) table_2
ON
  table_1.start_station_name = table_2.start_station_name
WHERE
  num_points > 400

Pour exécuter la requête, procédez comme suit :

  1. Dans la console Google Cloud, cliquez sur le bouton Saisir une nouvelle requête.

  2. Saisissez la requête GoogleSQL suivante dans la zone de texte Éditeur de requête.

  3. Cliquez sur Exécuter.

L'instruction SELECT de la requête utilise la fonction EXTRACT pour extraire les informations de date de la colonne starttime. La requête utilise la clause COUNT(*) pour obtenir le nombre quotidien total de trajets Citi Bike.

table_1 a 679 séries temporelles. La requête utilise une logique INNER JOIN supplémentaire pour sélectionner toutes les séries temporelles ayant plus de 400 points temporels, soit un total de 383 séries temporelles.

Étape 3 : Prévoir plusieurs séries temporelles simultanément avec des paramètres par défaut

Au cours de cette étape, vous allez prévoir le nombre total de trajets quotidiens à partir de différentes stations Citi Bike. Pour ce faire, vous devez prévoir de nombreuses séries temporelles. Vous pourriez écrire plusieurs requêtes CREATE MODEL, mais cela peut être un processus fastidieux et chronophage, en particulier lorsque vous avez un grand nombre de séries temporelles.

Pour améliorer ce processus, BigQuery ML vous permet de créer un ensemble de modèles de séries temporelles afin de prévoir plusieurs séries temporelles à l'aide d'une seule requête. En outre, tous les modèles de séries temporelles sont ajustés simultanément.

Dans la requête GoogleSQL suivante, la clause CREATE MODEL crée et entraîne un ensemble de modèles nommé bqml_tutorial.nyc_citibike_arima_model_default.

CREATE OR REPLACE MODEL `bqml_tutorial.nyc_citibike_arima_model_default`
OPTIONS
  (model_type = 'ARIMA_PLUS',
   time_series_timestamp_col = 'date',
   time_series_data_col = 'num_trips',
   time_series_id_col = 'start_station_name'
  ) AS
SELECT *
FROM bqml_tutorial.nyc_citibike_time_series
WHERE date < '2016-06-01'

Pour exécuter la requête CREATE MODEL afin de créer et d'entraîner votre modèle, procédez comme suit :

  1. Dans la console Google Cloud, cliquez sur le bouton Saisir une nouvelle requête.

  2. Saisissez la requête GoogleSQL suivante dans la zone de texte Éditeur de requête.

  3. Cliquez sur Exécuter.

    L'exécution de la requête prend environ 14 minutes et 25 secondes.

La clause OPTIONS(model_type='ARIMA_PLUS', time_series_timestamp_col='date', ...) indique que vous créez un ensemble de modèles de série temporelle ARIMA_PLUS basés sur ARIMA. Outre time_series_timestamp_col et time_series_data_col, vous devez spécifier time_series_id_col, qui permet d'annoter différentes séries temporelles d'entrée.

Cet exemple n'affiche pas les points temporels de la série temporelle postérieurs au 01/06/2016, afin que ces points puissent être utilisés ultérieurement pour évaluer la précision des prévisions à l'aide de la fonction ML.EVALUATE.

Étape 4 : Évaluer la précision des prévisions pour chaque série temporelle

Au cours de cette étape, vous évaluez la précision des prévisions pour chaque série temporelle en utilisant la requête ML.EVALUATE suivante.

SELECT *
FROM
  ML.EVALUATE(MODEL `bqml_tutorial.nyc_citibike_arima_model_default`,
              TABLE `bqml_tutorial.nyc_citibike_time_series`,
              STRUCT(7 AS horizon, TRUE AS perform_aggregation))

Pour exécuter la requête ci-dessus, procédez comme suit :

  1. Dans la console Google Cloud, cliquez sur le bouton Saisir une nouvelle requête.

  2. Saisissez la requête GoogleSQL suivante dans la zone de texte Éditeur de requête.

  3. Cliquez sur Exécuter. Cette requête renvoie plusieurs métriques de prévision, telles que :

    Les résultats doivent se présenter sous la forme suivante : ML.EVALUATE output1.

ML.EVALUATE utilise le modèle ARIMA_PLUS entraîné à l'étape précédente comme premier argument.

Le deuxième argument est une table de données contenant les données de vérité terrain. Ces résultats de prévision sont comparés aux données de vérité terrain pour calculer les métriques de justesse. Dans ce cas, nyc_citibike_time_series contient à la fois les points de série temporelle antérieurs au 01/06/2016 et ceux postérieurs au 01/06/2016. Les points postérieurs au 01/06/2016 sont les données de vérité terrain. Les points antérieurs au 01/06/2016 sont utilisés pour entraîner le modèle à générer des prévisions après cette date. Seuls les points postérieurs au 01/06/2016 sont nécessaires pour calculer les métriques. Les points antérieurs au 01/06/2016 sont ignorés dans le calcul des métriques.

Le troisième argument est un STRUCT contenant deux paramètres. L'horizon a une valeur de 7, ce qui signifie que la requête calcule la précision des prévisions sur la base d'une prévision à sept points. Notez que si les données de vérité terrain contiennent moins de sept points pour la comparaison, les métriques de précision sont calculées en fonction des points disponibles uniquement. perform_aggregation a la valeur TRUE, ce qui signifie que les métriques de précision des prévisions sont agrégées individuellement pour chaque point de série temporelle. Si vous spécifiez perform_aggregation comme FALSE, la précision des prévisions est renvoyée pour chaque point de temps de série temporelle prévu.

Étape 5 : Évaluer la précision globale des prévisions pour toutes les séries temporelles

Au cours de cette étape, vous allez évaluer la précision des prévisions pour l'ensemble des 383 séries temporelles à l'aide de la requête suivante :

SELECT
  AVG(mean_absolute_percentage_error) AS MAPE,
  AVG(symmetric_mean_absolute_percentage_error) AS sMAPE
FROM
  ML.EVALUATE(MODEL `bqml_tutorial.nyc_citibike_arima_model_default`,
              TABLE `bqml_tutorial.nyc_citibike_time_series`,
              STRUCT(7 AS horizon, TRUE AS perform_aggregation))

Parmi les métriques de prévision renvoyées par ML.EVALUATE, seules les erreurs absolues de pourcentage moyen et les erreurs de pourcentage absolu symétrique sont indépendantes des valeurs de la série temporelle. Par conséquent, pour évaluer la précision globale des prévisions de l'ensemble des séries temporelles, seul l'agrégation de ces deux métriques est pertinente.

Cette requête renvoie les résultats suivants : pour les EAMP : 0,3471, pour les EAMSP : 0,2563.

Étape 6 : Prévoir plusieurs séries temporelles simultanément à l'aide d'un espace de recherche d'hyperparamètres plus petit

À l'étape 3, nous avons utilisé les valeurs par défaut pour toutes les options d'entraînement, y compris auto_arima_max_order. Cette option contrôle l'espace de recherche pour le réglage d'hyperparamètres dans l'algorithme auto.ARIMA.

Dans cette étape, vous utilisez un espace de recherche plus petit pour les hyperparamètres.

CREATE OR REPLACE MODEL bqml_tutorial.nyc_citibike_arima_model_max_order_2
OPTIONS
  (model_type = 'ARIMA_PLUS',
   time_series_timestamp_col = 'date',
   time_series_data_col = 'num_trips',
   time_series_id_col = 'start_station_name',
   auto_arima_max_order = 2
  ) AS
SELECT *
FROM bqml_tutorial.nyc_citibike_time_series
WHERE date < '2016-06-01'

Cette requête réduit la valeur auto_arima_max_order de 5 (la valeur par défaut) à 2.

Pour exécuter la requête, procédez comme suit :

  1. Dans la console Google Cloud, cliquez sur le bouton Saisir une nouvelle requête.

  2. Saisissez la requête GoogleSQL suivante dans la zone de texte Éditeur de requête.

  3. Cliquez sur Exécuter.

    L'exécution de la requête prend environ 1 minute et 45 secondes. Rappelez-vous qu'il faut 14 minutes et 25 secondes à la requête pour se terminer si auto_arima_max_order est défini sur 5. La vitesse est donc environ sept fois supérieure en définissant auto_arima_max_order sur 2. Si vous vous demandez pourquoi le gain de vitesse n'est pas de 5/2 = 2,5 x, c'est parce l'augmentation de l'ordre de auto_arima_max_order entraîne non seulement une augmentation du nombre de modèles candidats, mais également d'où l'augmentation du temps d'entraînement des modèles.

Étape 7 : Évaluez la précision des prévisions en fonction d'un espace de recherche d'hyperparamètres plus petit

SELECT
  AVG(mean_absolute_percentage_error) AS MAPE,
  AVG(symmetric_mean_absolute_percentage_error) AS sMAPE
FROM
  ML.EVALUATE(MODEL `bqml_tutorial.nyc_citibike_arima_model_max_order_2`,
              TABLE `bqml_tutorial.nyc_citibike_time_series`,
              STRUCT(7 AS horizon, TRUE AS perform_aggregation))

Cette requête renvoie les résultats suivants : pour les EAMP : 0,3337, pour les EAMSP : 0,2337.

À l'étape 5, l'utilisation d'un espace de recherche d'hyperparamètres plus grand (auto_arima_max_order = 5) a résulté en un MAPE de 0,3471 et un sMAPE de 0,2563. Par conséquent, dans ce cas spécifique, un plus petit espace de recherche d'hyperparamètres permet en fait d'améliorer la précision des prévisions. Une raison expliquant ce comportement est que l'algorithme auto.ARIMA n'effectue le réglage des hyperparamètres que pour le module de tendance de l'ensemble du pipeline de modélisation. Le meilleur modèle ARIMA sélectionné par l'algorithme auto.ARIMA peut ne pas générer les meilleurs résultats de prévision pour l'ensemble du pipeline.

Étape 8 : Prévoir plusieurs séries temporelles simultanément avec un espace de recherche d'hyperparamètres plus petit et des stratégies d'entraînement rapides et intelligentes

Au cours de cette étape, vous utilisez un espace de recherche d'hyperparamètres plus petit avec une stratégie d'entraînement rapide et intelligent et en utilisant une ou plusieurs des options d'entraînement max_time_series_length, max_time_series_length ou time_series_length_fraction.

Bien que la modélisation périodique (par exemple la saisonnalité) nécessite un certain nombre de points temporels, la modélisation des tendances en nécessite moins. D'un autre côté, la modélisation des tendances est beaucoup plus coûteuse en ressources de calcul que les autres composants de séries temporelles tels que la saisonnalité. En utilisant les options d'entraînement rapide ci-dessus, vous pouvez modéliser efficacement le composant de tendance avec un sous-ensemble de séries temporelles, tandis que les autres composants de séries temporelles utilisent l'intégralité des séries temporelles.

Cet exemple utilise max_time_series_length pour effectuer un entraînement rapide.

CREATE OR REPLACE MODEL `bqml_tutorial.nyc_citibike_arima_model_max_order_2_fast_training`
OPTIONS
  (model_type = 'ARIMA_PLUS',
   time_series_timestamp_col = 'date',
   time_series_data_col = 'num_trips',
   time_series_id_col = 'start_station_name',
   auto_arima_max_order = 2,
   max_time_series_length = 30
  ) AS
SELECT *
FROM `bqml_tutorial.nyc_citibike_time_series`
WHERE date < '2016-06-01'

L'option max_time_series_length a une valeur de 30, ce qui signifie que pour chacune des 383 séries temporelles, seuls les 30 points temporels les plus récents sont utilisés pour modéliser le composant de tendance. Cela dit, la modélisation de composants autres que le composant de tendance utilise toujours l'intégralité des séries temporelles.

Pour exécuter la requête, procédez comme suit :

  1. Dans la console Google Cloud, cliquez sur le bouton Saisir une nouvelle requête.

  2. Saisissez la requête GoogleSQL suivante dans la zone de texte Éditeur de requête.

  3. Cliquez sur Exécuter.

    L'exécution de la requête prend environ 35 secondes. Cette méthode est trois fois plus rapide que la requête d'entraînement qui n'utilise pas ma stratégie d'entraînement rapide (elle se termine en une minute et 45 secondes). Notez qu'en raison de la surcharge de temps constante de la partie non-entraînement de la requête (prétraitement des données, etc.), le gain de temps sera bien plus important si vous utilisez un nombre de séries temporelles plus important que dans le cas présent. Pour un million de séries temporelles, le gain de temps se rapproche du rapport entre la longueur de la série temporelle et la valeur de max_time_series_length. Dans ce cas, le gain de temps sera plus de 10 fois supérieur.

Étape 9 : Évaluer la précision des prévisions pour un modèle comportant un espace de recherche d'hyperparamètres plus petit et des stratégies d'entraînement rapides et intelligentes

SELECT
  AVG(mean_absolute_percentage_error) AS MAPE,
  AVG(symmetric_mean_absolute_percentage_error) AS sMAPE
FROM
  ML.EVALUATE(MODEL `bqml_tutorial.nyc_citibike_arima_model_max_order_2_fast_training`,
              TABLE `bqml_tutorial.nyc_citibike_time_series`,
              STRUCT(7 AS horizon, TRUE AS perform_aggregation))

Cette requête renvoie les résultats suivants : pour les EAMP : 0,3515, pour les EAMSP : 0,2473.

Rappelez-vous que, sans l'utilisation de stratégies d'entraînement rapides, les résultats de la précision des prévisions sont pour les EAMP de 0,3337, pour les EAMSP de 0,2337. La différence entre les deux ensembles de valeurs de métriques est de 3 %, ce qui n'est pas significatif d'un point de vue statistique.

En résumé, vous avez utilisé un espace de recherche d'hyperparamètres plus petit et des stratégies d'entraînement rapide et intelligent pour entraîner votre modèle jusqu'à deux fois plus rapidement sans sacrifier la précision des prévisions. Comme indiqué précédemment, avec un plus grand nombre de séries temporelles, le gain de temps généré par les stratégies d'entraînement rapide peut être considérablement plus élevé. De plus, la bibliothèque ARIMA sous-jacente utilisée par ARIMA_PLUS a été optimisée pour fonctionner cinq fois plus rapidement qu'avant. Ensemble, ces gains permettent de prévoir des millions de séries temporelles en seulement quelques heures.

Étape 10 : Prévoir plus d'un million de séries temporelles

Dans cette étape, vous prévoyez les ventes de plus d'un million de produits alcoolisés dans différents magasins en utilisant les données publiques sur les ventes d'alcool de l'Iowa.

CREATE OR REPLACE MODEL
  `bqml_tutorial.liquor_forecast_by_product`
OPTIONS(
  MODEL_TYPE = 'ARIMA_PLUS',
  TIME_SERIES_TIMESTAMP_COL = 'date',
  TIME_SERIES_DATA_COL = 'total_bottles_sold',
  TIME_SERIES_ID_COL = ['store_number', 'item_description'],
  HOLIDAY_REGION = 'US',
  AUTO_ARIMA_MAX_ORDER = 2,
  MAX_TIME_SERIES_LENGTH = 30
) AS
SELECT
  store_number,
  item_description,
  date,
  SUM(bottles_sold) as total_bottles_sold
FROM
  `bigquery-public-data.iowa_liquor_sales.sales`
WHERE date BETWEEN DATE("2015-01-01") AND DATE("2021-12-31")
GROUP BY store_number, item_description, date

L'entraînement du modèle utilise toujours un petit espace de recherche d'hyperparamètres ainsi que la stratégie d'entraînement rapide et intelligent. L'exécution de la requête prend environ une heure et 16 minutes.

Effectuer un nettoyage

Pour éviter que les ressources utilisées lors de ce tutoriel soient facturées sur votre compte Google Cloud, supprimez le projet contenant les ressources, ou conservez le projet et supprimez les ressources individuelles.

  • Supprimez le projet que vous avez créé.
  • Ou conservez le projet et supprimez l'ensemble de données.

Supprimer l'ensemble de données

La suppression de votre projet entraîne celle de tous les ensembles de données et de toutes les tables qui lui sont associés. Si vous préférez réutiliser le projet, vous pouvez supprimer l'ensemble de données que vous avez créé dans ce tutoriel :

  1. Si nécessaire, ouvrez la page BigQuery dans Cloud Console.

    Accéder à BigQuery

  2. Dans le panneau de navigation, cliquez sur l'ensemble de données bqml_tutorial que vous avez créé.

  3. Cliquez sur Supprimer l'ensemble de données pour supprimer l'ensemble de données, la table, ainsi que toutes les données.

  4. Dans la boîte de dialogue Supprimer l'ensemble de données, confirmez la commande de suppression en saisissant le nom de votre ensemble de données (bqml_tutorial), puis cliquez sur Supprimer.

Supprimer votre projet

Pour supprimer le projet :

  1. Dans la console Google Cloud, accédez à la page Gérer les ressources.

    Accéder à la page Gérer les ressources

  2. Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur Supprimer.
  3. Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur Arrêter pour supprimer le projet.

Étapes suivantes