Skip to content

Latest commit

 

History

History
73 lines (51 loc) · 4.11 KB

File metadata and controls

73 lines (51 loc) · 4.11 KB

Модель: Local Linear Trend (LLT)

1) Целевой ряд

Целевой ряд соответствует build_occupied_series в src/plot.rs:

  • Для каждого дня берём среднюю площадь по:
    • occupied_after_24_02_2022 (RU)
    • other_territories с hash == "#01579b" (UA)
  • Целевой ряд: $RU - UA$

Модель обучается на плотном дневном ряду, начиная с 2022-11-22 (включительно).

2) Подготовка данных

Используем те же правила, что и в графике:

  1. Парсим временные метки и агрегируем к дневному среднему по категориям.
  2. Строим плотный дневной календарь от минимальной до максимальной даты.
  3. Заполняем пропуски линейной интерполяцией между известными точками.
  4. Масштабируем значения scale = 1000.0 для устойчивости оптимизации.

Реализация: load_target_series в src/model.rs.

3) Определение модели

State-space модель Local Linear Trend:

  • Состояние: $x_t = [\text{level}_t, \text{trend}_t]$
  • Переход:
    • $\text{level}t = \text{level}{t-1} + \text{trend}{t-1} + w{\text{level}}$
    • $\text{trend}t = \text{trend}{t-1} + w_{\text{trend}}$
  • Наблюдение:
    • $y_t = \text{level}_t + v_t$

Шумы считаем гауссовыми:

  • $w_{\text{level}} \sim \mathcal{N}(0, \sigma_{\text{level}}^2)$
  • $w_{\text{trend}} \sim \mathcal{N}(0, \sigma_{\text{trend}}^2)$
  • $v_t \sim \mathcal{N}(0, \sigma_{\text{obs}}^2)$

Оцениваем $\log(\sigma_{\text{level}})$, $\log(\sigma_{\text{trend}})$, $\log(\sigma_{\text{obs}})$, чтобы гарантировать положительность.

4) Оптимизация

  • Цель: отрицательное лог-правдоподобие Калмановского фильтра.
  • Оптимизатор: L-BFGS (argmin) с численным градиентом (центральная разность).
  • Критерии останова: более строгие допуски (grad <= 1e-8, cost <= 1e-10) и до 400 итераций.
  • Инициализация: по стандартному отклонению дневных разностей.
  • Гетероскедастичность: дисперсии процесса и наблюдения масштабируются по времени, выше в периоды высокой волатильности (по скользящему среднему модулей дневных изменений).
  • Для trend-filter: робастная ошибка Huber в терме данных, чтобы снизить влияние выбросов.

Реализация: LocalLinearTrendProblem в src/model.rs.

5) Прогнозирование (горизонт $H$ дней)

Берём финальное отфильтрованное состояние и ковариацию и прогоняем переход вперёд на $H$ дней без шага обновления по наблюдениям:

  • Мат. ожидание: $\hat{y}_t = \text{level}_t$
  • Дисперсия: $\text{Var}(\hat{y}t) = P{00} + \sigma_{\text{obs}}^2$
  • 95% интервал: $\hat{y}_t \pm 1.96 \cdot \sqrt{\text{Var}(\hat{y}_t)}$

Реализация: FittedModel::forecast в src/model.rs.

Для trend-filter прогноза используется последнее значение и наклон тренда с демпфированием $\phi \in (0,1]$: $\hat{y}t = y_T + s_T \cdot \sum{k=0}^{t-1} \phi^k$. Дисперсия расширяется с горизонтом за счёт неопределённости наклона: $\text{Var}(\hat{y}t) = \sigma{\text{resid}}^2 + \left(\sum_{k=0}^{t-1} \phi^k\right)^2 \cdot \sigma_{\text{slope}}^2$, с минимальным полом для устойчивости.