Декомпозиция временного ряда: тренд, сезонность, шум
Что такое декомпозиция
Decomposition (декомпозиция) временного ряда — разложение на компоненты:
- Trend (тренд). Долгосрочное направление роста или падения.
- Seasonality (сезонность). Регулярные периодические колебания.
- Cycle. Долгосрочные waves, не fixed period (экономические циклы).
- Residual (остаток). То, что не объясняется trend и seasonality.
Разложение помогает понять behavior данных, выбрать forecasting model, выявить аномалии.
Additive vs Multiplicative
Две модели комбинирования компонентов.
Additive. Компоненты суммируются.
Y(t) = Trend(t) + Seasonal(t) + Residual(t)Применима когда amplitude seasonality constant over time. Seasonal swings одинаковые при любом уровне тренда.
Multiplicative. Компоненты множатся.
Y(t) = Trend(t) × Seasonal(t) × Residual(t)Применима когда amplitude seasonality пропорциональна уровню. С ростом тренда seasonal swings тоже растут.
Для multiplicative часто используют log-transform, после которого multiplicative становится additive:
log(Y) = log(Trend) + log(Seasonal) + log(Residual)Как отличить
Визуально смотрите на seasonal amplitudes.
Additive signals.
- Температура по месяцам: зима-лето разница всегда ~30°C.
- Simple business metrics со стабильной seasonality.
Multiplicative signals.
- Продажи e-commerce: дneсs growth + bigger spike on Black Friday.
- Revenue с растущим бизнесом и Q4 seasonality.
Тест: разделите ряд на 2-3 сегмента, посмотрите amplitude seasonality в каждом. Растёт вместе с уровнем → multiplicative. Constant → additive.
Классическая decomposition в Python
import pandas as pd
from statsmodels.tsa.seasonal import seasonal_decompose
# Assuming monthly data
result = seasonal_decompose(y, model='additive', period=12)
result.plot()
plt.show()
trend = result.trend
seasonal = result.seasonal
residual = result.residДля multiplicative — model='multiplicative'.
Классический метод использует moving averages для оценки trend, потом averages по сезону для seasonal, оставшееся — residual.
Простой, но с недостатками:
- Первые/последние периоды теряются (MA window).
- Smooth trend может over-smooth.
- Одинаковый seasonal pattern для всех лет.
STL decomposition
Seasonal-Trend decomposition using LOESS (STL) — современный метод. Преимущества:
- Robust к outliers.
- Гибкий seasonal pattern — может меняться во времени.
- Работает с любым seasonal period.
- Нет lost periods на границах.
from statsmodels.tsa.seasonal import STL
stl = STL(y, period=12, robust=True)
result = stl.fit()
result.plot()Параметры:
period— seasonal cycle length.seasonal— smoothness of seasonal component.trend— smoothness of trend.robust— использовать weights для outliers.
STL — go-to метод для современной decomposition.
X-13ARIMA-SEATS
Метод от U.S. Census Bureau. Самый advanced для economic data:
- Автоматическое выявление outliers.
- Handling trading day effects (понедельник vs суббота).
- Holiday adjustments (Easter, Christmas).
- Calendar effects.
Используется в официальной статистике (GDP, unemployment).
from statsmodels.tsa.x13 import x13_arima_analysis
result = x13_arima_analysis(y)
# Требует X13 binary installedДля бизнес-данных обычно overkill, но для макростат — стандарт.
Multiple seasonality
Реальность часто имеет multiple seasonal patterns.
Daily traffic:
- Weekly (пн-пт vs сб-вс)
- Yearly (летний спад)
- Holiday effects
STL handles только одну seasonality. Для multiple:
MSTL. Multiple STL. Библиотека statsforecast.
from statsforecast.models import MSTL
mstl = MSTL(season_length=[7, 365.25])
mstl.fit(y)Prophet. Facebook library. Автоматически handles multiple seasonalities.
TBATS. Complex seasonal ARIMA variant. Handles non-integer seasonality (365.25 дней в year).
Применение в бизнесе
Forecasting. Раздельное моделирование trend и seasonality → точнее прогнозы.
Forecast = Extrapolated Trend + Seasonal (from same month in past)Anomaly detection. После удаления trend и seasonality остаются residuals. Большие residuals — аномалии.
# Z-score на residuals
z = (residuals - residuals.mean()) / residuals.std()
anomalies = df[abs(z) > 3]Seasonally adjusted metrics. Убираем seasonal effect для понимания истинного growth.
Y_sa = Y - Seasonal # additive
Y_sa = Y / Seasonal # multiplicativeSeasonally adjusted revenue показывает underlying growth без шума от Q4 peak.
Identifying changes. Комendcreased trend slope может signal business model change. Новая seasonal pattern — signal customer behavior shift.
Timе series analysis — частая тема на собесах analytics и data science. В тренажёре Карьерник есть задачи на forecasting, сезонность и аналитику временных рядов.
Step-by-step example
Данные: daily revenue e-commerce store за 3 года.
Шаг 1. Visualize.
df['revenue'].plot()
# Видим: растущий тренд, недельная сезонность (weekends > weekdays),
# годовая сезонность (Q4 spike)Шаг 2. STL decomposition.
from statsforecast.models import MSTL
mstl = MSTL(season_length=[7, 365])
mstl.fit(df['revenue'].values)
components = mstl.predict(h=30) # или получить fitted valuesШаг 3. Analyze trend.
# Trend показывает underlying growth rate
# Если linear: growth = coefficient per day
# Если shape меняется: business model changed at inflection pointШаг 4. Analyze seasonality.
# Weekly: Tue-Wed могут быть low points, weekends peak
# Yearly: Black Friday, Christmas spikes
# Understand когда allocate marketing, staffingШаг 5. Forecast.
# Extrapolate trend + apply seasonal pattern
# Or use Prophet/SARIMA/ETS со встроенной декомпозициейFilters для trend extraction
Alternative methods:
Hodrick-Prescott (HP) filter. Popular in economics. Разделяет trend и cyclical components.
from statsmodels.tsa.filters.hp_filter import hpfilter
cycle, trend = hpfilter(y, lamb=1600) # lambda=1600 for quarterlyBaxter-King filter. Band-pass filter. Изолирует specific frequency ranges.
Kalman filter. Dynamic approach, handles complex state space models.
Для most business applications STL или seasonal_decompose — достаточно.
Handling missing data
Decomposition sensitive к пропускам. Опции:
Imputation перед decomposition:
- Linear interpolation.
- Seasonal interpolation (use same month/day в предыдущие years).
Decomposition с пропусками:
- Prophet handles natively.
- State space models (SARIMA, Kalman filter).
Избегайте FFill/BFill — создаёт artificial flat periods, искажает trend и seasonality.
Seasonality strength metric
Иногда нужно numerically assess, насколько seasonal ряд.
Seasonal strength = max(0, 1 - Var(Residual) / Var(Residual + Seasonal))От 0 (no seasonality) до 1 (pure seasonal).
ss = max(0, 1 - np.var(residual) / np.var(residual + seasonal))Помогает решить: stoит ли seasonal modeling, или white noise approach OK.
Типичные ошибки
Wrong seasonal period. Daily data с 30 period (monthly) → искаженная seasonality. Период должен совпадать с true cycle.
Additive для multiplicative data. Residuals будут гетероскедастичны. Визуально проверять.
Over-smoothing trend. Слишком wide LOESS window → trend «проглатывает» cycles.
Ignoring holidays. Easter, Chinese New Year, Ramadan — moveable dates. Standard decomposition их пропускает. Prophet handles.
Too short series. STL нуждается в 2+ полных seasonal cycles. Короткий ряд → unreliable.
Читайте также
FAQ
Какой метод decomposition лучший?
STL — хороший default. Prophet/MSTL для multiple seasonalities. X-13 для macro data.
Можно ли decompose короткий ряд?
< 2 полных cycles — результат unreliable. Лучше accumulate данные.
Multiplicative или additive — автоматически?
Автоматической детекции нет. Визуальный анализ amplitude. Rule: log-transform и decompose additively — safe option.
Decomposition = forecasting?
Нет. Decomposition — описательный analysis. Forecasting — extrapolating компоненты. Похожие but different tasks.