Soothsayer.Trend (Soothsayer v0.6.1)
View SourceTrend component with optional piecewise linear changepoints.
Handles network building, feature engineering, and weight extraction for the trend.
The trend function with changepoints is:
trend(t) = k * t + m + sum(delta_j * max(0, t - s_j))Where:
k= base growth rate (learned)m= offset (learned)s_j= changepoint positions (computed from data, fixed)delta_j= rate adjustments at each changepoint (learned)
Summary
Functions
Builds changepoint feature tensor computing max(0, t - s_j) for each changepoint.
Builds the trend component layer.
Builds trend features tensor and metadata from dates.
Creates the Axon input node for the trend component.
Builds the complete trend input by concatenating t with changepoint features.
Computes evenly spaced changepoint indices within the first portion of data.
Computes changepoint positions as dates from the data.
Converts dates to numeric values (days since first date).
Extracts learned trend weights from a fitted model.
Converts numeric values back to dates.
Functions
@spec build_changepoint_features(Nx.Tensor.t(), [number()]) :: Nx.Tensor.t() | nil
Builds changepoint feature tensor computing max(0, t - s_j) for each changepoint.
Parameters
t- Tensor of time values with shape{n_samples, 1}.changepoint_positions- List of numeric changepoint positions.
Returns
A tensor of shape {n_samples, changepoints} with changepoint features.
Examples
iex> t = Nx.tensor([[1.0], [2.0], [3.0]])
iex> Soothsayer.Trend.build_changepoint_features(t, [1.5])
#Nx.Tensor<f32[3][1] [[0.0], [0.5], [1.5]]>
Builds the trend component layer.
Parameters
input- Axon input node frombuild_input/1.config- Model configuration map.
Returns
An Axon dense layer when enabled, or Axon.constant(0) when disabled.
@spec build_features([Date.t()], map()) :: {Nx.Tensor.t(), map()}
Builds trend features tensor and metadata from dates.
Parameters
dates- List of dates.config- Model configuration map with:trendkey.
Returns
A tuple {tensor, metadata} where:
tensorhas shape{n_dates, 1 + changepoints}metadatacontains:first_dateand:changepoint_positions
Examples
iex> dates = [~D[2023-01-01], ~D[2023-01-02], ~D[2023-01-03]]
iex> config = %{trend: %{changepoints: 0, changepoints_range: 0.8}}
iex> {tensor, metadata} = Soothsayer.Trend.build_features(dates, config)
iex> Nx.shape(tensor)
{3, 1}
iex> metadata.first_date
~D[2023-01-01]
Creates the Axon input node for the trend component.
Parameters
config- Model configuration map with:trendkey.
Returns
An Axon input node with shape {nil, 1 + changepoints}.
@spec build_trend_input(Nx.Tensor.t(), Nx.Tensor.t() | nil) :: Nx.Tensor.t()
Builds the complete trend input by concatenating t with changepoint features.
Parameters
t- Tensor of time values with shape{n_samples, 1}.changepoint_features- Tensor of changepoint features with shape{n_samples, changepoints}.
Returns
A tensor of shape {n_samples, 1 + changepoints}.
Examples
iex> t = Nx.tensor([[1.0], [2.0]])
iex> cp_features = Nx.tensor([[0.0, 0.0], [0.5, 0.0]])
iex> Soothsayer.Trend.build_trend_input(t, cp_features)
#Nx.Tensor<f32[2][3] [[1.0, 0.0, 0.0], [2.0, 0.5, 0.0]]>
@spec compute_changepoint_indices(non_neg_integer(), non_neg_integer(), float()) :: [ non_neg_integer() ]
Computes evenly spaced changepoint indices within the first portion of data.
Parameters
n_samples- Total number of samples in the dataset.changepoints- Number of changepoints to create.changepoints_range- Fraction of data to place changepoints in (0-1).
Returns
A list of indices where changepoints will be placed.
Examples
iex> Soothsayer.Trend.compute_changepoint_indices(100, 5, 0.8)
[16, 32, 48, 64, 80]
@spec compute_changepoint_positions([Date.t()], non_neg_integer(), float()) :: [ Date.t() ]
Computes changepoint positions as dates from the data.
Parameters
dates- List of dates in the dataset.changepoints- Number of changepoints to create.changepoints_range- Fraction of data to place changepoints in (0-1).
Returns
A list of dates where changepoints are positioned.
Examples
iex> dates = Enum.map(0..99, fn i -> Date.add(~D[2023-01-01], i) end)
iex> Soothsayer.Trend.compute_changepoint_positions(dates, 5, 0.8)
[~D[2023-01-17], ~D[2023-02-02], ~D[2023-02-18], ~D[2023-03-06], ~D[2023-03-22]]
@spec date_to_numeric([Date.t()], Date.t()) :: Nx.Tensor.t()
Converts dates to numeric values (days since first date).
Parameters
dates- List of dates.first_date- Reference date (typically first date in dataset).
Returns
A tensor of numeric values representing days since first_date.
Examples
iex> Soothsayer.Trend.date_to_numeric([~D[2023-01-01], ~D[2023-01-02]], ~D[2023-01-01])
#Nx.Tensor<f32[2] [0.0, 1.0]>
@spec get_weights(Soothsayer.Model.t()) :: %{ kernel: Nx.Tensor.t(), bias: Nx.Tensor.t() }
Extracts learned trend weights from a fitted model.
Parameters
model- A fittedSoothsayer.Modelstruct.
Returns
A map with :kernel and :bias tensors.
Converts numeric values back to dates.
Parameters
numeric- List of numeric values (days since first_date).first_date- Reference date.
Returns
A list of dates.
Examples
iex> Soothsayer.Trend.numeric_to_date([0.0, 1.0], ~D[2023-01-01])
[~D[2023-01-01], ~D[2023-01-02]]