Dans les scénarios de prévision réels, il est courant de générer des prévisions distinctes pour plusieurs catégories, telles que les pays, les points de vente ou les lignes de produits. Cette leçon explique comment mettre à l'échelle la prévision de série temporelle dans de nombreux groupes de ce type à l'aide du paramètre group_key dans SAP HANA PAL et de la logique de boucle personnalisée.
Entraînement du modèle avec l'algorithme AdditiveModelForecast
Le client d'apprentissage automatique Python pour SAP HANA (hana-ml) expose toutes les fonctions SAP HANA Predictive Analysis Library (PAL) ainsi que les fonctions Automated Predictive Library (APL) dans Python pour une utilisation basée sur les données de saisie SAP HANA DataFrames.
Ensuite, nous entraînons des modèles individuels à l'aide du même algorithme AdditiveModelForecast [1], comme nous l'avons fait pour le scénario de modèle de série temporelle univariée.
Cependant, nous spécifions maintenant le pays de résidence comme clé de groupe, qui fournit des modèles individuels pour chaque pays.
12amf = AdditiveModelForecast(massive=True)
amf.fit(data=hdf_overnightstays_agg, group_key='COUNTRYOFRESIDENCE')<hana_ml.algorithms.pal.tsa.additive_model_preast.AdditiveModelForecast à l'adresse 0x1d9c79d7020>
Prévision basée sur une série temporelle - Individuellement par pays
Nous créons un DataFrame SAP HANA qui contient les dates/mois pour lesquels nous voulons créer une prévision.
Ensuite, nous commençons par identifier le mois le plus récent à partir de l'historique de la formation.
1234str_lastdate = hdf_overnightstays_agg.tail(1, ref_col='MONTH').collect().iloc[0,0]
str_lastdate = str(str_lastdate)[0:10]
print(str_lastdate)2024-05-01
Maintenant, nous créons un DataFrame SAP HANA qui contient le premier jour des mois souhaités pour la prévision.
123456months_to_forecast=12
hdf_overnightstays_future = binomial(conn, n=1, p=1, num_random=months_to_forecast)
hdf_overnightstays_future = hdf_overnightstays_future.select('*', (f'''ADD_MONTHS(TO_DATE ('{str_lastdate}', 'YYYY-MM-DD'), ID+1)''', 'MONTH') )
hdf_overnightstays_future = hdf_overnightstays_future.select('MONTH', ('0', 'TARGET'))
hdf_overnightstays_future.head(10).collect()| MOIS | CIBLE | |
|---|---|---|
| 0 | 2024-06-01 | 0 |
| 1 | 2024-07-01 | 0 |
| 2 | 2024-08-01 | 0 |
| 3 | 2024-09-01 | 0 |
| 4 | 2024-10-01 | 0 |
| 5 | 2024-11-01 | 0 |
| 6 | 2024-12-01 | 0 |
| 7 | 2025-01-01 | 0 |
| 8 | 2025-02-01 | 0 |
| 9 | 2025-03-01 | 0 |
Ensuite, nous créons un DataFrame SAP HANA qui contient les pays pour lesquels des prévisions doivent être fournies.
123hdf_overnightstays_countries = hdf_overnightstays.agg([('sum', 'OVERNIGHTSTAYS', 'TOTAL' )], group_by='COUNTRYOFRESIDENCE' ) \
.sort('TOTAL', desc=True).select('COUNTRYOFRESIDENCE').head(10)
hdf_overnightstays_countries.collect()| COUNTRYOFRESIDENCE | |
|---|---|
| 0 | Suisse |
| 1 | Allemagne |
| 2 | United States |
| 3 | Royaume-Uni |
| 4 | France |
| 5 | Italie |
| 6 | Pays-Bas |
| 7 | Belgique |
| 8 | Inde |
| 9 | Espagne |
Ensuite, nous combinons les deux DataFrames SAP HANA ci-dessus pour créer un nouveau DataFrame contenant les dates/mois futurs pour chaque pays.
123hdf_overnightstays_topredict = hdf_overnightstays_future.add_id().set_index('ID').join(hdf_overnightstays_countries.add_id('ID').set_index('ID'), how='cross' )
hdf_overnightstays_topredict = hdf_overnightstays_topredict.drop('ID')
hdf_overnightstays_topredict.head(10).collect()| MOIS | CIBLE | COUNTRYOFRESIDENCE | |
|---|---|---|---|
| 0 | 01/06/2024 | 0 | Suisse |
| 1 | 01/06/2024 | 0 | Allemagne |
| 2 | 01/06/2024 | 0 | United States |
| 3 | 01/06/2024 | 0 | Royaume-Uni |
| 4 | 01/06/2024 | 0 | France |
| 5 | 01/06/2024 | 0 | Italie |
| 6 | 01/06/2024 | 0 | Pays-Bas |
| 7 | 01/06/2024 | 0 | Belgique |
| 8 | 01/06/2024 | 0 | Inde |
| 9 | 01/06/2024 | 0 | Espagne |
Application du modèle pour générer des prévisions
Ensuite, nous évaluons le modèle de série temporelle entraîné pour créer des prévisions pour les pays individuels pour les dates indiquées.
12hdf_overnightstays_pred = amf.predict(data=hdf_overnightstays_topredict, group_key='COUNTRYOFRESIDENCE')
hdf_overnightstays_predicted = hdf_overnightstays_pred[0]Nous pouvons examiner les détails des composants de la prévision, c'est-à-dire la tendance, la saisonnalité, comme illustré ci-dessous :
1hdf_overnightstays_pred[1].collect()| ID GROUPE | MOIS | TENDANCE | SAISONAL | VACANCES | EXOGÉNEUF | |
|---|---|---|---|---|---|---|
| 0 | Belgique | 01/06/2024 | 46941,398949 | {"saisonnalités":3149.2922197280824} | {} | {} |
| 1 | Belgique | 01/07/2024 | 46645,399501 | {"saisonnalités":53969.69442748901} | {} | {} |
| 2 | Belgique | 01/08/2024 | 46339,533404 | {"saisonnalités":47670.95477129075} | {} | {} |
| 3 | Belgique | 01/09/2024 | 46033,667307 | {"saisonnalités":-10867.900939089028} | {} | {} |
| 4 | Belgique | 01/10/2024 | 45737,667859 | {"saisonnalités":-35024.826999824596} | {} | {} |
| ... | ... | ... | ... | ... | ... | ... |
| 115 | United States | 01/01/2025 | 256174,088611 | {"saisonnalités":-105260.40367463966} | {} | {} |
| 116 | United States | 01/02/2025 | 255710,827254 | {"saisonnalités":-107113.21705733694} | {} | {} |
| 117 | United States | 01/03/2025 | 255292,397641 | {"saisonnalités":-63771.189585235305} | {} | {} |
| 118 | United States | 2025-04-01 | 254829,136284 | {"saisonnalités":-74262.95570659888} | {} | {} |
| 119 | United States | 2025-05-01 | 254380,818842 | {"saisonnalités":35157.57804977409} | {} | {} |
120 lignes × 6 colonnes
Évaluation de l'exactitude
Nous vérifions s'il existe des erreurs comme suit :
1hdf_overnightstays_pred[2].collect()GROUP_ID ERROR_TIMESTAMP ERRORCODE MESSAGE
Nous tracons les prévisions spécifiquement pour l'Allemagne comme vu ci-dessous:
12forecast_line_plot(pred_data=hdf_overnightstays_predicted.filter(''' "GROUP_ID" = 'Germany' ''').drop('GROUP_ID').set_index('MONTH'),
confidence=("YHAT_LOWER", "YHAT_UPPER"), enable_plotly=True)
Maintenant, nous tracons les prévisions pour les États-Unis comme suit :
12forecast_line_plot(pred_data=hdf_overnightstays_predicted.filter(''' "GROUP_ID" = 'United States' ''').drop('GROUP_ID').set_index('MONTH'),
confidence=("YHAT_LOWER", "YHAT_UPPER"), enable_plotly=True)
Nous pouvons combiner le jeu de données historique utilisé pour entraîner le modèle et les valeurs prévisionnelles dans un seul DataFrame SAP HANA comme indiqué ci-dessous :
123456789hdf_overnightstays_predicted = hdf_overnightstays_predicted.select(
'MONTH',
('GROUP_ID', 'COUNTRYOFRESIDENCE'),
('NULL', 'OVERNIGHTSTAYS_SUM'),
('YHAT', 'FORECAST'),
('YHAT_LOWER', 'FORECAST_LOWER'),
('YHAT_UPPER', 'FORECAST_UPPER')
)
hdf_overnightstays_predicted.head(10).collect()| MOIS | COUNTRYOFRESIDENCE | SOMMES_HTSTAYS_OVERNIGHTSTAYS | PRÉVISION | FORECAST_LOWER | FORECAST_UPPER | |
|---|---|---|---|---|---|---|
| 0 | 01/06/2024 | Belgique | Aucune | 50090,691169 | 47179,354589 | 52902,229641 |
| 1 | 01/07/2024 | Belgique | Aucune | 100615,093928 | 97772,912096 | 103203,241535 |
| 2 | 01/08/2024 | Belgique | Aucune | 94010,488175 | 91129,243296 | 96876,143447 |
| 3 | 01/09/2024 | Belgique | Aucune | 35165,766368 | 32295,303313 | 38081,503388 |
| 4 | 01/10/2024 | Belgique | Aucune | 10712,840859 | 7792,914224 | 13545,382103 |
| 5 | 01/11/2024 | Belgique | Aucune | 15575,706973 | 12869,710511 | 18361,714953 |
| 6 | 01/12/2024 | Belgique | Aucune | 43761,773402 | 40908,291509 | 46512,689291 |
| 7 | 01/01/2025 | Belgique | Aucune | 22965,282178 | 20305,025961 | 25710,640517 |
| 8 | 01/02/2025 | Belgique | Aucune | 36852,832053 | 33948,725286 | 39735,768094 |
| 9 | 01/03/2025 | Belgique | Aucune | 42565,990727 | 39522,284487 | 45665,217573 |
123456hdf_overnightstays_agg = hdf_overnightstays_agg.select('*', ('NULL', 'FORECAST'),
('NULL', 'FORECAST_LOWER'),
('NULL', 'FORECAST_UPPER')
)
hdf_overnightstays_all = hdf_overnightstays_predicted.union(hdf_overnightstays_agg)
hdf_overnightstays_all.sort('MONTH').tail(20).collect()| MOIS | COUNTRYOFRESIDENCE | SOMMES_HTSTAYS_OVERNIGHTSTAYS | PRÉVISION | FORECAST_LOWER | FORECAST_UPPER | |
|---|---|---|---|---|---|---|
| 0 | 01/04/2025 | Italie | Aucune | 7.301358e+04 | 6.667947e+04 | 7.887995e+04 |
| 1 | 01/04/2025 | United States | Aucune | 1.805662e+05 | 1.680320e+05 | 1.921834e+05 |
| 2 | 01/04/2025 | Royaume-Uni | Aucune | 9.974975e+04 | 9.186932e+04 | 1.070457e+05 |
| 3 | 01/04/2025 | Belgique | Aucune | 2.574547e+04 | 2.259784e+04 | 2.862533e+04 |
| 4 | 01/04/2025 | Suisse | Aucune | 1.378666e+06 | 1.322983e+06 | 1,430933e+06 |
| 5 | 01/04/2025 | Espagne | Aucune | 3.213217e+04 | 2.940963e+04 | 3.476349e+04 |
| 6 | 01/04/2025 | Inde | Aucune | 6.515502e+04 | 5.293711e+04 | 7.653153e+04 |
| 7 | 01/04/2025 | Allemagne | Aucune | 2.407886e+05 | 2.251664e+05 | 2.552813e+05 |
| 8 | 01/04/2025 | France | Aucune | 1.020115e+05 | 9.917646e+04 | 1.046622e+05 |
| 9 | 01/04/2025 | Pays-Bas | Aucune | 3.838326e+04 | 3.441906e+04 | 4.207428e+04 |
| 10 | 01/05/2025 | United States | Aucune | 2.895384e+05 | 2.755186e+05 | 3.024338e+05 |
| 11 | 01/05/2025 | Italie | Aucune | 6.399058e+04 | 5.780458e+04 | 6.952312e+04 |
| 12 | 01/05/2025 | Royaume-Uni | Aucune | 1.080254e+05 | 9.963275e+04 | 1.155868e+05 |
| 13 | 01/05/2025 | Suisse | Aucune | 1.502996e+06 | 1,445847e+06 | 1,553558e+06 |
| 14 | 01/05/2025 | Inde | Aucune | 1.180078e+05 | 1.052617e+05 | 1.293825e+05 |
| 15 | 01/05/2025 | France | Aucune | 1,204332e+05 | 1.173433e+05 | 1.233076e+05 |
| 16 | 01/05/2025 | Espagne | Aucune | 3,689542e+04 | 3.382324e+04 | 3.987497e+04 |
| 17 | 01/05/2025 | Pays-Bas | Aucune | 5.181526e+04 | 4.768336e+04 | 5.550257e+04 |
| 18 | 01/05/2025 | Allemagne | Aucune | 2.789746e+05 | 2.621818e+05 | 2.946275e+05 |
| 19 | 01/05/2025 | Belgique | Aucune | 1.842008e+04 | 1.533416e+04 | 2.117920e+04 |
Le cas échéant, nous pouvons sauvegarder le jeu de données fusionné dans une table dans SAP HANA Cloud. Par exemple, SAP Analytics Cloud peut accéder à ces données.
1hdf_overnightstays_all.save('OVERNIGHTSTAYS_FORECAST_COUNTRIES', force=True)<hana_ml.dataframe.DataFrame à l'adresse 0x1d9c79d69f0>
Enfin, nous tracons l'ensemble du jeu de données, c'est-à-dire les valeurs et prévisions historiques, pour un seul pays - dans ce cas, pour l'Allemagne.
1hdf_overnightstays_data = hdf_overnightstays_all.filter('''"COUNTRYOFRESIDENCE" = 'Germany' ''').collect()12345678910111213fig, ax = plt.subplots()
ax.fill_between(hdf_overnightstays_data['MONTH'].values,
hdf_overnightstays_data['FORECAST_LOWER'].values,
hdf_overnightstays_data['FORECAST_UPPER'].values, alpha=0.2)
ax.plot(hdf_overnightstays_data['MONTH'].values,
hdf_overnightstays_data['OVERNIGHTSTAYS_SUM'].values, '-')
plt.xticks(rotation=45)
plt.xlabel("MONTH")
plt.ylabel("OVERNIGHTSTAYS")
plt.grid()
plt.show()