Целевой ряд соответствует build_occupied_series в src/plot.rs:
- Для каждого дня берём среднюю площадь по:
-
occupied_after_24_02_2022(RU) -
other_territoriesсhash == "#01579b"(UA)
-
- Целевой ряд:
$RU - UA$
Модель обучается на плотном дневном ряду, начиная с 2022-11-22 (включительно).
Используем те же правила, что и в графике:
- Парсим временные метки и агрегируем к дневному среднему по категориям.
- Строим плотный дневной календарь от минимальной до максимальной даты.
- Заполняем пропуски линейной интерполяцией между известными точками.
- Масштабируем значения
scale = 1000.0для устойчивости оптимизации.
Реализация: load_target_series в src/model.rs.
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)$
Оцениваем
- Цель: отрицательное лог-правдоподобие Калмановского фильтра.
- Оптимизатор: L-BFGS (
argmin) с численным градиентом (центральная разность). - Критерии останова: более строгие допуски (
grad <= 1e-8,cost <= 1e-10) и до 400 итераций. - Инициализация: по стандартному отклонению дневных разностей.
- Гетероскедастичность: дисперсии процесса и наблюдения масштабируются по времени, выше в периоды высокой волатильности (по скользящему среднему модулей дневных изменений).
- Для trend-filter: робастная ошибка Huber в терме данных, чтобы снизить влияние выбросов.
Реализация: LocalLinearTrendProblem в src/model.rs.
Берём финальное отфильтрованное состояние и ковариацию и прогоняем переход
вперёд на
- Мат. ожидание:
$\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 прогноза используется последнее значение и наклон тренда
с демпфированием