Implementation:Online ml River Forecaster Learn One
| Knowledge Sources | Domains | Last Updated |
|---|---|---|
| River River Docs | Online Machine Learning, Time Series Forecasting, API Design | 2026-02-08 16:00 GMT |
Overview
Concrete tool documenting the learn_one interface method of the time_series.base.Forecaster class used by all River time series forecasters. Pattern Doc.
Description
The Forecaster.learn_one method is the abstract interface that all River time series forecasters must implement. It defines the contract for incrementally updating model state with a single new observation. This pattern doc describes the interface itself and how it is concretely realized by the two main forecaster implementations: SNARIMAX and HoltWinters.
The Forecaster base class inherits from base.Estimator and declares two abstract methods: learn_one and forecast. The learn_one method is marked with @abc.abstractmethod, ensuring that any subclass must provide a concrete implementation.
Usage
Reference this pattern when you need to understand how forecasters consume new observations, or when implementing a custom forecaster that must conform to the River Forecaster interface.
Code Reference
Source Location
river/time_series/base.py:L10-L27
Interface Signature
class Forecaster(base.Estimator):
@abc.abstractmethod
def learn_one(self, y: float, x: dict | None = None) -> None:
"""Updates the model.
Parameters
----------
y
In the literature this is called the endogenous variable.
x
Optional additional features to learn from. In the literature
these are called the exogenous variables.
"""
raise NotImplementedError
Import
from river import time_series
# The base class is at time_series.base.Forecaster
SNARIMAX.learn_one Implementation
Source: river/time_series/snarimax.py:L336-L350
def learn_one(self, y, x=None):
# Wait until enough history for differencing
if len(self.y_hist) >= self.differencer.n_required_past_values:
x = self._add_lag_features(x=x, Y=self.y_diff, errors=self.errors)
# Learn on the differenced series
y_diff = self.differencer.diff(y, self.y_hist)
self.y_diff.appendleft(y_diff)
y_pred = self.regressor.predict_one(x)
self.errors.appendleft(y_diff - y_pred)
self.regressor.learn_one(x, y_diff)
self.y_hist.appendleft(y)
HoltWinters.learn_one Implementation
Source: river/time_series/holt_winters.py:L187-L208
def learn_one(self, y, x=None):
if self._initialized:
self.level.update(y, self.trend, self.season)
if self.trend is not None:
self.trend.update(y, self.level)
if self.season is not None:
self.season.update(y, self.level, self.trend)
return
# Accumulate values for initialization
self._first_values.append(y)
if len(self._first_values) < max(2, self.seasonality):
return
# Initialize components from accumulated values
self.level.append(statistics.mean(self._first_values))
diffs = [b - a for a, b in zip(self._first_values[:-1], self._first_values[1:])]
if self.trend is not None:
self.trend.append(statistics.mean(diffs))
if self.season is not None:
self.season.extend([y / self.level[-1] for y in self._first_values])
self._initialized = True
I/O Contract
Inputs
| Parameter | Type | Description |
|---|---|---|
| y | float | The current time series observation (endogenous variable) |
| x | dict or None | Optional dictionary of exogenous features for this time step |
Outputs
| Return Type | Description |
|---|---|
| None | The model's internal state is updated in-place |
Usage Examples
Basic learn_one loop
from river import datasets
from river import time_series
model = time_series.SNARIMAX(p=12, d=1, q=12, m=12, sd=1)
for x, y in datasets.AirlinePassengers():
model.learn_one(y)
# Model state is updated with each observation
learn_one with exogenous features
from river import time_series
model = time_series.SNARIMAX(p=1, d=0, q=0, m=1)
# x provides exogenous features alongside the target y
model.learn_one(y=112, x={"temperature": 72.5, "holiday": 0})
model.learn_one(y=118, x={"temperature": 75.0, "holiday": 0})
model.learn_one(y=132, x={"temperature": 80.1, "holiday": 1})
HoltWinters learn_one with initialization phase
from river import time_series
model = time_series.HoltWinters(alpha=0.3, beta=0.1, gamma=0.6, seasonality=12)
# First 12 observations are used for initialization
for y in [112, 118, 132, 129, 121, 135, 148, 148, 136, 119, 104, 118]:
model.learn_one(y)
# After this loop, components are initialized
# Subsequent calls update components via exponential smoothing
model.learn_one(115)