Skip to main content

Seasonality Detection

Seasonality refers to regular, predictable fluctuations that recur at fixed intervals -- such as weekly sales spikes on Fridays, monthly billing cycles, or annual holiday demand surges. Detecting these patterns and their exact period length is a critical prerequisite for accurate forecasting, because passing the wrong seasonal period (or none at all) to a forecasting model degrades prediction quality. AnoFox provides 12 detection methods and pattern classification tools to identify these cycles automatically.

FunctionDescriptionType
ts_detect_periods_byMulti-method period detection (12 algorithms)Table Macro
ts_classify_seasonality_byClassify seasonality type per groupTable Macro
ts_classify_seasonalityClassify seasonality (single series)Table Macro
Showing 3 of 3

ts_detect_periods_by​

Detect seasonal periods for grouped series using one of 12 algorithms.

ts_detect_periods_by(
source VARCHAR,
group_col COLUMN,
date_col COLUMN,
value_col COLUMN,
params MAP
) → TABLE(id, periods)

Parameters:

ParameterTypeRequiredDescription
sourceVARCHARYesSource table name
group_colCOLUMNYesSeries identifier (unquoted)
date_colCOLUMNYesDate/timestamp column (unquoted)
value_colCOLUMNYesValue column (unquoted)
paramsMAPNoConfiguration (use MAP{} for defaults)

Params MAP Options:

KeyTypeDefaultDescription
methodVARCHAR'fft'Detection algorithm (see table below)
max_periodVARCHAR'365'Maximum period to search
min_confidenceVARCHARmethod-specificMinimum confidence threshold; '0' to see all

Detection Methods​

The method parameter selects one of 12 algorithms, each optimized for different data characteristics:

MethodAliasesSpeedBest For
'fft''periodogram'Very FastClean signals (default)
'acf''autocorrelation'FastCyclical patterns, noise-robust
'autoperiod''ap'FastGeneral purpose, robust
'cfd''cfdautoperiod'FastTrending data
'lombscargle''lomb_scargle'MediumIrregular sampling
'aic''aic_comparison'SlowModel comparison
'ssa''singular_spectrum'MediumComplex patterns
'stl''stl_period'SlowDecomposition-based
'matrix_profile''matrixprofile'SlowPattern repetition
'sazed''zero_padded'MediumHigh frequency resolution
'auto'—MediumUnknown characteristics
'multi''multiple'MediumMultiple seasonalities

Returns​

Returns a periods STRUCT per group:

FieldTypeDescription
periods[]STRUCT[]Array of {period, confidence, strength, amplitude, phase, iteration}
n_periodsBIGINTNumber of detected periods
primary_periodDOUBLEDominant period
methodVARCHARMethod used

Confidence Interpretation​

MethodConfidence MeaningGood Threshold
FFTPeak-to-mean power ratio> 5.0
ACFAutocorrelation at lag> 0.3

Default thresholds filter low-confidence periods automatically. Set min_confidence='0' to see all candidates.

Examples​

-- Detect periods using default FFT method
SELECT id, (periods).primary_period, (periods).n_periods
FROM ts_detect_periods_by('sales', product_id, date, value, MAP{});

-- Use ACF method with limited search range
SELECT * FROM ts_detect_periods_by('sales', product_id, date, value,
MAP{'method': 'acf', 'max_period': '28'});

-- Detect multiple seasonalities
SELECT * FROM ts_detect_periods_by('hourly_data', sensor_id, timestamp, reading,
MAP{'method': 'multi'});

-- Use auto method for unknown data
SELECT id, (periods).primary_period
FROM ts_detect_periods_by('new_data', series_id, date, value,
MAP{'method': 'auto'});

Workflow: Detect → Forecast​

-- Step 1: Detect seasonal period
SELECT id, (periods).primary_period
FROM ts_detect_periods_by('sales', product_id, date, value, MAP{});
-- Returns e.g. primary_period = 7 (weekly)

-- Step 2: Use detected period in forecast
SELECT * FROM ts_forecast_by(
'sales', product_id, date, value,
'AutoETS', 14, '1d', MAP{'seasonal_period': '7'}
);

ts_classify_seasonality_by​

Classify the type of seasonal pattern per group, including timing stability and amplitude modulation.

ts_classify_seasonality_by(
source VARCHAR,
group_col COLUMN,
date_col COLUMN,
value_col COLUMN,
period DOUBLE
) → TABLE

Parameters:

ParameterTypeRequiredDescription
sourceVARCHARYesSource table name
group_colCOLUMNYesSeries identifier (unquoted)
date_colCOLUMNYesDate/timestamp column (unquoted)
value_colCOLUMNYesValue column (unquoted)
periodDOUBLEYesExpected seasonal period

Returns:

ColumnTypeDescription
group_col(input)Series identifier
timing_classificationVARCHAR'early', 'on_time', 'late', 'variable'
modulation_typeVARCHAR'stable', 'growing', 'shrinking', 'variable'
has_stable_timingBOOLEANConsistent peak timing?
timing_variabilityDOUBLELower = more stable
seasonal_strengthDOUBLE0-1 scale
is_seasonalBOOLEANSignificant seasonality?
cycle_strengthsDOUBLE[]Strength per cycle
weak_seasonsINTEGER[]Indices of weak cycles

Example:

-- Classify weekly seasonality per product
SELECT id, seasonal_strength, is_seasonal
FROM ts_classify_seasonality_by('sales', product_id, date, quantity, 7.0)
WHERE is_seasonal AND has_stable_timing;

ts_classify_seasonality​

Single-series variant (no grouping).

ts_classify_seasonality(
source VARCHAR,
date_col COLUMN,
value_col COLUMN,
period DOUBLE
) → TABLE

Same return columns as ts_classify_seasonality_by but without the group column.

Example:

SELECT seasonal_strength, timing_classification, modulation_type
FROM ts_classify_seasonality('monthly_sales', date, revenue, 12.0);

Interpretation Guide​

MetricValueInterpretation
seasonal_strength> 0.6Strong seasonality, use seasonal models
seasonal_strength0.3 - 0.6Moderate seasonality
seasonal_strength< 0.3Weak or no seasonality
timing_classificationon_timeConsistent peak timing
timing_classificationvariablePeak timing varies
modulation_typestableSeasonal amplitude is consistent
modulation_typegrowingSeasonal effect is increasing

Model Selection Based on Detection​

Detection ResultRecommended Models
Strong stable seasonalityAutoETS, HoltWinters, SeasonalES
Multiple periods detectedAutoTBATS, AutoMSTL, MFLES
Variable seasonalityDynamicTheta, DynamicOptimizedTheta
No seasonality detectedNaive, SES, Holt
Trending + seasonalHoltWinters, AutoARIMA
🍪 Cookie Settings