JoaquinAmatRodrigo / skforecast

Time series forecasting with machine learning models
https://skforecast.org
BSD 3-Clause "New" or "Revised" License
992 stars 113 forks source link

Duda sobre backtesting_forecaster #733

Open LuisTellezSirocco opened 6 days ago

LuisTellezSirocco commented 6 days ago

Muy buenas,

Estoy empezando a usar esta librería y no sé si hay algo que no estoy haciendo correctamente.

La cuestión es la siguiente, para mí, cada vez que hago un forecast, es muy importante tener controlado el ahead, esto es, si tengo frecuencia horaria y necesito steps = 5, si empiezo a hacer forecasts desde aquí:

2023-12-02 01:00:00, tendré que:

start date ahead
0 2023-12-02 01:00:00 2023-12-02 01:00:00 1
1 2023-12-02 01:00:00 2023-12-02 02:00:00 2
2 2023-12-02 01:00:00 2023-12-02 03:00:00 3
3 2023-12-02 01:00:00 2023-12-02 04:00:00 4
4 2023-12-02 01:00:00 2023-12-02 05:00:00 5

Si he entendido bien, hacer algo como esto:

metrica, predicciones = backtesting_forecaster(
    gap=0, 
    forecaster=forecaster,
    y=data["obs"],
    exog=data[[x for x in data.columns if "PC" in x]],
    steps=5,
    metric="mean_absolute_error",
    initial_train_size=len(data[:fin_train]),
    refit=False,
    n_jobs="auto",
    verbose=True,
    show_progress=True,
) 

Genera una determinada validación basada en folds:

Information of backtesting process
----------------------------------
Number of observations used for initial training: 9411
Number of observations used for backtesting: 720
    Number of folds: 144
    Number of steps per fold: 5
    Number of steps to exclude from the end of each train set before test (gap): 0

Fold: 0
    Training:   2022-11-04 22:00:00 -- 2023-12-02 00:00:00  (n=9411)
    Validation: 2023-12-02 01:00:00 -- 2023-12-02 05:00:00  (n=5)
Fold: 1
    Training:   2022-11-04 22:00:00 -- 2023-12-02 00:00:00  (n=9411)
    Validation: 2023-12-02 06:00:00 -- 2023-12-02 10:00:00  (n=5)
Fold: 2
    Training:   2022-11-04 22:00:00 -- 2023-12-02 00:00:00  (n=9411)
    Validation: 2023-12-02 11:00:00 -- 2023-12-02 15:00:00  (n=5)
Fold: 3
    Training:   2022-11-04 22:00:00 -- 2023-12-02 00:00:00  (n=9411)
    Validation: 2023-12-02 16:00:00 -- 2023-12-02 20:00:00  (n=5)
   .....

Lo que voy buscando en definitiva es alguna manera de solapar los folds para conseguir algo como esto:

start date ahead
0 2023-12-02 01:00:00 2023-12-02 01:00:00 1
1 2023-12-02 01:00:00 2023-12-02 02:00:00 2
2 2023-12-02 01:00:00 2023-12-02 03:00:00 3
3 2023-12-02 01:00:00 2023-12-02 04:00:00 4
4 2023-12-02 01:00:00 2023-12-02 05:00:00 5
5 2023-12-02 02:00:00 2023-12-02 02:00:00 1
6 2023-12-02 02:00:00 2023-12-02 03:00:00 2
7 2023-12-02 02:00:00 2023-12-02 04:00:00 3
8 2023-12-02 02:00:00 2023-12-02 05:00:00 4
9 2023-12-02 02:00:00 2023-12-02 06:00:00 5

Poder avanzar el step en 1 a la vez que sigo haciendo 5 predicciones. Estoy intentando jugar con el parámetro Gap para ver si consigo hacer esto.. pero no estoy seguro de que sea lo correcto.

Gracias de antemano.

JavierEscobarOrtiz commented 6 days ago

Buenas @LuisTellezSirocco

Gracias por usar Skforecast! Actualmente no es posible solapar los folds con la función de backtesting. El tamaño del validation set siempre va a estar marcado por el argumento steps.

Con gap lo que consigues es comenzar las predicciones después de n obervaciones, pero el test de validación se mueve steps posiciones, de tal manera que la función recorre todas las observaciones 1 vez.

Backtesting_gap

Me gustaría enteder mejor cuál es la finalidad de generar más de una predicción para una misma fecha. Qué prediccion utilizas para calcular la métrica final?

Gracias!

LuisTellezSirocco commented 6 days ago

Muchas gracias por la respuesta @JavierEscobarOrtiz !

La cuestión vendría más porque espero una degradación considerable del modelo conforme aumenta el ahead, y puesto que tengo otros modelos funcionando de otras maneras sin depender de datos "real time", estoy buscando hacer una optimización que permita "unir" ambos modelos, en base al ahead del modelo ARR. Por tanto, ese "solapamiento", me permitiría usar menos datos reales para llevar a cabo dicha optimización...

Espero haberme explicado correctamente, un saludo!