Skip to content
AI360Xpert

Time Series Fundamentals

A time series is a sequence of observations indexed by time — and forecasting it requires understanding the patterns hidden in that sequence: trends, seasonality, cycles, and noise, each requiring different modeling approaches.

A time series is a sequence of observations indexed by time — and forecasting it requires understanding the patterns hidden in that sequence: trends, seasonality, cycles, and noise, each requiring different modeling approaches.
A time series is a sequence of observations indexed by time — and forecasting it requires understanding the patterns hidden in that sequence: trends, seasonality, cycles, and noise, each requiring different modeling approaches.

Why Does This Exist?

Time-ordered data requires different treatment than cross-sectional data. Standard ML assumes i.i.d. (independent and identically distributed) samples. Time series observations violate this: tomorrow's temperature depends on today's; next quarter's sales depend on last quarter's patterns. Applying standard ML without accounting for temporal dependencies produces models that appear accurate but fail in deployment.

Time series problems appear everywhere: demand forecasting for supply chains, energy consumption prediction, financial price prediction, patient vitals monitoring, network traffic anomaly detection.

Think of It Like This

A detective reading the history of a city

A time series is like reading a city's history: some patterns are long-term trends (population grew steadily from 1950 to 2020), some are seasonal (crime spikes in summer), some are cyclical (economic booms and busts every 7–10 years), and some are random events (a pandemic in 2020). A forecaster, like a detective, reads these overlapping patterns and extrapolates what comes next — while knowing that truly random events cannot be predicted.

How It Actually Works

The four components

A time series yty_t can be decomposed into:

yt=Tt+St+Ct+εty_t = T_t + S_t + C_t + \varepsilon_t

ComponentSymbolDescription
TrendTtT_tLong-run direction (up, down, flat)
SeasonalityStS_tPeriodic fluctuations with fixed period (weekly, annual)
CyclesCtC_tIrregular long-term oscillations (business cycles)
Noiseεt\varepsilon_tRandom, unpredictable variation

Alternatively, if the pattern amplifies over time (seasonal swings grow with the trend), use multiplicative decomposition: yt=Tt×St×Ct×εty_t = T_t \times S_t \times C_t \times \varepsilon_t.

Autocorrelation

The key statistical property that distinguishes time series: observations at time tt are correlated with observations at time tkt-k (lag kk).

Autocorrelation function (ACF): ρk=Corr(yt,ytk)\rho_k = \text{Corr}(y_t, y_{t-k})

If sales this week correlate with sales last week: ρ1>0\rho_1 > 0. If there's a weekly pattern, ρ7\rho_7 will be high. Plotting the ACF for all lags gives the correlogram, the first diagnostic tool for any time series.

Stationarity

A stationary time series has constant statistical properties over time: constant mean, constant variance, and ACF depending only on lag, not on time position.

E[yt]=μtVar(yt)=σ2t\mathbb{E}[y_t] = \mu \quad \forall t \qquad \text{Var}(y_t) = \sigma^2 \quad \forall t

Most forecasting models require stationarity. Non-stationary series (with trends or changing variance) must be transformed:

  • Differencing removes trends: Δyt=ytyt1\Delta y_t = y_t - y_{t-1}
  • Log transformation stabilizes variance: y~t=log(yt)\tilde{y}_t = \log(y_t)
  • Seasonal differencing removes seasonality: Δ12yt=ytyt12\Delta_{12} y_t = y_t - y_{t-12}

Code

import pandas as pdimport numpy as npimport matplotlibmatplotlib.use('Agg')  # non-interactive backend
# ── Generate synthetic time series ────────────────────────────────────────────np.random.seed(42)dates = pd.date_range("2020-01-01", periods=104, freq="W")
trend      = np.linspace(100, 200, 104)seasonality = 20 * np.sin(2 * np.pi * np.arange(104) / 52)noise      = np.random.normal(0, 5, 104)y = trend + seasonality + noise
ts = pd.Series(y, index=dates, name="weekly_sales")
# ── Basic statistics ──────────────────────────────────────────────────────────print("Time series summary:")print(f"  Length: {len(ts)} weeks")print(f"  Mean:   {ts.mean():.2f}")print(f"  Std:    {ts.std():.2f}")print(f"  Range:  [{ts.min():.2f}, {ts.max():.2f}]")
# ── Autocorrelation function ──────────────────────────────────────────────────from statsmodels.stats.stattools import durbin_watsonfrom pandas.plotting import autocorrelation_plot
# Manual ACF computationdef acf_values(series, max_lag=20):    acf = [1.0]  # lag 0    for k in range(1, max_lag + 1):        corr = np.corrcoef(series[k:], series[:-k])[0, 1]        acf.append(corr)    return acf
acf = acf_values(ts.values)print("\nACF values:")for lag, val in enumerate(acf[:10]):    print(f"  Lag {lag:>2}: {val:+.3f}")
# ── Classical decomposition ───────────────────────────────────────────────────from statsmodels.tsa.seasonal import seasonal_decompose
decomposition = seasonal_decompose(ts, model='additive', period=52)print("\nDecomposition components:")print(f"  Trend range:       [{decomposition.trend.dropna().min():.1f}, {decomposition.trend.dropna().max():.1f}]")print(f"  Seasonal range:    [{decomposition.seasonal.min():.1f}, {decomposition.seasonal.max():.1f}]")print(f"  Residual std:      {decomposition.resid.dropna().std():.2f}")
# ── Differencing to achieve stationarity ─────────────────────────────────────ts_diff = ts.diff().dropna()print(f"\nAfter first differencing:")print(f"  Mean: {ts_diff.mean():.4f} (≈0 → trend removed)")print(f"  Std:  {ts_diff.std():.2f}")

Watch Out For

Data leakage in train-test splits

With time series, you cannot randomly shuffle and split — the test set must be strictly after the training set in time. Using a random split leaks future information into training (the model sees data from "the future" during training), producing unrealistically optimistic metrics. Always split chronologically.

Assuming stationarity without testing

Many forecasting models (ARIMA, linear regression) assume stationarity. Applying them to a non-stationary series (trending, heteroskedastic) produces unreliable estimates. Always test stationarity (Augmented Dickey-Fuller or KPSS test) and apply the appropriate transformation before fitting.

The Quick Version

  • A time series is observations indexed by time — observations are not i.i.d.; they have temporal dependencies.
  • Four components: trend (long-run direction), seasonality (periodic pattern), cycles (irregular oscillations), noise.
  • Autocorrelation measures the correlation between a series and its own lagged values — the fundamental diagnostic.
  • Stationarity (constant mean and variance over time) is required by most classical forecasting models.
  • Transform non-stationary series: differencing removes trends, log transformation stabilizes variance.