--- title: Naive2 model keywords: fastai sidebar: home_sidebar summary: "Common benchmark model." description: "Common benchmark model." nb_path: "nbs/models_naive2__naive2.ipynb" ---
{% raw %}
{% endraw %} {% raw %}
{% endraw %}

# Naive Benchmark Model

> API details.

{% raw %}

## `class` `Naive`[source]

> `Naive`()

Naive model. This benchmark model produces a forecast that is equal to the last observed value for a given time series.

{% endraw %} {% raw %}
{% endraw %}

# Seasonal Naive Benchmark Model

> API details.

{% raw %}

## `class` `SeasonalNaive`[source]

> `SeasonalNaive`()

Seasonal Naive model. This benchmark model produces a forecast that is equal to the last observed value of the same season for a given time series.

{% endraw %} {% raw %}
{% endraw %}

# Naive2 Benchmark Model

> API details.

The Naive2 benchmark model, as explained in the M4 guide is determined by the following process:- Test the time-series for seasonal patterns by performing a 90% auto-correlation.

- Based on the test select between a Naive benchmark (random walk) or a spline detrended seasonal forecast.

{% raw %}

#### `detrend`[source]

> `detrend`(`insample_data`)

Calculates a & b parameters of LRL :param insample_data: :return:

{% endraw %} {% raw %}

#### `deseasonalize`[source]

> `deseasonalize`(`original_ts`, `ppy`)

Calculates and returns seasonal indices :param original_ts: original data :param ppy: periods per year :return:

{% endraw %} {% raw %}

#### `moving_averages`[source]

> `moving_averages`(`ts_init`, `window`)

Calculates the moving averages for a given TS :param ts_init: the original time series :param window: window length :return: moving averages ts

{% endraw %} {% raw %}

#### `seasonality_test`[source]

> `seasonality_test`(`original_ts`, `ppy`)

Seasonality test :param original_ts: time series :param ppy: periods per year :return: boolean value: whether the TS is seasonal

{% endraw %} {% raw %}

#### `acf`[source]

> `acf`(`data`, `k`)

Autocorrelation function :param data: time series :param k: lag :return:

{% endraw %} {% raw %}
{% endraw %} {% raw %}

## `class` `Naive2`[source]

> `Naive2`(`seasonality`)

Naive2 model. Popular benchmark model for time series forecasting that automatically adapts to the potential seasonality of a series based on an autocorrelation test. If the series is seasonal the model composes the predictions of Naive and SeasonalNaive, else the model predicts on the simple Naive.

{% endraw %} {% raw %}
{% endraw %}

# Naive Benchmark Usage Example

{% raw %}

    import pandas as pd
    from nixtlats.data.datasets.epf import EPF, EPFInfo
    from nixtlats.data.tsloader import TimeSeriesLoader

    import pylab as plt
    from pylab import rcParams
    plt.style.use('seaborn-whitegrid')
    plt.rcParams['font.family'] = 'serif'

    FONTSIZE = 17

    # Load and plot data
    Y_df, X_df, S_df = EPF.load_groups(directory='./data', groups=['NP'])

    fig = plt.figure(figsize=(15, 6))
    plt.plot(Y_df.ds, Y_df.y.values, color='#628793', linewidth=0.4)
    plt.ylabel('Price [EUR/MWh]', fontsize=15)
    plt.xlabel('Date', fontsize=15)
    # plt.savefig('./results/NP.png', bbox_inches = 'tight')
    plt.show()

    100%|██████████| 2.12M/2.12M [00:00<00:00, 3.30MiB/s]
    INFO:nixtla.data.datasets.utils:Successfully downloaded NP.csv, 2118914, bytes.
    100%|██████████| 2.53M/2.53M [00:00<00:00, 3.46MiB/s]
    INFO:nixtla.data.datasets.utils:Successfully downloaded PJM.csv, 2530311, bytes.
    100%|██████████| 1.97M/1.97M [00:00<00:00, 2.74MiB/s]
    INFO:nixtla.data.datasets.utils:Successfully downloaded BE.csv, 1974555, bytes.
    100%|██████████| 2.00M/2.00M [00:00<00:00, 3.15MiB/s]
    INFO:nixtla.data.datasets.utils:Successfully downloaded FR.csv, 1996871, bytes.
    100%|██████████| 2.10M/2.10M [00:00<00:00, 2.82MiB/s]
    INFO:nixtla.data.datasets.utils:Successfully downloaded DE.csv, 2095831, bytes.

{% endraw %} {% raw %}

    from itertools import chain
    from multiprocessing import Pool
    from numpy.lib.stride_tricks import sliding_window_view
    from nixtlats.losses.numpy import mae

    def fit_predict_naive2(Y, output_size=24, seasonality=24):
        y_hat_list = []
        for idx in range(len(Y)):
            y_id = Y[idx, :]
            y_hat_id = Naive2(seasonality).fit(y_id).predict(output_size)
            y_hat_list += [y_hat_id]
        return y_hat_list

    def parallelized_naive2(Y, n_cores=32):
        # Y
        n_partitions = n_cores**3//4  # number of partitions to split the array
        Y_split  = np.array_split(Y, n_partitions)
        pool = Pool(n_cores)
        Y_hat_list = list(chain.from_iterable(pool.map(fit_predict_naive2, Y_split)))
        pool.close()
        pool.join()
        Y_hat = np.vstack(Y_hat_list)
        return Y_hat

{% endraw %} {% raw %}

    Y_windows = sliding_window_view(Y_df.y.values, window_shape=24*7)
    day_idxs = (np.arange(len(Y_windows)) % 24) == 0
    Y_windows = Y_windows[day_idxs, :]
    print("Y_windows.shape", Y_windows.shape)

    Y_windows.shape (2178, 168)

{% endraw %} {% raw %}

    Y_hat = parallelized_naive2(Y=Y_windows)
    Y_hat = Y_hat.reshape(-1)
    Y_hat.shape

    (52272,)

{% endraw %} {% raw %}

    fig = plt.figure(figsize=(15, 6))
    plt.plot(Y_df.ds[168:], Y_df.y.values[168:], color='#628793', linewidth=0.4, label='true')
    plt.plot(Y_df.ds[168:], Y_hat[:len(Y_hat)-24], color='peru', linewidth=0.4, label='forecast')
    plt.ylabel('Price [EUR/MWh]', fontsize=15)
    plt.xlabel('Date', fontsize=15)
    plt.legend()
    # plt.savefig('./results/NP.png', bbox_inches = 'tight')
    plt.show()

{% endraw %} {% raw %}

    naive2_mae = mae(y=Y_df.y.values[168:], y_hat=Y_hat[:len(Y_hat)-24])
    print(f'MAE: {naive2_mae}')

    MAE: 2.5901857898968275

{% endraw %}