Stl (ex_stl v0.1.0)
View Source A fast and reliable Elixir library for decomposing time series data using STL (Seasonal and Trend decomposition using Loess). This package provides Elixir bindings to the STL C++ library https://github.com/ankane/stl-cpp
using Fine to handle implementing the NIF.
It supports both Seasonal-trend and Multi Seasonal-trend decomposition using decompose/2
and decompose/3
respectively, with the ability to smooth outliers with robust
decomposition. See the docs for decompose/2
and decompose/3
for more details.
For a single seasonal trend, you can pass a list of values or a Date keyed map as the series.
# Decompose a simple list with a weekly seasonal pattern
series = [5.0, 9.0, 2.0, 9.0, 0.0, 6.0, 3.0, 8.0, 5.0, 8.0,
7.0, 8.0, 8.0, 0.0, 2.0, 5.0, 0.0, 5.0, 6.0, 7.0,
3.0, 6.0, 1.0, 4.0, 4.0, 4.0, 3.0, 7.0, 5.0, 8.0]
result = Stl.decompose(series, 7)
# Access the components
seasonal = result.seasonal
trend = result.trend
remainder = result.remainder
# Calculate strength measures
seasonal_strength = Stl.seasonal_strength(result)
trend_strength = Stl.trend_strength(result)
IO.puts("Seasonal strength: #{seasonal_strength}")
# Seasonal strength: 0.28411169658385693
IO.puts("Trend strength: #{trend_strength}")
# Trend strength: 0.16384239106781462
For multi seasonal trends, the second param should be an integer list of periods.
Stl.decompose(series, [7, 30])
Summary
Functions
Decompose a time series using STL (Seasonal and Trend decomposition using Loess).
Calculate the seasonal strength from a decomposition result.
Calculate the trend strength from a decomposition result.
Types
Functions
@spec decompose([number()] | map(), pos_integer() | [pos_integer()], Stl.Params.t()) :: t()
Decompose a time series using STL (Seasonal and Trend decomposition using Loess).
Parameters
series
- A list of numbers or a map with keys (e.g., dates) and values.:period
- REQUIRED: The period of the seasonal component (must be >= 2).opts
- Options for the decomposition::seasonal_length
- Length of the seasonal smoother.:trend_length
- Length of the trend smoother.:low_pass_length
- Length of the low-pass filter.:seasonal_degree
- Degree of locally-fitted polynomial in seasonal smoothing (0 or 1).:trend_degree
- Degree of locally-fitted polynomial in trend smoothing (0 or 1).:low_pass_degree
- Degree of locally-fitted polynomial in low-pass smoothing (0 or 1).:seasonal_jump
- Skipping value for seasonal smoothing.:trend_jump
- Skipping value for trend smoothing.:low_pass_jump
- Skipping value for low-pass smoothing.:inner_loops
- Number of loops for updating the seasonal and trend components.:outer_loops
- Number of iterations of robust fitting.:robust
- If robustness iterations are to be used (boolean).:include_weights
- Whether to include robustness weights in the result (boolean).- For MSTL (when period is a list):
:iterations
- Number of iterations for MSTL.:lambda
- Lambda for Box-Cox transformation (between 0 and 1).:seasonal_lengths
- Lengths of the seasonal smoothers.
Examples
Standard STL decomposition (single period):
# Decompose with weekly seasonality result = Stl.decompose(series, 7) # Access components seasonal = result.seasonal trend = result.trend remainder = result.remainder # With robustness result = Stl.decompose(series, 7, robust: true) weights = result.weights
MSTL decomposition (multiple periods):
# Decompose with both weekly and yearly seasonality result = Stl.decompose(series, [7, 365]) # Access seasonal components weekly_seasonal = Enum.at(result.seasonal, 0) yearly_seasonal = Enum.at(result.seasonal, 1) # With additional MSTL options result = Stl.decompose(series, [7, 365], iterations: 2, lambda: 0.5, seasonal_lengths: [11, 731] )
Calculate the seasonal strength from a decomposition result.
Returns a float value between 0 and 1 representing the seasonal strength to signify a detected seasonal trend.
Values range from 0.0 to 1.0, where:
- 0.0 means no strength
- 1.0 means maximum strength
Examples
iex> result = Stl.decompose([5.0, 9.0, 2.0, 9.0, 0.0, 6.0, 3.0], 2)
iex> Stl.seasonal_strength(result)
0.9422302715663797
Calculate the trend strength from a decomposition result.
Expects a decomposition map containing :trend
and :remainder
components.
Returns a float value between 0 and 1 representing the trend strength.
Examples
iex> result = Stl.decompose([5.0, 9.0, 2.0, 9.0, 0.0, 6.0, 3.0], 2)
iex> Stl.trend_strength(result)
0.727898191447705