ML Atlas

02 · Dane · 4 min czytania · aktualizacja

Czym różnią się dane szeregów czasowych i jak poprawnie walidować prognozy?

W skrócie

W szeregu czasowym kolejność niesie informację, a sąsiednie wartości są zależne. Losowy podział przecieka przyszłością i daje fałszywie dobre wyniki.

Co to jest

Szereg czasowy to ciąg obserwacji tej samej wielkości uporządkowanych w czasie: dzienna sprzedaż, godzinowe zużycie prądu, kurs akcji, tętno co sekundę. W odróżnieniu od zwykłej tabeli kolejność wierszy jest tu częścią danych, a sąsiednie obserwacje są ze sobą powiązane — dzisiejsza temperatura mówi dużo o jutrzejszej.

Typowe składniki szeregu to trend (długookresowy kierunek), sezonowość (powtarzający się wzór, np. tygodniowy lub roczny), cykle o nieregularnej długości i szum. Zadaniem jest najczęściej prognoza przyszłych wartości, ale także wykrywanie anomalii czy klasyfikacja całych przebiegów.

Intuicja: przewidywanie jutrzejszej pogody na podstawie przetasowanych dni z całego roku byłoby oszustwem — model „widziałby” dni z przyszłości otaczające dzień, który ma przewidzieć.

Mechanizm — dlaczego tak działa

Większość metod uczenia maszynowego zakłada, że przykłady są niezależne i pochodzą z tego samego rozkładu. Szereg czasowy łamie oba założenia. Obserwacje są autokorelowane: wartość w chwili t silnie zależy od wartości w t − 1. A rozkład bywa niestacjonarny: średnia, wariancja czy sezonowość zmieniają się w czasie.

Autokorelacja sprawia, że losowy podział na zbiór treningowy i testowy jest wyciekiem. Każdy punkt testowy ma w treningu sąsiadów z obu stron, prawie identycznych, więc model interpoluje zamiast prognozować. Walidacja daje wtedy znakomite wyniki, które znikają w pierwszym dniu wdrożenia. Poprawny schemat to walidacja w przód (walk-forward, time series split): ucz na przeszłości, testuj na następnym okresie, przesuń okno i powtórz. Między treningiem a testem warto zostawić przerwę równą horyzontowi prognozy.

Niestacjonarność ma dwa skutki. Po pierwsze, model nauczony na jednym okresie może nie pasować do następnego — stąd potrzeba monitorowania i regularnego douczania. Po drugie, dwie niezależne niestacjonarne serie (np. błądzenia losowe) często wykazują silną korelację, która nic nie znaczy — klasyczna „regresja pozorna” (Granger i Newbold, 1974). Dlatego zależności między szeregami bada się zwykle na różnicach (zmianach), a nie na poziomach.

Modele uczenia maszynowego dostają szereg czasowy w postaci tabeli cech: opóźnień (wartość z t − 1, t − 7), statystyk kroczących (średnia z ostatnich 7 dni), cech kalendarzowych (dzień tygodnia, święta). Każda z tych cech musi korzystać wyłącznie z informacji dostępnej w chwili prognozy. Trzeba też pamiętać, że drzewa decyzyjne i lasy losowe nie ekstrapolują — przewidują wartości z zakresu widzianego w treningu, więc przy trendzie potrzebują różnicowania lub połączenia z modelem liniowym.

Zawsze warto mieć prognozę naiwną jako punkt odniesienia: „jutro będzie tak jak dziś” albo „jak tydzień temu”. Zaskakująco często trudno ją pobić.

Na przykładzie

Symulujemy błądzenie losowe: 1000 kroków, każda zmiana losowana z rozkładu normalnego N(0, 1). Prognoza naiwna (następna wartość = ostatnia) ma średni błąd bezwzględny 0,78 — zgodnie z teorią, bo E|N(0, 1)| ≈ 0,80, a lepiej się nie da, bo kolejne zmiany są nieprzewidywalne. Las losowy, któremu podajemy tylko numer kroku jako cechę, w 5-krotnej walidacji z losowym podziałem osiąga błąd 0,65 — pozornie lepiej niż naiwna prognoza, czyli lepiej niż to możliwe. Przy walidacji w przód ten sam model ma błąd 5,22: nie umie nic poza interpolacją między sąsiadami.

Las losowy na pięciu opóźnieniach daje 0,85 przy losowym podziale, ale 2,89 przy walidacji w przód — szereg w przyszłości wychodzi poza zakres widziany w treningu, a drzewa nie ekstrapolują. Regresja liniowa na tych samych opóźnieniach ma 0,80, praktycznie tyle co prognoza naiwna. Pozorne korelacje też wychodzą od razu: dla 200 par niezależnych błądzeń losowych (po 500 kroków) mediana |r| wynosi 0,38, a w 38% par |r| przekracza 0,5. Dla par niezależnych szumów bez sumowania mediana to 0,03.

W praktyce

  • Walidacja: TimeSeriesSplit(n_splits=5, gap=...) w scikit-learn; nigdy KFold(shuffle=True) dla prognoz.
  • Cechy w pandas: df['y'].shift(1), df['y'].rolling(7).mean().shift(1), df.index.dayofweek; shift przed rolling, by nie użyć bieżącej wartości.
  • Stacjonarność: różnicowanie df['y'].diff(), logarytm dla wzrostu procentowego; test ADF w statsmodels.tsa.stattools.adfuller.
  • Modele klasyczne: ARIMA/SARIMA i ETS w statsmodels; dla wielu serii często gradient boosting na cechach opóźnionych; sieci rekurencyjne i transformery przy dużych danych.
  • Zawsze porównuj z prognozą naiwną i sezonową naiwną.
  • Typowy błąd: skalowanie lub imputacja na całym szeregu przed podziałem — statystyki z przyszłości trafiają do treningu.

Najczęstsze pytania

Dlaczego nie można losowo dzielić szeregu czasowego?
Bo sąsiednie obserwacje są prawie identyczne, a model dostaje w treningu wartości z przyszłości względem punktu testowego. Ocena mierzy wtedy umiejętność interpolacji, a nie prognozowania, i jest zawyżona.
Co to jest stacjonarność i po co ona?
Szereg stacjonarny ma stałe w czasie własności statystyczne: średnią, wariancję i strukturę autokorelacji. Wiele metod klasycznych to zakłada, a relacje między szeregami niestacjonarnymi bywają pozorne. Różnicowanie często zamienia szereg niestacjonarny w stacjonarny.
Czy sieci neuronowe są najlepsze do prognoz?
Nie zawsze. Na pojedynczych, krótkich szeregach proste metody statystyczne i prognoza naiwna często wygrywają. Sieci i gradient boosting przewyższają je głównie przy wielu powiązanych seriach i bogatych cechach zewnętrznych.

Źródła

  • Hyndman R. J., Athanasopoulos G. „Forecasting: Principles and Practice”, 3rd ed., OTexts, 2021, https://otexts.com/fpp3/
  • Box G. E. P., Jenkins G. M. „Time Series Analysis: Forecasting and Control”. Holden-Day, 1970.
  • Granger C. W. J., Newbold P. (1974). „Spurious regressions in econometrics”. Journal of Econometrics, 2(2), 111–120.
  • Géron A. „Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow”, 3rd ed., 2022, rozdz. 15.
  • Dokumentacja scikit-learn: Time Series Split, https://scikit-learn.org/stable/modules/cross_validation.html#time-series-split

Zobacz też