PacktPublishing / Modern-Time-Series-Forecasting-with-Python

Modern Time Series Forecasting with Python, published by Packt
MIT License
401 stars 209 forks source link

In implementation of Seasonal Decompose (STL) with FourierSeries, `max_cycle=np.max(seasonal_cycle)` is wrong? #33

Open Norlandz opened 6 months ago

Norlandz commented 6 months ago

For the Textbook's implementation of Seasonal Decompose (STL) with FourierSeries & RidgeCV.

(if I understood correctly) In .\src\decomposition\seasonal.py

class FourierDecomposition(BaseDecomposition):
...
    def _calculate_fourier_terms(self, seasonal_cycle: np.ndarray, max_cycle: int):
        """Calculates Fourier Terms given the seasonal cycle and max_cycle"""
        sin_X = np.empty((len(seasonal_cycle), self.n_fourier_terms), dtype="float64")
        cos_X = np.empty((len(seasonal_cycle), self.n_fourier_terms), dtype="float64")
        for i in range(1, self.n_fourier_terms + 1):
            sin_X[:, i - 1] = np.sin((2 * np.pi * seasonal_cycle * i) / max_cycle)
            cos_X[:, i - 1] = np.cos((2 * np.pi * seasonal_cycle * i) / max_cycle)
        return np.hstack([sin_X, cos_X])
...

    def _prepare_X(self, detrended, **seasonality_kwargs):
...
            seasonal_cycle = (getattr(date_index, self.seasonality_period)).values
        return self._calculate_fourier_terms(
            seasonal_cycle, max_cycle=np.max(seasonal_cycle)
        )

max_cycle=np.max(seasonal_cycle) is wrong

ie,eg: seasonal_cycle = df.index.dayofweek.values => we know: dayofweek gives 0,1,2,3,4,5,6 max_cycle=np.max(seasonal_cycle) => it takes 6 -- this is wrong it should take 7 as the max_cycle (-- the period in FourierSeries)

eg: For a comparison of a simple ex image using 7 clearly fits better than using 6.

eg: For a comparison of a the textbook energy_consumption data: image (this is not so obvious) (but you can see, if use 6, there are always 2 days sticks to the same level,, in each period)

manujosephv commented 6 months ago

Good catch! It definitely should be 7 and not 6. I'll add it to the errata and correct in the next edition. Can you help me with the chapter number and page number?

Norlandz commented 6 months ago

Good catch! It definitely should be 7 and not 6. I'll add it to the errata and correct in the next edition. Can you help me with the chapter number and page number?

Chapter 03 > Decomposing a time series > Fourier decomposition page 67 stl = FourierDecomposition(seasonality_period="hour", model = "additive", n_fourier_terms=5) Figure 3.16 - Decomposition using Fourier terms (zoomed-in for a month) Figure 3.17 - Multiple seasonality decomposition using Fourier terms Figure 3.18 - Multiple seasonality decomposition using Fourier terms (zoomed-in for a month)